i am struggeling with Arduino and MQTT to work as i want to.
The good news is, I can see both of my values in the serial monitor, but they are in the same string.
If i display the payload, i`l get 2 sets of numbers (ASCII ?)
I found out that Serial.print((char) payload[i] displays the 2 values i want to see.
But i need those 2 values to be separate from each other and to convert them to variables.
I`ve been searching for hours, but i am not getting anywhere....
this is the code so far:
// publish and subscribe
client.publish(topic, "p1monitor/smartmeter/consumption_kw");
client.publish(topic1, "p1monitor/smartmeter/production_kw");
client.subscribe(topic);
client.subscribe(topic1);
}
//Callback loop:
void callback(char *topic, byte *payload, unsigned int length) {
for (int i = 0; i < length; i++) {
Serial.print((char) payload[i]);
}
Serial.println();
}
void loop() {
client.loop();
}
the output in the serial monitor looks like this:
0.151
0.007
0.148
0.007
0.151
0.007
0.146
the first line 0.151 is the energy consumtion (topic) en the following line is the energy production (0.007, topic1).
How do i separate the 2 topics from the incoming data and convert them to a variable ?
I can convert the payload to a float, but that isthe whole payload, not the to values.
I`m stuck...
The topic name is, not surprisingly, in the topic variable in the form of a pointer to an array of chars terminated by a zero. Such an array is commonly referred to as a C style string (NOTE - not a String - capital S)
To compare a string with a value you can use the appropriately name strcmp() function, like this
if (strcmp(topic, "p1monitor/smartmeter/consumption_kw" == 0)
{
// we got a message from the p1monitor/smartmeter/consumption_kw topic
}
You can turn the payload into a float like this
char messageBuffer[30];
memcpy(messageBuffer, payload, length); copy the message
messageBuffer[length] = '\0'; //turn it into a string
float theNumber = atof(messagBuffer); //convert to a float
The principle would be that on receipt of a message the topic would be compared to the appropriate string and the associated variable would be extracted from the payload
If you put the topic name strings in an array then you don't even need two sets of code to do the comparison because you could iterate through the array and do the comparison
NOTE that I have not had the opportunity to test the code snippets that I posted. The principles are sound but there may be typos in there
You quoted part of my answer and mentioned an error in another part
Please post your full sketch and the full error message copied from the IDE using the button provided for the purpose. Please use code tags when you post both of them
There's a typo in the (untested) suggested code, a missing parenthesis. But first
Why are you sending the topic names to the topic?
Do you control the format of the messages? If subscribers are expecting bare numbers, publishing text -- as above -- might break them. And if it's just a number, it may be possible to send it directly as a 4-byte float or 8-byte double, which would obviate conversion from string.
Pick better names for variables, especially since the variable name topic is the first argument in the callback function.
If you really are only subscribing to two topics, you only have to check for one.
void callback(const char *topic, byte *payload, unsigned int length) {
if (strcmp(topic, topicConsumption) == 0) {
// that one
} else {
// the other one
}
}
if (strcmp(topic, "p1monitor/smartmeter/consumption_kw" == 0)
{
// we got a message from the p1monitor/smartmeter/consumption_kw topic
}
Should be
if (strcmp(topic, "p1monitor/smartmeter/consumption_kw" == 0)) //added missing )
{
// we got a message from the p1monitor/smartmeter/consumption_kw topic
}