Такая проблема, работаю над скетчем для Arduino UNO + Ethernet Shild W5100, который будет управлять реле по протоколу MQTT программно через систему автоматизации Умного дома MajorDoMo, или вручную с выключателей-кнопок + отображать в системе MajorDoMo состояние реле (Вкл./Выкл., 0 или 1) для каждой релюшки. Только пока не могу понять как сделать управление Вкл./Выкл. с отправкой статуса о реле через топики по MQTT и выключателей. Уже долго мучаюсь над кодом, помогите пожалуйста. Спойлер: Код: Код (C++): /* Переделываю скетч для реле */ #include <SPI.h> // Библиотека SPI шины #include <Ethernet.h> // Ethernet библиотека #include <PubSubClient.h> // Библиотека MQTT #include <EEPROM.h> // Библиотека EEPROM #define Relay1 2 // Реле №1 #define Relay2 3 // Реле №2 #define relays_topic1 "home/data/status/Relay/1" //публикуемый топик #define BUTTON_1 6 // Кнопка-выключатель №1 #define BUTTON_2 7 // Кнопка-выключатель №2 #define relays_topic2 "home/data/status/Relay/2" //публикуемый топик #define UNUSED(expr) do { (void)(expr); } while (0) /*Безсмысленный цикл для callback убирающий предупреждение с компилятора*/ long last_mls3 = millis(); //функция времени для отправки топиков bool stateRelay1 = false; // Состояние Реле №1 bool wasButtonDown1 = false; // Состояние 1-й кнопки bool stateRelay2 = true; // Статус Реле №2 bool wasButtonDown2 = false; // Объявляем что кнопка №2 не нажата 0 int Address1 = 0; // Адреса EEPROM для хранения значений int Address2 = 2; // Задаём mac и ip адреса в Локальной сети byte mac[] = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED }; IPAddress ip{192, 168, 1, 74}; //ip Адрес Ethernet Shild'a Arduino IPAddress server{192, 168, 1, 70}; //ip Адрес для MQTT Брокера // Шапка Функции Callback для объявления и Инициализации PubSubClient void callback(char* topic, byte* payload, unsigned int length); EthernetClient ethClient; // Инициализируем Ethernet клиент PubSubClient client(server, 1883, callback, ethClient); // Инициализируем MQTT клиент // Функция Callback void callback(char* topic, byte* payload, unsigned int length) { //Используем идентификатор UNUSED для устранения Warning'а при компиляции UNUSED(topic); client.publish("home/data/status/Relay", payload, length); } void setup() { pinMode(Relay1, OUTPUT); // Задаём Реле №1 как Выход pinMode(BUTTON_1, INPUT); // Задаём кнопку №1 как Вход pinMode(Relay2, OUTPUT); pinMode(BUTTON_2, INPUT); Serial.begin(9600); // Задаём скорость порта в БОД'ах. Serial.println(F("Relay test!")); /* Тестовое сообщ. при откр. Монитора порта. Так же обёртываем сообщения в макрос F() для экономии ОЗУ */ Ethernet.begin(mac, ip); // Инициализируем mac, ip delay(100); //ждем 100 милисекунд client.connect("RelayClient"); //конектимся с брокером как клиент client.subscribe(relays_topic1); //подписываемся на топик client.subscribe(relays_topic2); //подписываемся на топик //цикл считывания значения из EEPROM для реле №1 if ( EEPROM.read(Address1) ) { digitalWrite(Relay1, HIGH); } else { digitalWrite(Relay1, LOW); } //цикл считывания значения из EEPROM для реле №2 if ( EEPROM.read(Address2) ) { digitalWrite(Relay2, HIGH); } else { digitalWrite(Relay2, LOW); } } // Функция для переподключения соединения с Брокером void reconnect() { // Повторяем, пока не переподключимся... while (!client.connected()) { // Логическое НЕ "!" - Проверяем, если клиент не Законнектен.... // Попытка подключиться if (client.connect("RelayClient")) { // Если RelayClient клиент подключен... Serial.println(F("Connected!")); // Выводим сообщ., что подключено! } else { Serial.print(F("failed connected - ")); // Ощибка соединения Serial.println(F("Jdem 5 seconds")); // Ждём 5 секунд delay(5000); } } } // Функция для кнопки №1 (функция для сенсорной кнопки) void Button1() { byte sensButtonVal = digitalRead(BUTTON_1); // Читаем значение с сенсорной кнопки bool isButtonDown1 = sensButtonVal; if (isButtonDown1 && !wasButtonDown1) { stateRelay1 = !stateRelay1; //delay(10); // Для сенсорной кнопки защита от дребезга некчему } wasButtonDown1 = isButtonDown1; digitalWrite(Relay1, stateRelay1); } // Функция для кнопки №2 (функция для механической кнопки) void Button2() { bool isButtonDown2 = digitalRead(BUTTON_2); if (isButtonDown2 && !wasButtonDown2) { stateRelay2 = !stateRelay2; delay(10); // Защита от дребезга } wasButtonDown2 = isButtonDown2; digitalWrite(Relay2, stateRelay2); } void loop() { if (!client.connect("RelayClient")) { // Если RelayClient клиент НЕ подключен... reconnect(); // Запускаем функцию переподключения } client.loop(); Button1(); Button2(); }