Cтранно работает скетч для nodeMCU, подскажите что не так

В общем затея была такова - сделать умный выключатель света (но он оказался умнее меня) на nodeMCU, с переключением от кнопки и одновременно через mqtt брокера. Покопавшись маленько в теме собрал вот такого вот франкенштейна (код приведен внизу).
Все запустилось, но! Переключение от кнопки не вызывает нареканий, разве что пока не подключится к mqtt-брокеру не фурычит, а вот с переключением от сообщений в топике проблема. Суть проблемы в следующем - пока не зажмешь кнопку, реагировать на сообщения в топике он не желает. Как быть и что делать? Заранее спасибо за помощь!

#include <PubSubClient.h>
#include <ESP8266WiFi.h>

const char* ssid = "12345678";
const char* password = "12345678";
const char* mqtt_server = "192.168.1.86";
const int mqtt_port = 1883;
const char* mqtt_topic = "LedState";
const char* mqtt_topic_2 = "LedChange";


const int ledPin = LED_BUILTIN; // Пин подключения светодиода
const int buttonPin = 14; // Пин подключения сенсорной кнопки

WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE  (50)
char msg[MSG_BUFFER_SIZE];
int value = 0;

bool isLedOn = false;



void callback(char* topic, byte* payload, unsigned int length) {
String message;
for (int i = 0; i < length; i++) {
message += (char)payload[i];
}
if ((char)payload[0] == '1') {
    digitalWrite(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
    // but actually the LED is on; this is because
    // it is active low on the ESP-01)
    
  } else {
    digitalWrite(BUILTIN_LED, HIGH);  // Turn the LED off by making the voltage HIGH
  }
}
void sendMessage(bool msg){
  if (msg){
    client.publish(mqtt_topic, "ON");
  } else {
    client.publish(mqtt_topic, "OFF");
  }
}
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("outTopic", "hello world");
      // ... and resubscribe
      client.subscribe(mqtt_topic);
      client.subscribe(mqtt_topic_2);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT);

Serial.begin(115200);

WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Подключение к Wi-Fi...");
}
Serial.println("Подключено к Wi-Fi");

client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
}

void loop() {
if (!client.connected()) {
    reconnect();
  }

client.loop();

unsigned long now = millis();
  if (now - lastMsg > 2000) {
    lastMsg = now;
    ++value;
    snprintf (msg, MSG_BUFFER_SIZE, "hello world #%ld", value);
    Serial.print("Publish message: ");
    Serial.println(msg);
    client.publish("outTopic", msg);
  }
client.setCallback(callback);
if (digitalRead(buttonPin) == LOW) { // Если кнопка нажата
    delay(20); // Делаем задержку для устранения дребезга контактов
    if (digitalRead(buttonPin) == LOW) { // Если кнопка до сих пор нажата
      isLedOn = !isLedOn; // Инвертируем флаг состояния светодиода

      if (isLedOn) {
        digitalWrite(ledPin, HIGH); // Включаем светодиод
        sendMessage(!isLedOn);
      } else {
        digitalWrite(ledPin, LOW); // Выключаем светодиод
        sendMessage(!isLedOn);
      }

      while (digitalRead(buttonPin) == LOW) { // Если кнопка все еще нажата
        delay(10); // Делаем небольшую задержку
      }
    }
  }
}

Простите, я удалил своё сообщение. С человеком с таким ником мне говорить не о чем. Надеюсь, кто-нибудь Вам поможет, но без меня.

4 лайка

В 112 и 115 все работает как нужно, но у меня ещё сделано включение/выключение если в топик LedChange приходит 0 или 1, так вот если кнопка не зажата, то он не реагирует на сообщения в топике, как только зажима кнопку, начинает реагировать

А по поводу ника, то какая собственно разница хоть царицей назовусь, не понимаю чего так реагировать

А в остальном понимаешь?

Значит, понималка не выросла, но это не моя проблема. Всего доброго.

нужно банить

всего недоброго (ему)

Спасибо всем большое, все такие отзывчивые, все по теме, сразу стало всё ясно - тут собрались какие то мудки и подссные язвы-комментаторы

как сам себя назовёшь - так и поплывёшь по проруби

1 лайк

Что-то я тоже не понял, что не так с ником. Оскорбляет чувства верующих? А у нас тут храм разве?
По мне так слово ровно из того же ряда, как брейнфак

2 лайка

Тем не менее, хотелось бы вернуться к теме, почему не работает так как нужно, прошу оставлять конструктивные комментарии

При чём тут чувства верующих? Такой ник неприемлем лично для меня. Я никого ни к чему не призывал, никому ничего не запрещал, в спортлото не писал, просто лично я, по своим личным мотивам, не хочу общаться с человеком, выбравшим такой ник. Почему? Да, потому, что не хочу. Надеюсь, я не обязан?

1 лайк

Все все, с вами все понятно, я попросил писать комментарии по теме, так что прошу уже закончить с разборками

Конечно не обязаны. Не надо так волноваться

Да, Господь с Вами, если я за что и волнуюсь, так только за то, пятница 13-ое как-то впустую проходит :frowning:

Попробуйте убрать строку 105, она в ЛУПе лишняя

Прочитать собственный код, может быть? У тебя даже комментарий стоит

// Если кнопка нажата

Ты это во сне написал, что ли?

1 лайк

Её раньше не было, все равно не работало, когда её добавил ничего не поменялось, вы правы она лишняя но ни на что все равно не влияет

То что находится начиная с 105 строки - это при нажатии кнопки он переключает состояние светодиода, и отправляет в топик LedState сообщение о состоянии светодиода. Там нет обработки входящих сообщений от топика LedChange, у меня эта обработка находится в строках 26 - 39, а в loopе подозреваю что он находится в client.loop. Но как то странно вызывается, только когда нажата кнопка, такое ощущение что он ждёт прерывания от кнопки, чтобы выполнять все остальное

Потому что только при нажатой кнопке запускается цикл в строчках 119-120