одной командой на все пины
- Войдите на сайт для отправки комментариев
Чт, 21/06/2018 - 01:46
Мне нужно управлять как по отдельности реле, так и с одной командой. Не хватает знаний, пробовал и так и сяк всё ровно не получается.
кусок кода
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;
int relayAll[] = {2,3,4,5,6,7,8,9}; //пробовал с масивом
пробовал с масивом , и с функцией loop allrele{...}
else if(String(topic)=="PowerPanel/relay8")
r = relay8;
else if(String(topic)=="PowerPanel/X") //мне вот сюда нужно в место Х чтото чо обозначало все 8 реле (пинов)
r = X; //мне вот сюда нужно в место Х чтото чо обозначало все 8 реле (пинов)
else
r = relay1;
digitalWrite(r, hl);
Команда digitalWrite пишет в один порт, она не может одновременно писать в несколько портов. Поскольку реле - устройство медленное, то вам должно быть все равно, одновременно вы ими управляете или по очереди. Напишите свою функцию управления реле, например, такую:
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 = -1; void relayWrite(int relay_number, bool hi_lo) { // если указан номер в диапазоне 2..9 то управляем реле по-отдельности if ((relay_number >= 2) && (relay_number <= 9)) { digitalWrite(relay_number, hi_lo); } // если указан номер -1 то управляем всеми реле сразу else if (relay_number == relayAll) { for (int i=2; i<=9; i++) // номера портов 2..9 { digitalWrite(i, hi_lo); } } }Теперь можно написать так:
else if(String(topic)=="PowerPanel/relay8") relayWrite(relay8, h1); else if(String(topic)=="PowerPanel/X") relayWrite(relayAll, h1); // все 8 реле (пинов) else relayWrite(relay1, h1);здесь комментарий не пишу комментарии в коде, пока не имею возможности обкатать на компиляторе а тем более на arduino, но есть в коде сомнения и я их прокомментировал
там есть два блока 2 и 3. 2 это который я старался оставить ближе к оригиналų только использовав идею от triac, a 3 максимально подтянув под предложение от triac
а блок но.1 не совсем уверен о его местоположении в этом коде.
/* управление блоком реле с MQTT протоколом контролер Arduino Nano сетевой адаптер W5100 ** в перспективе нужно добавить запись EEPROM для запоминания включенных реле после пропажи напряжения */ #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 = -1; //**добавлено * tiac // начало блока -1 ///*** добавлено * tiac ***/// // void relayWrite(int relay_number, bool hi_lo) { // если указан номер в диапазоне 2..9 то управляем реле по-отдельности if ((relay_number >= 2) && (relay_number <= 9)) { digitalWrite(relay_number, hi_lo); } // если указан номер -1 то управляем всеми реле сразу else if (relay_number == relayAll) { for (int i=2; i<=9; i++) // номера портов 2..9 { digitalWrite(i, hi_lo); } } } //конец блока -1////*************/////////// // 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; // инициация h и r, в блоке Но2 r - не нужно Serial.begin(9600); 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; // начало блока -2 ////**вариант Но1**/// 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; digitalWrite(r, hl); Serial.println(); } //конец блока -2// // начало блока -3**---или всё же вариант Но2 с такой идеей ---добавлено * tiac // if(String(topic)=="PowerPanel/relay1") relayWrite(relay1, hl); else if(String(topic)=="PowerPanel/relay2") relayWrite(relay1, hl); else if(String(topic)=="PowerPanel/relay3") relayWrite(relay1, hl); else if(String(topic)=="PowerPanel/relay4") relayWrite(relay1, hl); else if(String(topic)=="PowerPanel/relay5") relayWrite(relay1, hl); else if(String(topic)=="PowerPanel/relay6") relayWrite(relay1, hl); else if(String(topic)=="PowerPanel/relay7") relayWrite(relay1, hl); else if(String(topic)=="PowerPanel/relay8") relayWrite(relay1, hl); else if(String(topic)=="PowerPanel/relayAll") relayWrite(relayAll, hl); else relayWrite(relay1, hl); digitalWrite(hl); // этот наверное тоже не нужен ? Serial.println(); } //конец блока -3//************////// EthernetClient ethClient; PubSubClient client(server, 1883, callback, ethClient); void reconnect() { // Loop пока мы не подключимся 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); // Каждый вывод подключается к реле в режиме OUTPUT, for(int i = 0; i < 8; i++){ //цикл, который будет повторяться 8 раз pinMode(relayAll[i],OUTPUT); //устанавливаем каждый PIN в режим OUTPUT } //можно и так если без цикла /* 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.println ("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(); }Могу еще такой вариант предложить:
uint8_t writeToPort(const uint8_t _port, const uint8_t _value) { volatile uint8_t *portRegister; portRegister = portOutputRegister(_port); if (NOT_A_PORT == portRegister) return false; ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { *portRegister = _value; } return true; }writeToPort(0, B10100101) - в порт A
writeToPort(3, B10100101) - в порт D (пины D7..D0)
Будет выставлять все пины разом.
но есть в коде сомнения и я их прокомментировал
если есть реальные вопросы - пишите конкретно. А ради ваших "сомнений", которые еще и в коде надо искать - копаться в нескольких сотнях строк вряд ли кому интересно. И что за глупость - "не могу обкатать на компиляторе" ? - с этого надо начинать, выкладывать непроверенный на компиляторе код - неуважение к форуму.
По сути вашего кода у меня есть вполне обоснованное сомнение, что такое количество String-ов поместится в оперативку Нано. Вы обращаетесь с памятью крайне неэкономно. С 178 по 195 строчку у вас 18 почти одинаковых строк, которые можно сократить до одной-двух.
если есть реальные вопросы - пишите конкретно. А ради ваших "сомнений", которые еще и в коде надо искать - копаться в нескольких сотнях строк вряд ли кому интересно.
И что за глупость - "не могу обкатать на компиляторе" ? - с этого надо начинать, выкладывать непроверенный на компиляторе код - неуважение к форуму.
По сути вашего кода у меня есть вполне обоснованное сомнение, что такое количество String-ов поместится в оперативку Нано. Вы обращаетесь с памятью крайне неэкономно. С 178 по 195 строчку у вас 18 почти одинаковых строк, которые можно сократить до одной-двух.
Без доп добавок код рабочий и памяти хватает и быстродействия, не знаю как и не вижу смысла чтобы его как- то усложнять для того что бы сэкономить память. Как локально с веб интерфейса сервера работает, с мобилы отдалённо тоже без нареканий.Я считаю, что это довольно интересный проект если кому нужно управлять нагрузками через интернет, по wifi есть на esp, вот есть теперь на проводах, только пока нет чтобы одной кнопкой можно было всё on/off.
Будет выставлять все пины разом.
Да про такой момент слышал, но есть боязнь закрыть пин подав 0 (которые используются для прошивки) на его и ардуинка станет недосягаемой. Надо даташит ещё поштудировать.
Будет выставлять все пины разом.
Да про такой момент слышал, но есть боязнь закрыть пин подав 0 (которые используются для прошивки) на его и ардуинка станет недосягаемой. Надо даташит ещё поштудировать.
Есть такая опасность. Я у себя ее решаю простой защитной маской (просто вырезал из этого кода, чтобы не усложнять): *portRegister = (*portRegister & port_protect[_port]) | (_value & ~port_protect[_port]); - в port_protect храню битовые маски, которые говорят - разрешено менять состояние конкретного пина или нет. Пока работает.