Задуман такой проект для управления блоком из 8 реле при помощи Arduino+W5100(можно и любой другой сетевой модуль). В найденном интернете скече убрал всё для меня не нужное и добавил то что нужно и подстроил для себя, что-бы можно было управлять 8-ю реле по mqtt протоколу. Всё работает, команды посылаются ответы состояния приходят (между прочем хорошая и дешёвая альтернатива реле управляемым по LAN). 1. Вопрос возник, когда захотелось иметь команду включения/отключения всех реле одной командой. Конечно можно сделать послание команд со стороны умного дома по mqtt, но это в крайнем случае. 2. Вопрос. Неплохо было бы всё записывать в память EEPROM состояние пинов, если при сбое питания всё восстанавливалось в последнее состояние. Выкладываю скеч. Знаками //*// обозначены безуспешные попытки решения данного вопроса Спойлер: connect relays to mqtt server Код (C++): /* connect to mqtt server, send and recive Arduino Nano W5100 */ #include <SPI.h> #include <Ethernet.h> #include <PubSubClient.h> //#include <EEPROM.h> const int relay1 = 2; const int relay2 = 3; const int relay3 = 4; const int relay4 = 5; const int relay5 = 6; const int relay6 = 7; const int relay7 = 8; const int relay8 = 9; //*// const int relayAll[] = { 2, 3, 4, 5, 6, 7, 8, 9 }; //*// int pinCount = 8; // Update these with values suitable for your network. byte mac[] = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED }; byte server[] = { 192, 168, 1, 140 }; byte ip[] = { 192, 168, 1, 132 }; void callback(char* topic, byte* payload, unsigned int length) { int r,hl; Serial.print("Message arrived ["); Serial.print(topic); Serial.print("] "); ////****/// char receivedChar = (char)payload[0]; Serial.print(receivedChar); if(receivedChar=='1') hl = LOW; else hl = HIGH; if(String(topic)=="PowerPanel/relay1") r = relay1; else if(String(topic)=="PowerPanel/relay2") r = relay2; else if(String(topic)=="PowerPanel/relay3") r = relay3; else if(String(topic)=="PowerPanel/relay4") r = relay4; else if(String(topic)=="PowerPanel/relay5") r = relay5; else if(String(topic)=="PowerPanel/relay6") r = relay6; else if(String(topic)=="PowerPanel/relay7") r = relay7; else if(String(topic)=="PowerPanel/relay8") r = relay8; //*// else if(String(topic)=="PowerPanel/relayAll") //*// r = relayAll; else r = relay1; //back; digitalWrite(r, hl); Serial.println(); } EthernetClient ethClient; PubSubClient client(server, 1883, callback, ethClient); void reconnect() { // Loop until we're reconnected while (!client.connected()) { Serial.println("Attempting MQTT connection..."); // Attempt to connect if (client.connect("arduinoPowerPanel")) { Serial.println("connected"); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); delay(5000); } } } void setup() { Serial.begin(9600); Ethernet.begin(mac, ip); pinMode(relay1, OUTPUT); pinMode(relay2, OUTPUT); pinMode(relay3, OUTPUT); pinMode(relay4, OUTPUT); pinMode(relay5, OUTPUT); pinMode(relay6, OUTPUT); pinMode(relay7, OUTPUT); pinMode(relay8, OUTPUT); //*// for (int thisPin = 0; thisPin < pinCount; thisPin++) {pinMode(relayAll[thisPin], OUTPUT);} //*// for (int thisPin;) {pinMode(relayAll[thisPin], OUTPUT);} if (client.connect("arduinoPowerPanel")) { Serial.print("online"); client.publish("PowerPanel/relay1", "1"); client.subscribe("PowerPanel/relay1"); client.publish("PowerPanel/relay2", "1"); client.subscribe("PowerPanel/relay2"); client.publish("PowerPanel/relay3", "1"); client.subscribe("PowerPanel/relay3"); client.publish("PowerPanel/relay4", "1"); client.subscribe("PowerPanel/relay4"); client.publish("PowerPanel/relay5", "1"); client.subscribe("PowerPanel/relay5"); client.publish("PowerPanel/relay6", "1"); client.subscribe("PowerPanel/relay6"); client.publish("PowerPanel/relay7", "1"); client.subscribe("PowerPanel/relay7"); client.publish("PowerPanel/relay8", "1"); client.subscribe("PowerPanel/relay8"); //*// client.publish("PowerPanel/relayAll", "1"); //*// client.subscribe("PowerPanel/relayAll"); } } void loop() { if (!client.connected()) { reconnect(); } client.loop(); }
Например: Код (C++): if(String(topic)=="PowerPanel/relay1") r = relay1; else if(String(topic)=="PowerPanel/relay2") r = relay2; else if(String(topic)=="PowerPanel/relay3") r = relay3; else if(String(topic)=="PowerPanel/relay4") r = relay4; else if(String(topic)=="PowerPanel/relay5") r = relay5; else if(String(topic)=="PowerPanel/relay6") r = relay6; else if(String(topic)=="PowerPanel/relay7") r = relay7; else if(String(topic)=="PowerPanel/relay8") r = relay8; else if(String(topic)=="PowerPanel/relayAll") r = 255; else r = relay1; if (r == 255) for (byte i = 0; i < pinCount - 1; i++) digitalWrite(relayAll[i], hl); else digitalWrite(r, hl);
ммда дёрнуло меня... Спасибо за помощь всё сработало, вкл/выкл все реле но вылезла другая проблема, по mqtt отправляется ответ статуса только 1 или 0, по адресу PowerPanel/relayAll , а ведь нужно что он менялся на всех восьми реле. Что опят какой- то массив создавать?
Вы наверное не так поняли. В этом скетче всё отлично работает, управляется всё по MQTT протоколу, по лан сети принимает команды и отсылает ответы о состоянии, но есть одна неточность, когда посылаешь команду чтобы включить все реле одной командой она выполняется, но вот ответ возвращается не по всем реле и сервере не отображается изменившееся статус subscribe "PowerPanel/relayAll" -- publish "PowerPanel/relayAll", "1", а надо как-то так PowerPanel/relay1, PowerPanel/relay2...., PowerPanel/relayAll или не не прав.
По команде relayAll надо не только включать каждое реле по списку, но и менять их статус. В коде, что вам написал Fogary в сообщении #2 в отработку команды (r==255) добавьте Код (C++): if (r == 255) for (byte i = 0; i < pinCount - 1; i++) { digitalWrite(relayAll[i], hl); String ss = "PowerPanel/relay" + String(i+1); client.publish(ss, "1"); client.subscribe(ss); } else digitalWrite(r, hl);
Спасибо что помогаете, как бы идею понял , но почему то в этом месте error: 'client' was not declared in this scope client.publish( ss, "1" ); если переношу эти две строки client.publish( ss, "1" ); client.subscribe( ss ); в условие if (client.connect("arduinoPowerPanel")) {... тогда ошибки не показывает, но также ни чего и не происходит нового скетч работает по предыдущему сценарию. Спойлер: MQTT+arduino rele Код (C++): /* connect to mqtt server, send and recive Arduino Nano W5100 HL-58S */ #include <SPI.h> #include <Ethernet.h> #include <PubSubClient.h> //#include <EEPROM.h> const int relay1 = 2; const int relay2 = 3; const int relay3 = 4; const int relay4 = 5; const int relay5 = 6; const int relay6 = 7; const int relay7 = 8; const int relay8 = 9; const int relayAll[] = { 2, 3, 4, 5, 6, 7, 8, 9 }; int pinCount = 9; // Update these with values suitable for your network. byte mac[] = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED }; byte server[] = { 192, 168, 1, 140 }; byte ip[] = { 192, 168, 1, 132 }; void callback(char* topic, byte* payload, unsigned int length) { int r,hl; Serial.print(" Message arrived ["); Serial.print(topic); Serial.print("] "); ////****/// char receivedChar = (char)payload[0]; Serial.print(receivedChar); if(receivedChar=='1') hl = LOW; else hl = HIGH; if(String(topic)=="PowerPanel/relay1") r = relay1; else if(String(topic)=="PowerPanel/relay2") r = relay2; else if(String(topic)=="PowerPanel/relay3") r = relay3; else if(String(topic)=="PowerPanel/relay4") r = relay4; else if(String(topic)=="PowerPanel/relay5") r = relay5; else if(String(topic)=="PowerPanel/relay6") r = relay6; else if(String(topic)=="PowerPanel/relay7") r = relay7; else if(String(topic)=="PowerPanel/relay8") r = relay8; else if(String(topic)=="PowerPanel/relayAll") r = 255; else r = relay1; if (r == 255) for (byte i = 0; i < pinCount - 1; i++) // digitalWrite(relayAll[i], hl); { digitalWrite(relayAll[i], hl); String ss = "PowerPanel/relay" + String(i+1); client.publish( ss, "1" ); client.subscribe( ss ); } else digitalWrite(r, hl); } EthernetClient ethClient; PubSubClient client(server, 1883, callback, ethClient); void reconnect() { // Loop until we're reconnected while (!client.connected()) { Serial.println(" Attempting MQTT connection..."); // Attempt to connect if (client.connect("arduinoPowerPanel")) { Serial.println("connected"); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); delay(5000); } } } void setup() { Serial.begin(9600); Ethernet.begin(mac, ip); pinMode(relay1, OUTPUT); pinMode(relay2, OUTPUT); pinMode(relay3, OUTPUT); pinMode(relay4, OUTPUT); pinMode(relay5, OUTPUT); pinMode(relay6, OUTPUT); pinMode(relay7, OUTPUT); pinMode(relay8, OUTPUT); if (client.connect("arduinoPowerPanel")) { Serial.print("online"); client.publish("PowerPanel/relay1", "1"); client.subscribe("PowerPanel/relay1"); client.publish("PowerPanel/relay2", "1"); client.subscribe("PowerPanel/relay2"); client.publish("PowerPanel/relay3", "1"); client.subscribe("PowerPanel/relay3"); client.publish("PowerPanel/relay4", "1"); client.subscribe("PowerPanel/relay4"); client.publish("PowerPanel/relay5", "1"); client.subscribe("PowerPanel/relay5"); client.publish("PowerPanel/relay6", "1"); client.subscribe("PowerPanel/relay6"); client.publish("PowerPanel/relay7", "1"); client.subscribe("PowerPanel/relay7"); client.publish("PowerPanel/relay8", "1"); client.subscribe("PowerPanel/relay8"); client.publish("PowerPanel/relayAll", "1"); client.subscribe("PowerPanel/relayAll"); //client.publish("ss", "1"); //client.subscribe("ss"); } } void loop() { if (!client.connected()) { reconnect(); } client.loop(); }
Строчки Код (C++): EthernetClient ethClient; PubSubClient client(server, 1883, callback, ethClient); перенесите выше процедуры callback() - это же должно быть очевидно... Вы совсем ничего в этой программе не понимаете? - списали код в инете?
А почему вас это удивляет, ведь на этом форуме около 90% таких как я. Я в первом посте написал что это всё выудил в инете. Собирал из кусков методом проб и ошибок. Но вот именного такого не нашёл. Этот https://hi-lab.ru/ АМС такие возможности и имеет, но туда вникать всё это из за нескольких реле стоит ли. По моему очень не плохое и довольно простое и дешёвое устройство которое можно без проблем согласовать как с Domoticz, OpenHab, MojorDomo и прочих платформ умного дома, там где можно проложить кабеля. Вот если не нужно включение всех реле сразу а управлять отдельными нагрузками, можно уже пользоваться, это открытый проект Была такая мысль переставить эти строки выше, но когда это сделал посыпалось уже н-цать строк ошибок в том числе и в езернет библиотеках, как -то не вникал особо что там не так, вернул всё в прежнее состояние.
Лучше так: Код (C++): void onPins() { digitalWrite(нужный пин, состояние); // И т.д. } А потом в loop(е) //onPins();