Разбор сообщений с сервера MQTT

Я делаю домашнюю автоматизацию на базе NodeMCU. Я адаптировал код, найденный в Интернете, для управления устройством (скажем, светодиодом) через брокер MQTT, размещенный на Raspberry Pi. Это прекрасно работает. Но когда я пытаюсь масштабировать его для более чем одного устройства, я натыкаюсь на стену.

void callback(char* topic, byte* payload, unsigned int length)
{
  
  const char* t_bedroom_light1 = "/home/bedroom/light1";
  
  Serial.print("Topic from MQTT broker is : ");
  Serial.print(topic);
  char p = payload[0];

  // if MQTT comes a 0 turn OFF pin D4
  if (topic == "/home/bedroom/light1" && p == '0')
  {
    digitalWrite(LIGHT_PIN, LOW);
    Serial.println(" Turn Light Off! ");
  }

  // if MQTT comes a 1, turn ON pin D4
  if (topic == "/home/bedroom/light1" && p == '1')
  {
    digitalWrite(LIGHT_PIN, HIGH);
    Serial.println(" Turn Light On! " );
  }
}

Последовательный монитор получает и печатает тему правильно с сервера MQTT. Но topic == "/home/bedroom/light1" никогда не возвращает true. Если я удалю эту часть, то p =='0' или p=='1' прекрасно работает само по себе. Я попытался сравнить эту тему с локально объявленным массивом char, попытался преобразовать ее в String и сделать strcmp. Ничего. Что я делаю не так? Вот выход последовательного монитора

12:43:20.346 -> .......
12:43:24.187 -> WiFi connected
12:43:24.187 -> IP address: 
12:43:24.187 -> 192.168.1.5
12:43:24.187 -> Attempting MQTT connection...connected
12:43:30.752 -> Topic from MQTT broker is : /home/bedroom/light1

, 👍1


1 ответ


Лучший ответ:

1

Это не так, как вы сравниваете строки C.

Когда вы пишете

if (topic == "/home/bedroom/light1")

вы сравниваете , является ли тема указателя символа тем же значением, что и адрес строки "/home/bedroom/light1", чего, конечно, нет в данном случае.

Чтобы сравнить строки C, используйте функцию strcmp (), которая возвращает 0, если они идентичны.

if (strcmp(topic, "/home/bedroom/light1") == 0 && p == '0')
,

Тай, это сработало! Нуб во мне не знал, что массивы символов-это строки. На самом деле я попытался привести массив char к новой строке и использовал для этого strcmp, но по некоторым причинам это не сработало., @coldbreeze16

На самом деле массивы char-это не "Строки" (обратите внимание на заглавные буквы S), а c-строки, что является существенной разницей(https://forum.arduino.cc/index.php?topic=559153.0). Строки только не должны использоваться в устройствах с ограниченной памятью (или только очень экономно), в то время как c-строки (массивы символов) не демонстрируют тех же проблем., @StarCat

Что сказал @StarCat. К сожалению, строки C также позволяют очень легко стрелять себе в ногу. Это определенно одна из менее интуитивных частей языка Си, если только вы не пришли к Нему из программирования на ассемблере :), @romkey