Reputation: 43
EDIT: The topics to publish and subscribe are correct even if they look different. with my publish, I writing on the field 4. Moreover I run also MQTT.fx in sub/pub mode with the same topics and it works perfectly.
I want to use mqtt with my NodeMCU with esp8266. I adapted simple MQTT example to my minimal project. In my code (attached below) I'm trying to publish and subscribe to a ThingSpeak channel. The publish function does not have any problem, it publishes every time it is called. But the callback function is simply ignored, my code never enters in it.
To give more infor here you have My settings:
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
// Update these with values suitable for your network.
const char* ssid = "*****";
const char* password = "*****";
const char* mqtt_server = "mqtt.thingspeak.com";
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
randomSeed(micros());
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Ciao sono la callback1\n");
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
// Switch on the LED if an 1 was received as first character
if ((char)payload[0] == '1') {
Serial.print("Ciao sono la callback2\n");
digitalWrite(BUILTIN_LED, LOW); // Turn the LED on (Note that LOW is the voltage level
// but actually the LED is on; this is because
// it is acive low on the ESP-01)
} else {
Serial.print("Ciao sono la callback3\n");
digitalWrite(BUILTIN_LED, HIGH); // Turn the LED off by making the voltage HIGH
}
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Create a random client ID
String clientId = "ESP8266Client-";
clientId += String(random(0xffff), HEX);
// Attempt to connect
if (client.connect(clientId.c_str())) {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish("channels/517055/publish/V4ZW4Y01ZLFD5XYR", "field5=7&status=MQTTPUBLISH");
// ... and resubscribe
client.subscribe("channels/517055/subscribe/fields/field4");
Serial.print("Ciao sono subscribe 01\n");
} 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() {
pinMode(BUILTIN_LED, OUTPUT); // Initialize the BUILTIN_LED pin as an output
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
Serial.print("Ciao sono la callback 10\n");
client.subscribe("channels/517055/subscribe/fields/field4");
Serial.print("Ciao subscribe 10\n");
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
long now = millis();
if (now - lastMsg > 2000) {
lastMsg = now;
++value;
snprintf (msg, 75, "field4= %ld&status=MQTTPUBLISH", value);
Serial.print("Publish message: ");
Serial.println(msg);
client.publish("channels/517055/publish/V4ZW4Y01ZLFD5XYR", msg);
}
}
Moreover here you have my serial monitor output:
Connecting to ZICHICHI
scandone
scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 1
cnt
connected with ZICHICHI, channel 1
dhcp client start...
............ip:192.168.1.68,mask:255.255.255.0,gw:192.168.1.254
.
WiFi connected
IP address:
192.168.1.68
Ciao sono la callback 10
Ciao subscribe 10
Attempting MQTT connection...connected
Ciao sono subscribe 01
Publish message: field4= 1&status=MQTTPUBLISH
Publish message: field4= 2&status=MQTTPUBLISH
pm open,type:2 0
Publish message: field4= 3&status=MQTTPUBLISH
Publish message: field4= 4&status=MQTTPUBLISH
Publish message: field4= 5&status=MQTTPUBLISH
Publish message: field4= 6&status=MQTTPUBLISH
Publish message: field4= 7&status=MQTTPUBLISH
Publish message: field4= 8&status=MQTTPUBLISH
Publish message: field4= 9&status=MQTTPUBLISH
Publish message: field4= 10&status=MQTTPUBLISH
Publish message: field4= 11&status=MQTTPUBLISH
Publish message: field4= 12&status=MQTTPUBLISH
Publish message: field4= 13&status=MQTTPUBLISH
Publish message: field4= 14&status=MQTTPUBLISH
Publish message: field4= 15&status=MQTTPUBLISH
Publish message: field4= 16&status=MQTTPUBLISH
Publish message: field4= 17&status=MQTTPUBLISH
I hope someone know what I made wrong.
Upvotes: 0
Views: 3707
Reputation: 43
SOLVED
The code posted by me and the code posted by @karan was correct. The problem I had was realeted with thingspeak Broker connection and the Thingspeak documentation, that wasn't updated at the time. In particular is necessary to pass MQTT_APIKEY and USERNAME to establish connection with mqtt broker, even with PUBLIC channel.
The problem is solved passing these 2 parameters in connection step, like this:
client.connect("ESP8266Client-", "Your_username", "MQTT_APIKEY");
Many thanks to @karan that help me, and improved my code.
Upvotes: 0
Reputation: 483
Actually, your Code is Almost correct but the loop() function is executing to Infinity. basically, the code got stuck in the loop function, so that's why its not able to subscribe. Even if it is subscribed also, loop function will dominate on callback function and callback function will not be called, it will act as a NULL
Here is the Code, I have made some changes. Just try out
**This code will not keep on Publish the payload every time, If you want you can add the client.plublish in the loop() before client.loop()
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
// Update these with values suitable for your network.
const char* ssid = "*****";
const char* password = "*****";
const char* mqtt_server = "mqtt.thingspeak.com";
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
randomSeed(micros());
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Ciao sono la callback1\n");
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
// Switch on the LED if an 1 was received as first character
if ((char)payload[0] == '1') {
Serial.print("Ciao sono la callback2\n");
digitalWrite(BUILTIN_LED, LOW); // Turn the LED on (Note that LOW is the voltage level
// but actually the LED is on; this is because
// it is acive low on the ESP-01)
} else {
Serial.print("Ciao sono la callback3\n");
digitalWrite(BUILTIN_LED, HIGH); // Turn the LED off by making the voltage HIGH
}
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Create a random client ID
String clientId = "ESP8266Client-";
clientId += String(random(0xffff), HEX);
// Attempt to connect
if (client.connect(clientId.c_str())) {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish("channels/517055/publish/V4ZW4Y01ZLFD5XYR", "field5=7&status=MQTTPUBLISH");
// ... and resubscribe
client.subscribe("channels/517055/subscribe/fields/field4");
Serial.print("Ciao sono subscribe 01\n");
} 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() {
pinMode(BUILTIN_LED, OUTPUT); // Initialize the BUILTIN_LED pin as an output
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
Serial.print("Ciao sono la callback 10\n");
connectmqtt();
}
void loop() {
if (!client.connected()) {
reconnect();
}
long now = millis();
if (now - lastMsg > 2000) {
lastMsg = now;
++value;
snprintf (msg, 75, "field4= %ld&status=MQTTPUBLISH", value);
Serial.print("Publish message: ");
Serial.println(msg);
}
client.loop();
}
void connectmqtt()
{
client.connect("ESP8266Client-");
{
Serial.println("connected");
// Once connected, publish an announcement...
// ... and resubscribe
client.subscribe("channels/517055/subscribe/fields/field4");
client.publish("channels/517055/publish/V4ZW4Y01ZLFD5XYR", msg);
if (!client.connected())
{
reconnect();
}
}
}
Upvotes: 1
Reputation: 768
You are subscribing to a different topic than a topic you are publishing to. Your publishing topic is "channels/517055/publish/V4ZW4Y01ZLFD5XYR" while you are subscribing to "channels/517055/subscribe/fields/field4".
Upvotes: 0