NodeMCU gets the command as byte* payload and atoi gives me 0
Hello, still learning. I have a NodeMCU (ESP8266) with PubSubClient controlling a LED strip through a MOSFET. On my Hermetry board there’s a slider that sends a command called light.set. I can see the message arrive in the serial monitor:
topic: v1/rpc/req/17
payload: {"method":"light.set","params":{"level":42}}
But in my callback I can’t get the 42 out. I tried:
void callback(char* topic, byte* payload, unsigned int length) {
int level = atoi((char*)payload);
analogWrite(D5, level);
}
level is always 0, sometimes a random big number. The strip doesn’t change. I also think the slider shows “Sent; waiting for the device” forever. What am I doing wrong?
Maybe cast it to a String first? String s = (char*)payload;
The payload isn’t null-terminated, so reading it as a C string runs past the end. That’s the random number.
Even with a null at the end, atoi on {“method”:… gives 0 because the first character is a brace. You need to parse the JSON.
Kevin A and Maria have both bits. I did nearly the same light controller for our office last year. Parse the JSON with ArduinoJson (it takes the buffer and length, so no null needed), pull the request id off the end of the topic, and answer on v1/rpc/res/ with that id. The “waiting for the device” stays because the board never gets an answer.
#include <ArduinoJson.h>
void callback(char* topic, byte* payload, unsigned int length) {
String t(topic);
String id = t.substring(t.lastIndexOf('/') + 1); // "17"
StaticJsonDocument<256> doc;
if (deserializeJson(doc, payload, length)) return;
if (doc["method"] == "light.set") {
int level = doc["params"]["level"] | -1; // -1 if missing
if (level >= 0 && level <= 100) {
analogWrite(D5, map(level, 0, 100, 0, 1023));
client.publish(("v1/rpc/res/" + id).c_str(), "{"ok":true}");
return;
}
}
client.publish(("v1/rpc/res/" + id).c_str(), "{"ok":false}");
}
ESP8266 analogWrite is 0-1023 by default, hence the map. And subscribe to v1/rpc/req/+ after every reconnect, not only in setup, or commands stop after the first Wi-Fi drop.
The topic list is on MQTT topics and payload reference.
It works!! The strip dims with the slider now and the board says Done. I had also been answering on v1/rpc/req/17 instead of res, so even when I got the number right nothing came back. Thank you Emily.
- Bu konuyu yanıtlamak için giriş yapmış olmalısınız.
Sohbete katılın
Soru sormak ve yanıtlamak, yararlı gönderileri beğenmek ve sorununuzu çözen yanıtı işaretlemek için oturum açın. Her katkı puan ve seviye kazandırır.

