I am trying to convert byte*
value to int
here is how I have it.
void mqttCallback(char* topic, byte* payload, unsigned int length) {
String topicStr = topic;
int* payload_value;
int updates_cal;
payload_value = (int*)payload;
//updates_cal = *payload_value;
Serial.print((int)payload_value);
delay(1);
Serial.println();
Serial.println("-----------------------");
}
I am getting MQTT payload as Integer value. Which I want to receive in my NodeMCU (ESP8266).
Is there any way to do this?
Thank you!
3 Answers 3
Judging by the comments, you are actually receiving your integer data as text, as a sequence of ASCII characters. This is what you send yourself using mosquitto_pub
. The buffer is apparently not zero-terminated.
If these characters represent an integer value, then the way to retrieve it as an integer value would be
char buffer[128];
// Make sure here that `length` is smaller than the above buffer size.
// Otherwise, you'd need a bigger buffer
// Form a C-string from the payload
memcpy(buffer, payload, length);
buffer[length] = '0円';
// Convert it to integer
char *end = nullptr;
long value = strtol(buffer, &end, 10);
// Check for conversion errors
if (end == buffer || errno == ERANGE)
; // Conversion error occurred
else
Sterial.println(value);
Another approach, which avoids using a separate large[ish] buffer just for the purposes of zero-termination, would be
// Build a `scanf` format string that will read no more than `length`
// characters without relying on zero-termination of the payload
char format[16];
snprintf(format, sizeof format, "%%%ud", length);
// Convert the payload
int payload_value = 0;
if (sscanf((const char *) payload, format, &payload_value) == 1)
Serial.println(payload_value);
else
; // Conversion error occurred
However, this approach is less protected from integer overflow than the previous one.
Note that most of the above "jumping through the hoops" is dedicated to adding a zero-terminator to the input buffer. If instead you opt for ensuring zero-termination on the sender's side, then it would all reduce to a simple
// Convert C-string to integer
char *end = nullptr;
long value = strtol((const char *) payload, &end, 10);
// Check for conversion errors
if (end == buffer || errno == ERANGE)
; // Conversion error occurred
else
Sterial.println(value);
No extra buffers required.
-
Comments are not for extended discussion; this conversation has been moved to chat.Majenko– Majenko2019年05月01日 16:04:52 +00:00Commented May 1, 2019 at 16:04
Don't know if you found an answer yet, but I had the exact same issue and eventually came up with this:
payload[length] = '0円'; // Add a NULL to the end of the char* to make it a string.
int aNumber = atoi((char *)payload);
Pretty simple in the end!
-
1Keep in mind that
payload[length]
is not part of the memory dedicated to the payload variable. The last item in the memory space of an array always islength-1
. Your approach may work most of the time, but you could potentialy overwrite other variables located at that place in memory.Steve2955– Steve29552020年04月09日 17:48:36 +00:00Commented Apr 9, 2020 at 17:48
byte*
means "pointer to byte(s). It is usually used to point to a byte buffer, and usually will also have a length value so you know how many bytes are in the buffer. It looks like your function does have a length value.
If you're certain that the data in the payload
parameter is a single int, and the length is correct for an int (2 bytes on Arduino I believe) then you should be able to cast the pointer to int*
type and then fetch the value from the buffer:
void mqttCallback(char* topic, byte* payload, unsigned int length) {
String topicStr = topic;
int payload_value;
int updates_cal;
if (length >= 2) {
//Cast payload to an int pointer and fetch the value
intValue = *((int*)payload);
}
}
-
I tried this, but there is some error. Its resetting my NodeMCU. Exception number is 9 is througing.user3201500– user32015002019年05月01日 13:17:40 +00:00Commented May 1, 2019 at 13:17
Explore related questions
See similar questions with these tags.
byte *
toint
, then you already have it, assuming thatint
is large enough to store an address on your platform. But what would be the point of this? Yourpayload_value
is an address.