如何修复 arduino 变量在回调函数中获取额外数据?
how to fix arduino variable getting extra data in callback function?
使用mqtt回调函数时。我在每个 运行.
上得到了额外的字符和持久字符
void callback(char* topic, byte* payload, unsigned int length) {
unsigned long currentMillis = millis();
const char* STATE_OPEN = "OPEN";
const char* STATE_CLOSE = "CLOSE";
const char* STATE_STOP = "STOP";
char* msg = (char*)payload;
if(strcmp(topic, "office/shutter") == 0) {
Serial.println(msg);
Serial.print("Message:");
if(strcmp(msg, STATE_OPEN) == 0) {
digitalWrite(relay2, LOW);
digitalWrite(relay1, HIGH);
shutterRunTime = currentMillis;
}
if(strcmp(msg, STATE_CLOSE) == 0) {
digitalWrite(relay1, LOW);
digitalWrite(relay2, HIGH);
shutterRunTime = currentMillis;
}
if(strcmp(msg, STATE_STOP) == 0) {
digitalWrite(relay2, LOW);
digitalWrite(relay1, LOW);
shutterRunTime = currentMillis;
}
}
Serial.println();
Serial.println("-----------------------");
if((currentMillis - shutterRunTime) >= shutterMaxRun) {
digitalWrite(relay2, LOW);
digitalWrite(relay1, LOW);
}
/* Clear the strings */
memset(msg, 0, sizeof(msg));
}
如果我 post 在 mqtt CLOSE
上它工作。如果我在 mqtt OPEN
上 post,如果它在 CLOSE
之前完成,我会得到 OPENr
或者如果它在我得到 OPENE
之后完成
我试图将变量 msg
清空,甚至 memset
也不起作用。我怎样才能让它只给我有效负载的值。
当我做 Serial.print(length)
它给了我正确的 4
或 5
所以我对实际发生的事情感到困惑。
您不能只将字节数组 payload
转换为字符数组,然后将其视为字符串(空终止字符数组)
当您调用 Serial.println(msg)
时,println 不知道字符串有多长,因此将继续读取,直到它遇到它在内存中找到的第一个 null。到目前为止,听起来您很幸运,在传入 payload
字节数组的实际长度之后只有 1 或 2 个字节。
如果您想要一个只包含负载的字符串,您应该 malloc 一个新的字符数组,即 length
+ 1,并确保新数组中的最后一个字符设置为 0(空)。
您可能还应该在 const 字符串中包含空终止符,这样 strcmp 也能正常工作。
使用mqtt回调函数时。我在每个 运行.
上得到了额外的字符和持久字符void callback(char* topic, byte* payload, unsigned int length) {
unsigned long currentMillis = millis();
const char* STATE_OPEN = "OPEN";
const char* STATE_CLOSE = "CLOSE";
const char* STATE_STOP = "STOP";
char* msg = (char*)payload;
if(strcmp(topic, "office/shutter") == 0) {
Serial.println(msg);
Serial.print("Message:");
if(strcmp(msg, STATE_OPEN) == 0) {
digitalWrite(relay2, LOW);
digitalWrite(relay1, HIGH);
shutterRunTime = currentMillis;
}
if(strcmp(msg, STATE_CLOSE) == 0) {
digitalWrite(relay1, LOW);
digitalWrite(relay2, HIGH);
shutterRunTime = currentMillis;
}
if(strcmp(msg, STATE_STOP) == 0) {
digitalWrite(relay2, LOW);
digitalWrite(relay1, LOW);
shutterRunTime = currentMillis;
}
}
Serial.println();
Serial.println("-----------------------");
if((currentMillis - shutterRunTime) >= shutterMaxRun) {
digitalWrite(relay2, LOW);
digitalWrite(relay1, LOW);
}
/* Clear the strings */
memset(msg, 0, sizeof(msg));
}
如果我 post 在 mqtt CLOSE
上它工作。如果我在 mqtt OPEN
上 post,如果它在 CLOSE
之前完成,我会得到 OPENr
或者如果它在我得到 OPENE
我试图将变量 msg
清空,甚至 memset
也不起作用。我怎样才能让它只给我有效负载的值。
当我做 Serial.print(length)
它给了我正确的 4
或 5
所以我对实际发生的事情感到困惑。
您不能只将字节数组 payload
转换为字符数组,然后将其视为字符串(空终止字符数组)
当您调用 Serial.println(msg)
时,println 不知道字符串有多长,因此将继续读取,直到它遇到它在内存中找到的第一个 null。到目前为止,听起来您很幸运,在传入 payload
字节数组的实际长度之后只有 1 或 2 个字节。
如果您想要一个只包含负载的字符串,您应该 malloc 一个新的字符数组,即 length
+ 1,并确保新数组中的最后一个字符设置为 0(空)。
您可能还应该在 const 字符串中包含空终止符,这样 strcmp 也能正常工作。