├── README.md
├── esp32_clients
├── esp_mqtt_client1
│ └── esp_mqtt_client1.ino
└── esp_mqtt_client2
│ └── esp_mqtt_client2.ino
└── rpi_mqtt_clients
├── client_pub.py
└── client_sub.py
/README.md:
--------------------------------------------------------------------------------
1 | # MQTT Network for data Exchange - Raspberry Pi & ESP32 Microcontrollers
2 |
3 |
4 | Read the :-
5 | complete article here.
6 |
7 | Watch Video :-
8 | on Youtube.
9 |
10 |
11 |
12 |
13 |
14 | The code for this project is created to demonstrate data exchange mechanism between Raspberry Pi & ESP32 Microcontrollers using MQTT network.
15 | In a MQTT network, the communication between devices takes place using a Publish & Subscribe mechanism. Messages can be published on a specific topic by a device.
16 | The devices that are subscribed to that topic can receive the message. Devices can send and receive data through a MQTT broker.
17 |
18 | No sensor is required to be interfaced for this project.
19 |
20 | ## The Code
21 |
22 | ### rpi_mqtt_clients (Raspberry Pi code)
23 | There two Python scripts in this folder. Both connects the broker as clients with following functionality
24 |
25 | #### client_pub.py
26 | This file publishes a simple counter value on a topic 'rpi/braodcast' every 02 seconds. This topic is subscribed by all other clients on the network.
27 |
28 | #### client_sub.py
29 | This file subscribe to all the 03 topics (one as mentioned above and other two topics are used by ESP32 to publish thier data). The data received by other clients is printed on the terminal.
30 |
31 | ### esp32_clients (ESP 32 code)
32 | This folder contains the C code written in Arduino IDE for 02 ESP32 microcontrollers.
33 | The code for both the ESP32 is completely identical. The only difference in the two codes is the name of the client and the topic to which it publishes.
34 | Both the ESPs do the publish & subscribe simultneously. One ESP publishes to the topic 'esp/sensor1' and the other publishes to 'esp/sensor2'.
35 | They both subscribe to 'rpi/broadcast' and receive data from this topic.
36 |
37 | ## The Information Flow
38 |
39 | The task of Python scripts running in Raspberry Pi and C code running in ESP32 can be summarised by the following diagram
40 |
41 |
42 |
43 | You can replicate this demo code on your devices and understand the MQTT communication. Later you can modify it for practical use by interfacing sensors and actuators as per your requirement.
44 |
--------------------------------------------------------------------------------
/esp32_clients/esp_mqtt_client1/esp_mqtt_client1.ino:
--------------------------------------------------------------------------------
1 | /*********
2 | Author: Jitesh Saini
3 | This code is built upon the example code in pubsubclient library
4 | Complete project details at https://helloworld.co.in
5 | *********/
6 |
7 | #include
8 | #include
9 |
10 | // Replace the SSID/Password details as per your wifi router
11 | const char* ssid = "yourSSID";
12 | const char* password = "yourPassword";
13 |
14 | // Replace your MQTT Broker IP address here:
15 | const char* mqtt_server = "192.168.1.45";
16 |
17 | WiFiClient espClient;
18 | PubSubClient client(espClient);
19 |
20 | long lastMsg = 0;
21 |
22 | #define ledPin 2
23 |
24 | void blink_led(unsigned int times, unsigned int duration){
25 | for (int i = 0; i < times; i++) {
26 | digitalWrite(ledPin, HIGH);
27 | delay(duration);
28 | digitalWrite(ledPin, LOW);
29 | delay(200);
30 | }
31 | }
32 |
33 | void setup_wifi() {
34 | delay(50);
35 | Serial.println();
36 | Serial.print("Connecting to ");
37 | Serial.println(ssid);
38 |
39 | WiFi.begin(ssid, password);
40 |
41 | int c=0;
42 | while (WiFi.status() != WL_CONNECTED) {
43 | blink_led(2,200); //blink LED twice (for 200ms ON time) to indicate that wifi not connected
44 | delay(1000); //
45 | Serial.print(".");
46 | c=c+1;
47 | if(c>10){
48 | ESP.restart(); //restart ESP after 10 seconds
49 | }
50 | }
51 |
52 | Serial.println("");
53 | Serial.println("WiFi connected");
54 | Serial.println("IP address: ");
55 | Serial.println(WiFi.localIP());
56 |
57 | }
58 |
59 | void connect_mqttServer() {
60 | // Loop until we're reconnected
61 | while (!client.connected()) {
62 |
63 | //first check if connected to wifi
64 | if(WiFi.status() != WL_CONNECTED){
65 | //if not connected, then first connect to wifi
66 | setup_wifi();
67 | }
68 |
69 | //now attemt to connect to MQTT server
70 | Serial.print("Attempting MQTT connection...");
71 | // Attempt to connect
72 | if (client.connect("ESP32_client1")) { // Change the name of client here if multiple ESP32 are connected
73 | //attempt successful
74 | Serial.println("connected");
75 | // Subscribe to topics here
76 | client.subscribe("rpi/broadcast");
77 | //client.subscribe("rpi/xyz"); //subscribe more topics here
78 |
79 | }
80 | else {
81 | //attempt not successful
82 | Serial.print("failed, rc=");
83 | Serial.print(client.state());
84 | Serial.println(" trying again in 2 seconds");
85 |
86 | blink_led(3,200); //blink LED three times (200ms on duration) to show that MQTT server connection attempt failed
87 | // Wait 2 seconds before retrying
88 | delay(2000);
89 | }
90 | }
91 |
92 | }
93 |
94 | //this function will be executed whenever there is data available on subscribed topics
95 | void callback(char* topic, byte* message, unsigned int length) {
96 | Serial.print("Message arrived on topic: ");
97 | Serial.print(topic);
98 | Serial.print(". Message: ");
99 | String messageTemp;
100 |
101 | for (int i = 0; i < length; i++) {
102 | Serial.print((char)message[i]);
103 | messageTemp += (char)message[i];
104 | }
105 | Serial.println();
106 |
107 | // Check if a message is received on the topic "rpi/broadcast"
108 | if (String(topic) == "rpi/broadcast") {
109 | if(messageTemp == "10"){
110 | Serial.println("Action: blink LED");
111 | blink_led(1,1250); //blink LED once (for 1250ms ON time)
112 | }
113 | }
114 |
115 | //Similarly add more if statements to check for other subscribed topics
116 | }
117 |
118 | void setup() {
119 | pinMode(ledPin, OUTPUT);
120 | Serial.begin(115200);
121 |
122 | setup_wifi();
123 | client.setServer(mqtt_server,1883);//1883 is the default port for MQTT server
124 | client.setCallback(callback);
125 | }
126 |
127 | void loop() {
128 |
129 | if (!client.connected()) {
130 | connect_mqttServer();
131 | }
132 |
133 | client.loop();
134 |
135 | long now = millis();
136 | if (now - lastMsg > 4000) {
137 | lastMsg = now;
138 |
139 | client.publish("esp32/sensor1", "88"); //topic name (to which this ESP32 publishes its data). 88 is the dummy value.
140 |
141 | }
142 |
143 | }
144 |
--------------------------------------------------------------------------------
/esp32_clients/esp_mqtt_client2/esp_mqtt_client2.ino:
--------------------------------------------------------------------------------
1 | /*********
2 | Author: Jitesh Saini
3 | This code is built upon the example code in pubsubclient library
4 | Complete project details at https://helloworld.co.in
5 | *********/
6 |
7 | #include
8 | #include
9 |
10 | // Replace the SSID/Password details as per your wifi router
11 | const char* ssid = "yourSSID";
12 | const char* password = "yourPassword";
13 |
14 | // Replace your MQTT Broker IP address here:
15 | const char* mqtt_server = "192.168.1.45";
16 |
17 | WiFiClient espClient;
18 | PubSubClient client(espClient);
19 |
20 | long lastMsg = 0;
21 |
22 | #define ledPin 2
23 |
24 | void blink_led(unsigned int times, unsigned int duration){
25 | for (int i = 0; i < times; i++) {
26 | digitalWrite(ledPin, HIGH);
27 | delay(duration);
28 | digitalWrite(ledPin, LOW);
29 | delay(200);
30 | }
31 | }
32 |
33 | void setup_wifi() {
34 | delay(50);
35 | Serial.println();
36 | Serial.print("Connecting to ");
37 | Serial.println(ssid);
38 |
39 | WiFi.begin(ssid, password);
40 |
41 | int c=0;
42 | while (WiFi.status() != WL_CONNECTED) {
43 | blink_led(2,200); //blink LED twice (for 200ms ON time) to indicate that wifi not connected
44 | delay(1000); //
45 | Serial.print(".");
46 | c=c+1;
47 | if(c>10){
48 | ESP.restart(); //restart ESP after 10 seconds
49 | }
50 | }
51 |
52 | Serial.println("");
53 | Serial.println("WiFi connected");
54 | Serial.println("IP address: ");
55 | Serial.println(WiFi.localIP());
56 |
57 | }
58 |
59 | void connect_mqttServer() {
60 | // Loop until we're reconnected
61 | while (!client.connected()) {
62 |
63 | //first check if connected to wifi
64 | if(WiFi.status() != WL_CONNECTED){
65 | //if not connected, then first connect to wifi
66 | setup_wifi();
67 | }
68 |
69 | //now attemt to connect to MQTT server
70 | Serial.print("Attempting MQTT connection...");
71 | // Attempt to connect
72 | if (client.connect("ESP32_client2")) { // Change the name of client here if multiple ESP32 are connected
73 | //attempt successful
74 | Serial.println("connected");
75 | // Subscribe to topics here
76 | client.subscribe("rpi/broadcast");
77 | //client.subscribe("rpi/xyz"); //subscribe more topics here
78 |
79 | }
80 | else {
81 | //attempt not successful
82 | Serial.print("failed, rc=");
83 | Serial.print(client.state());
84 | Serial.println(" trying again in 2 seconds");
85 |
86 | blink_led(3,200); //blink LED three times (200ms on duration) to show that MQTT server connection attempt failed
87 | // Wait 2 seconds before retrying
88 | delay(2000);
89 | }
90 | }
91 |
92 | }
93 |
94 | //this function will be executed whenever there is data available on subscribed topics
95 | void callback(char* topic, byte* message, unsigned int length) {
96 | Serial.print("Message arrived on topic: ");
97 | Serial.print(topic);
98 | Serial.print(". Message: ");
99 | String messageTemp;
100 |
101 | for (int i = 0; i < length; i++) {
102 | Serial.print((char)message[i]);
103 | messageTemp += (char)message[i];
104 | }
105 | Serial.println();
106 |
107 | // Check if a message is received on the topic "rpi/broadcast"
108 | if (String(topic) == "rpi/broadcast") {
109 | if(messageTemp == "15"){
110 | Serial.println("Action: blink LED");
111 | blink_led(1,1250); //blink LED once (for 1250ms ON time)
112 | }
113 | }
114 |
115 | //Similarly add more if statements to check for other subscribed topics
116 | }
117 |
118 | void setup() {
119 | pinMode(ledPin, OUTPUT);
120 | Serial.begin(115200);
121 |
122 | setup_wifi();
123 | client.setServer(mqtt_server,1883);//1883 is the default port for MQTT server
124 | client.setCallback(callback);
125 | }
126 |
127 | void loop() {
128 |
129 | if (!client.connected()) {
130 | connect_mqttServer();
131 | }
132 |
133 | client.loop();
134 |
135 | long now = millis();
136 | if (now - lastMsg > 4000) {
137 | lastMsg = now;
138 |
139 | client.publish("esp32/sensor2", "37"); //topic name (to which this ESP32 publishes its data). 37 is the dummy value.
140 |
141 | }
142 |
143 | }
144 |
--------------------------------------------------------------------------------
/rpi_mqtt_clients/client_pub.py:
--------------------------------------------------------------------------------
1 | import time
2 | import paho.mqtt.client as mqtt
3 |
4 |
5 | def on_publish(client, userdata, mid):
6 | print("message published")
7 |
8 |
9 | client = mqtt.Client("rpi_client2") #this name should be unique
10 | client.on_publish = on_publish
11 | client.connect('127.0.0.1',1883)
12 | # start a new thread
13 | client.loop_start()
14 |
15 | k=0
16 | while True:
17 | k=k+1
18 | if(k>20):
19 | k=1
20 |
21 | try:
22 | msg =str(k)
23 | pubMsg = client.publish(
24 | topic='rpi/broadcast',
25 | payload=msg.encode('utf-8'),
26 | qos=0,
27 | )
28 | pubMsg.wait_for_publish()
29 | print(pubMsg.is_published())
30 |
31 | except Exception as e:
32 | print(e)
33 |
34 | time.sleep(2)
35 |
--------------------------------------------------------------------------------
/rpi_mqtt_clients/client_sub.py:
--------------------------------------------------------------------------------
1 | import paho.mqtt.client as mqtt
2 | import time
3 |
4 | def on_connect(client, userdata, flags, rc):
5 | global flag_connected
6 | flag_connected = 1
7 | client_subscriptions(client)
8 | print("Connected to MQTT server")
9 |
10 | def on_disconnect(client, userdata, rc):
11 | global flag_connected
12 | flag_connected = 0
13 | print("Disconnected from MQTT server")
14 |
15 | # a callback functions
16 | def callback_esp32_sensor1(client, userdata, msg):
17 | print('ESP sensor1 data: ', msg.payload.decode('utf-8'))
18 |
19 |
20 | def callback_esp32_sensor2(client, userdata, msg):
21 | print('ESP sensor2 data: ', str(msg.payload.decode('utf-8')))
22 |
23 | def callback_rpi_broadcast(client, userdata, msg):
24 | print('RPi Broadcast message: ', str(msg.payload.decode('utf-8')))
25 |
26 | def client_subscriptions(client):
27 | client.subscribe("esp32/#")
28 | client.subscribe("rpi/broadcast")
29 |
30 | client = mqtt.Client("rpi_client1") #this should be a unique name
31 | flag_connected = 0
32 |
33 | client.on_connect = on_connect
34 | client.on_disconnect = on_disconnect
35 | client.message_callback_add('esp32/sensor1', callback_esp32_sensor1)
36 | client.message_callback_add('esp32/sensor2', callback_esp32_sensor2)
37 | client.message_callback_add('rpi/broadcast', callback_rpi_broadcast)
38 | client.connect('127.0.0.1',1883)
39 | # start a new thread
40 | client.loop_start()
41 | client_subscriptions(client)
42 | print("......client setup complete............")
43 |
44 |
45 | while True:
46 | time.sleep(4)
47 | if (flag_connected != 1):
48 | print("trying to connect MQTT server..")
49 |
50 |
--------------------------------------------------------------------------------