Hey All,
I'm sending data to an esp8266 over mqtt and I need to know what kind of data is being sent from nodered. ascii? utf-8? or raw? or???
As far as I know I'm not declaring/defining these anywhere in my flows
thanks
Rich
Hey All,
I'm sending data to an esp8266 over mqtt and I need to know what kind of data is being sent from nodered. ascii? utf-8? or raw? or???
As far as I know I'm not declaring/defining these anywhere in my flows
thanks
Rich
Based on the mqtt protocol it looks like ascii
https://cedalo.com/blog/mqtt-packet-guide/''
Someone please verify that ascii is the standard for mqtt and nodered
Thanks
You can send anything you like, though I think the data actually sent is a raw buffer.
If you use the node red MQTT nodes it will handle it all for you. You can send the node a number, string, boolean etc. If you send the node an object it will be converted to a JSON string and the subscriber can convert it back to an object easily.
If you explain why you are asking the question then possibly someone will be able to tell you what you need to know.
I'm trying to parse the data on the esp8266 side and I need to know what's being sent.
The simplest is to publish a string. That will be received as a string by the standard esp MQTT code.
hmm, I think that's what I'm doing. Here's the flow in question
[
{
"id": "f77c465a8c64faee",
"type": "ui_slider",
"z": "cf08cb9713ba9cda",
"name": "",
"label": "slider",
"tooltip": "",
"group": "65963440961b63cc",
"order": 2,
"width": 0,
"height": 0,
"passthru": true,
"outs": "all",
"topic": "topic",
"topicType": "msg",
"min": 0,
"max": "255",
"step": 1,
"className": "",
"x": 210,
"y": 80,
"wires": [
[
"902ba5af9d02cea1"
]
]
},
{
"id": "902ba5af9d02cea1",
"type": "mqtt out",
"z": "cf08cb9713ba9cda",
"name": "",
"topic": "/hangingLamp/stream",
"qos": "",
"retain": "",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "1a947cf4658331dc",
"x": 440,
"y": 80,
"wires": []
},
{
"id": "65963440961b63cc",
"type": "ui_group",
"name": "HANGING LAMP",
"tab": "f3a8a67ff0904e39",
"order": 3,
"disp": true,
"width": "6",
"collapse": true,
"className": ""
},
{
"id": "1a947cf4658331dc",
"type": "mqtt-broker",
"name": "",
"broker": "192.168.1.217",
"port": "1883",
"clientid": "",
"autoConnect": true,
"usetls": false,
"protocolVersion": "4",
"keepalive": "60",
"cleansession": true,
"birthTopic": "",
"birthQos": "0",
"birthPayload": "",
"birthMsg": {},
"closeTopic": "",
"closeQos": "0",
"closePayload": "",
"closeMsg": {},
"willTopic": "",
"willQos": "0",
"willPayload": "",
"willMsg": {},
"userProps": "",
"sessionExpiry": ""
},
{
"id": "f3a8a67ff0904e39",
"type": "ui_tab",
"name": "HOME",
"icon": "dashboard",
"order": 1,
"disabled": false,
"hidden": false
}
]
ascii? raw? UTF-8?
Imo, always send JSON. JSON is extensible & if you realise 2 months down the line you need to add additional info (e.g. timestamp or label or units etc) you can add data to the payload without breaking the existing data.
I tried to post this as another thread but the moderator closed it saying this was too similar.
The topic was " Is it ok to ask an Arduino/esp8266 question here?
Hey All,
I've been trying to figure this out with help from the Arduino forums but it's proving difficult. I hope posting it here is appropriate.
I'm struggling with parsing mqtt from a slider in a node red to an esp8266 .
Here's my flow in question
[
{
"id": "f77c465a8c64faee",
"type": "ui_slider",
"z": "cf08cb9713ba9cda",
"name": "",
"label": "slider",
"tooltip": "",
"group": "65963440961b63cc",
"order": 2,
"width": 0,
"height": 0,
"passthru": true,
"outs": "all",
"topic": "topic",
"topicType": "msg",
"min": 0,
"max": "255",
"step": 1,
"className": "",
"x": 210,
"y": 80,
"wires": [
[
"902ba5af9d02cea1"
]
]
},
{
"id": "902ba5af9d02cea1",
"type": "mqtt out",
"z": "cf08cb9713ba9cda",
"name": "",
"topic": "/hangingLamp/stream",
"qos": "",
"retain": "",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "1a947cf4658331dc",
"x": 440,
"y": 80,
"wires": []
},
{
"id": "65963440961b63cc",
"type": "ui_group",
"name": "HANGING LAMP",
"tab": "f3a8a67ff0904e39",
"order": 3,
"disp": true,
"width": "6",
"collapse": true,
"className": ""
},
{
"id": "1a947cf4658331dc",
"type": "mqtt-broker",
"name": "",
"broker": "192.168.1.217",
"port": "1883",
"clientid": "",
"autoConnect": true,
"usetls": false,
"protocolVersion": "4",
"keepalive": "60",
"cleansession": true,
"birthTopic": "",
"birthQos": "0",
"birthPayload": "",
"birthMsg": {},
"closeTopic": "",
"closeQos": "0",
"closePayload": "",
"closeMsg": {},
"willTopic": "",
"willQos": "0",
"willPayload": "",
"willMsg": {},
"userProps": "",
"sessionExpiry": ""
},
{
"id": "f3a8a67ff0904e39",
"type": "ui_tab",
"name": "HOME",
"icon": "dashboard",
"order": 1,
"disabled": false,
"hidden": false
}
]
This works as intended. The problem arises on the Arduino side when I try to convert the payload to an int. It's been suggested that I need to know what kind of data is being sent over mqtt. I did some research and it seems the data is ascii but I've also read it "could" be raw data. This is where I'm stumbling.
Any advice is appreciated!
Arduino code
void ledControl(char* topic, byte* payload, unsigned int length) {
int modeBrightness = 255;
if (strcmp(topic, "/hangingLamp/stream") == 0){
(char)payload[0].toInt = modeBrightness; // How can I make this assignment?
Serial.println(modeBrightness); //toInt isn't working
}
}
that sounds like a good idea. However I've never parsed JSON on the arduino side. Do you happen to have an example?
If you send JSON, it will always be correctly parsed back to original type.
No, but this is a very very common thing & Google is definitely your friend here.
See my first reply in this post (JSON is the answer)
I am not entirely sure it is worth going for JSON if you have only a few data values to pass. What do you see if you print what you get from MQTT in the esp?
Are you using WifiClient for MQTT? To get a float value all I do is, for example,
void callback(char* topic, byte* payload, unsigned int length) {
String str = String();
for (int i = 0; i < length; i++) {
str += (char)payload[i];
}
if(strcmp(topic, "boiler/setpoint") == 0) {
Serial.println("setpoint received " + str);
setpoint = str.toFloat();
} else if(strcmp(topic, "boiler/enable") == 0) {
...
Here is excerpt from a sketch I used once to water my tomatoes...
It cannot run, because it is only parts, but I used ArduinoJson.h which parses JSON just fine.
#include <ArduinoJson.h>
void MQTT_reconnect() {
if (!mqttClient.connected()) {
if (!mqttClient.connect(MQTT_SERVER, MQTT_PORT)) {
Serial.print("MQTT connection failed! Error code = ");
Serial.println(mqttClient.connectError());
} else
{
Serial.println("You're connected to the MQTT broker!");
Serial.println();
}
}
}
void subscribeMQTTCommand() {
if (mqttClient.connected()) {
mqttClient.onMessage(onMqttMessage);
// subscribe to a topic
mqttClient.subscribe(TOPIC_COMMAND, 2);
}
}
void onMqttMessage(int messageSize) {
String topic = mqttClient.messageTopic();
// do something with the topic
StaticJsonDocument<256> doc;
deserializeJson(doc, mqttClient);
// use the JsonDocument as usual...
// access JSON elements via doc["name"]
if (doc["type"] == "pump") {
int dur = doc["duration"];
if (dur >= 0 && dur < 121) {
PUMP_DURATION = dur;
// run pump
} else {
// illegal duration
}
}
}
In your MQTT output in NR you choose what is being sent. Buffers or chars. You can absolutely use chars. Depending on what your output is, you have to deal with the int-parsing differently esp side.
If you simply want to parse an int from a char array or a buffer of chars you can use these functions:
int parseDigits(const byte* input) {
//size_t length = sizeof(input) / sizeof(input[0]);
size_t length = sizeof(input);
char* charInput = reinterpret_cast<char*>(const_cast<byte*>(input));
charInput[length+1] = '\0'; // add null terminator
int result = 0;
while (*charInput) {
if (isdigit(*charInput)) {
result = result * 10 + (*charInput - '0');
}
charInput++;
}
return result;
}
int parseDigits(const char* input) {
int result = 0;
while (*input) {
if (isdigit(*input)) {
result = result * 10 + (*input - '0');
}
input++;
}
return result;
}
In your case, where you're sending ascii chars the function you'd go with is the latter.
This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.