Hello,
Is it possible to subscribe to multiple MQTT topics in the same sketch, ie. esp32/relay1, esp32/relay2, esp32/relay3 etc.
All demos I have seen only show a single example?
Regards
Ian
PS. With reference to the Learn ESP32 with Arduino IDE course, module 7 units 3-4
Hello Ian,
Yes, of course. The main of goal of MQTT is that you can subscribe and publish to many topics that once for that exact purpose (controlling more than one relay/output per device).
You can go to the onConnect() function and subscribe to more topics, for example:
// Add more topics that want your ESP32 to be subscribed to void onMqttConnect(bool sessionPresent) { Serial.println("Connected to MQTT."); Serial.print("Session present: "); Serial.println(sessionPresent); uint16_t packetIdSub = mqttClient.subscribe("esp32/relay1", 0); uint16_t packetIdSub2 = mqttClient.subscribe("esp32/relay2", 0); Serial.print("Subscribing at QoS 0, packetId: "); Serial.println(packetIdSub); }
Then, you need to modify the onMqttMessage() function with what happens when your receive a message on that topic, for example:
void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) { String messageTemp; for (int i = 0; i < len; i++) { //Serial.print((char)payload[i]); messageTemp += (char)payload[i]; } // Check if the MQTT message was received on topic esp32/relay1 if (strcmp(topic, "esp32/relay1") == 0) { // If the relay is on turn it off (and vice-versa) if (messageTemp == "ON") { digitalWrite(relay1, HIGH); } else { digitalWrite(relay1, LOW); } } if (strcmp(topic, "esp32/relay2") == 0) { // If the relay is on turn it off (and vice-versa) if (messageTemp == "ON") { digitalWrite(relay2, HIGH); } else { digitalWrite(relay2, LOW); } } Serial.println("Publish received."); Serial.print(" message: "); Serial.println(messageTemp); Serial.print(" topic: "); Serial.println(topic); Serial.print(" qos: "); Serial.println(properties.qos); Serial.print(" dup: "); Serial.println(properties.dup); Serial.print(" retain: "); Serial.println(properties.retain); Serial.print(" len: "); Serial.println(len); Serial.print(" index: "); Serial.println(index); Serial.print(" total: "); Serial.println(total); }
I hope this example helps you do what you’re looking for!
Hello Rui,
Yes thanks that’s exactly what I’m looking for, I was on the right lines in the onMqttConnect but I thought I would have to increment the packetIdSub to something like packetIdSub1, packetIdSub2 etc.
But I was stumped at the onMqttMessage part.
Thanks again
Ian
Hello Rui,
In fact I’ve just tried it an I did get a build error: redeclaration of ‘uint16_t packetIdSub’
Should. I indeed increment the packetIdSub?
Will this effect the onMqttMessage?
Regards
Ian
I’ve fixed my previous answer. Yes, you should create something like that (packetIdSub, packetIdSub2, etc…). It’s just for debugging information in your serial monitor.
Ok thanks, Rui
In the meantime, I’ve bought your ESP Micropython course.
Does seem friendlier than C+
Could you also give a quick example of multiple publishing and subscribing in Micropython, please?
Regards
Ian
Yes, MicroPython is definitely a more friendly programming language!
Let’s start editing the boot.py: https://github.com/RuiSantosdotme/ESP-MicroPython/blob/master/code/MQTT/Node_RED_Client/boot.py
You need to create variables for your MQTT topics. For example for the subscribe topics output and output2
topic_sub = b'output' topic_sub2 = b'output2'
To publish messages on different topics, you just need to define more variables. For example to publish MQTT messages on topic temp and hum:
topic_pub = b'temp' topic_pub2 = b'hum'
Then, in the main.py file: https://github.com/RuiSantosdotme/ESP-MicroPython/blob/master/code/MQTT/Node_RED_Client/main.py
You need to edit def connect_and_subscribe() function to subscribe to all your topics:
def connect_and_subscribe(): global client_id, mqtt_server, topic_sub client = MQTTClient(client_id, mqtt_server) client.set_callback(sub_cb) client.connect() client.subscribe(topic_sub) client.subscribe(topic_sub2) # you could subscribe to more topics print('Connected to %s MQTT broker, subscribed to %s topic and to %s topic' % (mqtt_server, topic_sub, topic_sub2)) return client
Then, in the def sub_cb(topic, msg), you create the conditions to do what happens when you receive a certain message in a specific topic:
def sub_cb(topic, msg): print((topic, msg)) if topic == b'output': if msg == b'on': print('output on') elif msg == b'off': print('output on') elif topic == b'output2': if msg == b'on': print('output on') elif msg == b'off': print('output on')
Then, to publish messages in any topic, you can add in the while True (for example), the following:
msg2 = b'your_humidity_value' # if you're using a float value to convert it to b'' #hum = 76.34 #msg2 = (b'{0:3.1f}'.format(hum)) client.publish(topic_pub2, msg2)
That will publish the msg2 content in the hum MQTT topic.
Hello Rui,
I have pump and relay1 working but not relays 2-4, would you be able to take a look at my Arduino sketching Node Red flow please?
Node red is sending the messages, but it seems like the sketch is not reading them.
Regards
Ian
I’m not sure Ian based on that information, but unfortunately I can’t debug custom code due to time constraints… I can only help if you encounter a technical issue with an exact code in the course. I can also provide small sample codes to expand something in the course, but after that I can debug custom projects.
I recommend double-checking the MQTT topics are properly set (they are case-sensitive). Thanks!
Ok yes, I understand. I’ve checked the MQTT Topics and your right, I had them set wrong in the flow.
How embarrassing, sorry!!
Regards
Ian
No problem! I’m glad you figured it out, they need to match exactly (they are case sensitive too). Otherwise, they will never connect. Regards,
Rui
Looking for a way use multiple esp8266’s with MQTT on RPi. I have been going thru the home automation course but I don’t see anything in there on how to set up more than 1 unit.
Does the answer above for the 32 also work for the 8266? If so, I will try to figure it out but if not, is there a sample I can see just for the 8266?
Thanks,
Bob