#19 Control LED from Mobile using Pub-Sub architecture RPi3: MQTT Broker, NodeMCU: Client

IoT Tutorial #19 [ Raspberry Pi Tutorials #7 & NodeMCU Tutorials #5 ]
In this post, we will see, How to control devices (Things) using Publish-Subscribe IoT Architecture.


In the previous post, we have seen how we can use Raspberry Pi 3 as a broker for Public-Subscribe IoT Architecture. Now, will use those steps to use Raspberry Pi 3 as a broker and NodeMCU as a Client (Subscriber) and will control LED connected to NodeMCU from Android Mobile Phone (Publisher).

Description:

To Control LED using Public-Subscribe Architecture
Here, NodeMCU is one node and Raspberry Pi (RPi3) is acting as Broker of the Publish-Subscribe Architecture.
NodeMCU is subscribed to the Broker(RPi3) > TopicName: "iot" and
It will receive all the msgs which will be published by any publisher to TopicName: "iot"



Physical Connections:

LED is connected to Pin 17 (D7 of NodeMCU)

Program Outcome:

If received msg is "0", It will turn OFF the LED
If received msg is "1", It will turn ON the LED

Steps:

1. Select Board as: NODEMCU 1.0 (ESP-12E Module) 

2. Install PubSub client library
   Go to Sketch > Include Library > Manage Libraries > search for "pubsub" > Install PubSubClient

3. Replace following things in the below program:   
   a. ssid_name (Wi-Fi Name)
   b. ssid_password (Wi-Fi Password)
   c. Borker_IP_Address (IP of RPi3) 
   d. topic_name (Here it is "iot")
   
4. Make all the connections shown above

5. Follow these steps to install mosquitto MQTT on RPi3 
   and Start Mosquitto Broker on RPi3 using command: sudo /etc/init.d/mosquitto start
6. Follow these steps to connect NodeMCU to Arduino IDE and upload the this sketch to NodeMCU

7. Open Arduino Serial Monitor on PC (Set Baud Rate to 9600 and set "Both NL & CR")

8. Open new Terminal on RPi3 and Publish msg using commands: 
   To turn OFF LED : mosquitto_pub -d -h <Borker_IP_Address> -t "iot" -m "0"
   To turn ON LED  : mosquitto_pub -d -h <Borker_IP_Address> -t "iot" -m "1" 
   where, -t: topic, -h: host, -d: debug, -m: msg

9. You can publish using android mobile phone also.   
   download and install any MQTT client app from play store 
   set host=Borker_IP_Address, port=1883, topic_name="iot"
   and send "0" and "1" to control LED.
   BUT, Your mobile should be connected to same Wi-Fi   



Note: 

     1. All you devices should be connect to same Wi-Fi Network
     2. topic name should be same for publisher and subscriber (Here it is "iot")
     3. To Subscribe to all topics on the borker, use this command in terminal:
          mosquitto_sub -t "#"
     4. check mqtt api document: https://pubsubclient.knolleary.net/api.html

For Better understanding you can watch demonstration video given below:

Downloads:

Download link is given in the Description of the YouTube video shown below.

Demonstration:




Program: 

PubSub_Control_LED_NodeMCU_RPi3-APDaga.ino to be uploaded on NodeMCU )



#include <ESP8266WiFi.h>        // import ESP8266WiFi libraries
#include <PubSubClient.h>       // import PubSubClient libraries
 
// Connect to the WiFi
const char* ssid = "SuiteUp";               // ssid_name
const char* password = "welcome@10";        // ssid_password
const char* mqtt_server = "192.168.0.35";   // Borker_IP_Address (IP of RPi3)
 
WiFiClient espClient;             // WiFiClient Object to Connect to WiFi
PubSubClient client(espClient);   // PubSubClient Object
 
const byte ledPin = 13;           // LED to D7 pin on NodeMCU
 
void callback(char* topic, byte* payload, unsigned int length) {    //Standard method
 Serial.print("Message arrived [");    // print on serial monitor
 Serial.print(topic);
 Serial.print("] ");
 for (int i=0;i<length;i++) {
  char receivedChar = (char)payload[i];
  Serial.print(receivedChar);
  if (receivedChar == '0')            
  // ESP8266 Huzzah outputs are "reversed"
    digitalWrite(ledPin, LOW);         // LED OFF
  if (receivedChar == '1')
    digitalWrite(ledPin, HIGH);        // LED ON
  }
  Serial.println();
}
 
 
void reconnect() {                      // function to reconnect to MQTT Broker (RPi3)
 // Loop until we're reconnected
 while (!client.connected()) {
 Serial.print("Attempting MQTT connection...");
 // Attempt to connect
 if (client.connect("ESP8266 Client")) {
  Serial.println("connected");
  // ... and subscribe to topic
  client.subscribe("iot");             // topic_name
 } else 
 {
  Serial.print("failed, rc=");
  Serial.print(client.state());
  Serial.println(" try again in 5 seconds");
  // Wait 5 seconds before retrying
  delay(5000);
  }
 }
}
 
void setup()
{
 Serial.begin(9600);                  // set baud rate = 9600
 
 client.setServer(mqtt_server, 1883); // connect mqtt broker with port no. = 1883
 client.setCallback(callback);        // set the callback method 
 // callback function gets called automatically when a msg arrives to subscriber
 // callback function returns a pointer to the received msg
 
 pinMode(ledPin, OUTPUT);             // set pin 13 (D7) as Output
}
 
void loop()
{
 if (!client.connected()) {
  reconnect();       // call function to recconect to MQTT Broker 
 }
 client.loop();      // to process incoming msg and to maintain its connectio to broker
}

--------------------------------------------------------------------------------

Click here to see more codes for Raspberry Pi 3 and similar Family.
&
Click here to see more codes for NodeMCU ESP8266 and similar Family.
&
Click here to see more codes for Arduino Mega (ATMega 2560) and similar Family.

Feel free to ask doubts in the comment section. I will try my best to solve it.
If you find this helpful by any mean like, comment and share the post.
This is the simplest way to encourage me to keep doing such work.

Thanks and Regards,
-Akshay P. Daga

10 Comments

  1. hi can you publish a diagram of your led circuit connected to node mcu or email it to me at [email protected]

    it's hard to see in the video, thanks

    ReplyDelete
  2. Also I get these errors when i try upload the sketch


    /home/brian/Arduino/led_node_mcu/led_node_mcu.ino: In function 'void callback(char*, byte*, unsigned int)':
    led_node_mcu:18: error: 'lt' was not declared in this scope
    for (int i=0;i<length;i++) {
    ^
    led_node_mcu:18: error: expected ')' before ';' token
    for (int i=0;i<length;i++) {
    ^
    led_node_mcu:18: error: 'i' was not declared in this scope
    for (int i=0;i<length;i++) {
    ^
    led_node_mcu:18: error: expected ';' before ')' token
    for (int i=0;i<length;i++) {
    ^
    exit status 1
    'lt' was not declared in this scope

    ReplyDelete
  3. i think this line is a typo?
    for (int i=0;i<length;i++)

    should it be for(int i = 0; i < length; i++)

    ReplyDelete
    Replies
    1. i mean this line

      for (int i=0;i<length;i++)

      Delete
  4. after i=0 in for loop, is that part a typo? i&lt

    ReplyDelete
    Replies
    1. Thanks for the feedback.
      I have made the correction now.

      Delete
  5. This is very educational content and written well for a change. It's nice to see that some people still understand how to write a quality post! town planning

    ReplyDelete
  6. Thankyou.
    I followed all the steps, It's working for me.
    I am doing home automation in my home using MQTT.
    Can you suggest me any solution, for control the GPIOs on nodeMCU from a different network...!!!! (I want to control my GPIOs far from home)

    ReplyDelete
  7. Thankyou.
    I followed all the steps, It's working for me.
    I am doing home automation in my home using MQTT.
    Can you suggest me any solution, for control the GPIOs on nodeMCU from a different network...!!!! (I want to control my GPIOs far from home)

    ReplyDelete
Post a Comment
Previous Post Next Post