Официальный сайт компании Arduino по адресу arduino.cc
Импульсные реле и управление ими с помощью Arduino и OpenHab
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Сразу прошу прощения, я новичок) Возможно подобная тема уже подымалась ранее, но все что я находил, мне так и не помогло. По-этому решил создать свою и описать задачу со своей, так сказать "колокольни".
Если коротко, то: Есть 10 импульсных реле, 10 твердотельных реле, Raspberry Pi3, "ардуинка" и "шилд" к ней. Все это нужно собрать в одну, работающую систему.
Если с подробностями, то: Изначально, при строительстве объекта, ничего умного и управляемого из вне, не предусматривалось. Но время шло, взгляды менялись, и в какой то момент заказчику захотелось иметь возможность управлять освещением на участке с помощью планшета или смартфона. А, как вы уже могли догадаться, "импульсники" были куплены и смонтированы, кнопки под них аналогично. В общем нужно с минимальными вложениями управлять "импульсниками" удаленно.
В теории представлялось все просто. Установив связь Arduino c OpenHab`ом, я хотел давать импульс, с помощью обычных ардуиновских релюшек, на импульсные реле(к которым уже подключена нагрузка), и с помощью датчика наличия напряжения отправлять статус в OpenHab. Ну и при всем при этом сохраняется возможность управления импусными реле с помощью обычных кнопочных выключателей(что как бы тоже хорошо, если вдруг ардуинка зависнет и откажется выключать свет в 3 ночи).
Просмотрев ролики про OpenHab и Arduino, я принялся собирать все это в кучу. По ходу столкнулся с некоторыми моментами в плане железа. А именно обычные реле не подходили для данной задачи, потому как через них, при включении/выключении импульсника, проходили наводки, которые приводили к зависанию ардуинку. Пришлось применить твердотельные реле. Проблема с наводками ушла, а на смену к ней пришла новая. Датчики тока. Изначально, изучив тему очень поверхностно, я предположил, что ими я буду снимать статус с импульсников, и за одно выведу отдельные мониторы в OpenHub`е для мониторинга потребления отдельных групп освещения(совершенно не нужная штука но, если бонусом, то почему бы и нет) И тут проблема была в том, что код и библиотеки для работы с этими датчиками ну прям очень увесисты для моей ардуинки. С одним-двумя датчиками работать можно, но когда их десять, все жутко лагало. Соответственно было принято решение заменить их на датчики наличия напряжения, которые должны выдавать логический 0 или 1(нагрузка есть или нагрузки нет, грубо говоря). Все вроде уже подходило к развязки НО. Мои умения кодить меня подвели)
А теперь внимание! Вопрос к знатокам.
Есть переменная "а" и переменная "b"(по умолчанию b = 0). Нужно прописать условие, если переменная "а" = 1, то переменной "b" нужно присвоить значение 1, а за тем(через 200мс) значение 0, один раз(для того, чтоб подать импульс для импульсного реле). Ну и точно также if(a == 0), то "b" нужно присвоить значение 1, а за тем(через 200мс) значение 0 один раз. КАК? Ну и к стати, важный момент, delay использовать нельзя.
Вот как выглядел код до момента в нем что-то исправить:
#include <PubSubClient.h> #include <SPI.h> #include <Ethernet.h> // -------------------------------------- Sensor - Пины Arduino ---------------------------------------------- const int sensor1 = 41; //Пин 41 датчик наличия напряжения для импульсного реле 1 const int sensor2 = 42; //Пин 42 датчик наличия напряжения для импульсного реле 2 const int sensor3 = 43; //Пин 43 датчик наличия напряжения для импульсного реле 3 const int sensor4 = 44; //Пин 44 датчик наличия напряжения для импульсного реле 4 const int sensor5 = 45; //Пин 45 датчик наличия напряжения для импульсного реле 5 const int sensor6 = 46; //Пин 46 датчик наличия напряжения для импульсного реле 6 const int sensor7 = 47; //Пин 47 датчик наличия напряжения для импульсного реле 7 const int sensor8 = 48; //Пин 48 датчик наличия напряжения для импульсного реле 8 const int sensor9 = 49; //Пин 49 датчик наличия напряжения для импульсного реле 9 const int sensor10 = 50; //Пин 50 датчик наличия напряжения для импульсного реле 10 // -------------------------------------- BEGIN - Пины Arduino ---------------------------------------------- #define Relay1_pin 31 //Пин 31 для реле 1 #define Relay2_pin 32 //Пин 32 для реле 2 #define Relay3_pin 33 //Пин 33 для реле 3 #define Relay4_pin 34 //Пин 34 для реле 4 #define Relay5_pin 35 //Пин 35 для реле 5 #define Relay6_pin 36 //Пин 36 для реле 6 #define Relay7_pin 37 //Пин 37 для реле 7 #define Relay8_pin 38 //Пин 38 для реле 8 #define Relay9_pin 39 //Пин 39 для реле 9 #define Relay10_pin 40 //Пин 40 для реле 10 // -------------------------------------- END - Пины Arduino ------------------------------------------------ // -------------------------------------- BEGIN - Глобальные переменные ------------------------------------- boolean Relay1 = HIGH; //Переменная для хранения состояния Реле 1 boolean Relay2 = HIGH; //Переменная для хранения состояния Реле 2 boolean Relay3 = HIGH; //Переменная для хранения состояния Реле 3 boolean Relay4 = HIGH; //Переменная для хранения состояния Реле 4 boolean Relay5 = HIGH; //Переменная для хранения состояния Реле 5 boolean Relay6 = HIGH; //Переменная для хранения состояния Реле 6 boolean Relay7 = HIGH; //Переменная для хранения состояния Реле 7 boolean Relay8 = HIGH; //Переменная для хранения состояния Реле 8 boolean Relay9 = HIGH; //Переменная для хранения состояния Реле 9 boolean Relay10 = HIGH; //Переменная для хранения состояния Реле 10 boolean val1; //Переменная для хранения состояния датчика наличия напряжения 1 boolean val2; //Переменная для хранения состояния датчика наличия напряжения 2 boolean val3; //Переменная для хранения состояния датчика наличия напряжения 3 boolean val4; //Переменная для хранения состояния датчика наличия напряжения 4 boolean val5; //Переменная для хранения состояния датчика наличия напряжения 5 boolean val6; //Переменная для хранения состояния датчика наличия напряжения 6 boolean val7; //Переменная для хранения состояния датчика наличия напряжения 7 boolean val8; //Переменная для хранения состояния датчика наличия напряжения 8 boolean val9; //Переменная для хранения состояния датчика наличия напряжения 9 boolean val10; //Переменная для хранения состояния датчика наличия напряжения 10 // -------------------------------------- END - Глобальные переменные --------------------------------------- // -------------------------------------- BEGIN - Установка параметров сети --------------------------------- void callback(char* topic, byte* payload, unsigned int length); // Установить MAC адресс для этой Arduino (должен быть уникальным в вашей сети) byte mac[] = { 0x90, 0xB2, 0xFA, 0x00, 0x4E, 0x49 }; // Утановить IP адресс для этой Arduino (должен быть уникальным в вашей сети) IPAddress ip(192, 168, 1, 115); // Уставновить IP адресс MQTT брокера byte server[] = { 192, 168, 1, 111 }; // Уставновить Логин и Пароль для подключения к MQTT брокеру const char* mqtt_username = "alexei"; const char* mqtt_password = "b348misty"; EthernetClient ethClient; PubSubClient client(server, 1883, callback, ethClient); // --------------------------------------- END - Установка параметров сети ---------------------------------- // --------------------------------------- BEGIN - Подключение и подписка на MQTT broker ---------------------------------- boolean reconnect() { //Serial.println("reconnect..."); if (client.connect("Arduino_test", mqtt_username, mqtt_password)) { client.subscribe("/room31/relay1"); Serial.println("Connected to: /room31/relay1"); client.subscribe("/room31/relay2"); Serial.println("Connected to: /room31/relay2"); client.subscribe("/room31/relay3"); Serial.println("Connected to: /room31/relay3"); client.subscribe("/room31/relay4"); Serial.println("Connected to: /room31/relay4"); client.subscribe("/room31/relay5"); Serial.println("Connected to: /room31/relay5"); client.subscribe("/room31/relay6"); Serial.println("Connected to: /room31/relay6"); client.subscribe("/room31/relay7"); Serial.println("Connected to: /room31/relay7"); client.subscribe("/room31/relay8"); Serial.println("Connected to: /room31/relay8"); client.subscribe("/room31/relay9"); Serial.println("Connected to: /room31/relay9"); client.subscribe("/room31/relay10"); Serial.println("Connected to: /room31/relay10"); client.subscribe("/room31/sensor1"); Serial.println("Connected to: /room31/sensor1"); Serial.println("MQTT connected"); } return client.connected(); } // --------------------------------------- END - Подключение и подписка на MQTT broker ---------------------------------- // --------------------------------------- BEGIN - void setup() ------------------------------------------- void setup() { digitalWrite(Relay1_pin, LOW); // Решение проблемы с LOW статусом пинов при загрузке ардуино digitalWrite(Relay2_pin, LOW); // устанавливает значение по умолчанию digitalWrite(Relay3_pin, LOW); // устанавливает значение по умолчанию digitalWrite(Relay4_pin, LOW); // устанавливает значение по умолчанию digitalWrite(Relay5_pin, LOW); // устанавливает значение по умолчанию digitalWrite(Relay6_pin, LOW); // устанавливает значение по умолчанию digitalWrite(Relay7_pin, LOW); // устанавливает значение по умолчанию digitalWrite(Relay8_pin, LOW); // устанавливает значение по умолчанию digitalWrite(Relay9_pin, LOW); // устанавливает значение по умолчанию digitalWrite(Relay10_pin, LOW); // устанавливает значение по умолчанию pinMode(Relay1_pin, OUTPUT); // устанавливает режим работы - выход pinMode(Relay2_pin, OUTPUT); // устанавливает режим работы - выход pinMode(Relay3_pin, OUTPUT); // устанавливает режим работы - выход pinMode(Relay4_pin, OUTPUT); // устанавливает режим работы - выход pinMode(Relay5_pin, OUTPUT); // устанавливает режим работы - выход pinMode(Relay6_pin, OUTPUT); // устанавливает режим работы - выход pinMode(Relay7_pin, OUTPUT); // устанавливает режим работы - выход pinMode(Relay8_pin, OUTPUT); // устанавливает режим работы - выход pinMode(Relay9_pin, OUTPUT); // устанавливает режим работы - выход pinMode(Relay10_pin, OUTPUT); // устанавливает режим работы - выход pinMode(sensor1, INPUT); // устанавливает режим работы - вход pinMode(sensor2, INPUT); // устанавливает режим работы - вход pinMode(sensor3, INPUT); // устанавливает режим работы - вход pinMode(sensor4, INPUT); // устанавливает режим работы - вход pinMode(sensor5, INPUT); // устанавливает режим работы - вход pinMode(sensor6, INPUT); // устанавливает режим работы - вход pinMode(sensor7, INPUT); // устанавливает режим работы - вход pinMode(sensor8, INPUT); // устанавливает режим работы - вход pinMode(sensor9, INPUT); // устанавливает режим работы - вход pinMode(sensor10, INPUT); // устанавливает режим работы - вход Serial.begin(9600); // Open serial communications // Start with a hard-coded address: Ethernet.begin(mac, ip); Serial.print("My ip address: "); Serial.println(Ethernet.localIP()); reconnect(); // Подключение к брокеру, подписка на прописанные выше темы } // --------------------------------------- END - void setup() --------------------------------------------- // --------------------------------------- BEGIN - void loop() -------------------------------------------- void loop() { client.loop(); } // --------------------------------------- END - void loop() ---------------------------------------------- // --------------------------------------- BEGIN - void callback ------------------------------------------ // Чтение данных из MQTT брокера void callback(char* topic, byte* payload, unsigned int length) { // проверка новых сообщений в подписках у брокера payload[length] = '\0'; Serial.print("Topic: "); Serial.print(String(topic)); Serial.println(" - "); //-----------------------------relay1------------------------------- if (String(topic) == "/room31/relay1") { String value = String((char*)payload); Relay1 = value.substring(0, value.indexOf(';')).toInt(); Serial.print("Znachenie prisvoenoe peremennoy Relay1: "); Serial.println(Relay1); digitalWrite(Relay1_pin, Relay1); } //-----------------------------relay2------------------------------- if (String(topic) == "/room31/relay2") { String value = String((char*)payload); Relay2 = value.substring(0, value.indexOf(';')).toInt(); Serial.print("Znachenie prisvoenoe peremennoy Relay2: "); Serial.println(Relay2); digitalWrite(Relay2_pin, Relay2); } //-----------------------------relay3------------------------------- if (String(topic) == "/room31/relay3") { String value = String((char*)payload); Relay3 = value.substring(0, value.indexOf(';')).toInt(); Serial.print("Znachenie prisvoenoe peremennoy Relay3: "); Serial.println(Relay3); digitalWrite(Relay3_pin, Relay3); } //------------------------------relay4------------------------------ if (String(topic) == "/room31/relay4") { String value = String((char*)payload); Relay4 = value.substring(0, value.indexOf(';')).toInt(); Serial.print("Znachenie prisvoenoe peremennoy Relay4: "); Serial.println(Relay4); digitalWrite(Relay4_pin, Relay4); } //-------------------------------relay5----------------------------- if (String(topic) == "/room31/relay5") { String value = String((char*)payload); Relay5 = value.substring(0, value.indexOf(';')).toInt(); Serial.print("Znachenie prisvoenoe peremennoy Relay5: "); Serial.println(Relay5); digitalWrite(Relay5_pin, Relay5); } //-------------------------------relay6----------------------------- if (String(topic) == "/room31/relay6") { String value = String((char*)payload); Relay6 = value.substring(0, value.indexOf(';')).toInt(); Serial.print("Znachenie prisvoenoe peremennoy Relay6: "); Serial.println(Relay6); digitalWrite(Relay6_pin, Relay6); } //-------------------------------relay7----------------------------- if (String(topic) == "/room31/relay7") { String value = String((char*)payload); Relay7 = value.substring(0, value.indexOf(';')).toInt(); Serial.print("Znachenie prisvoenoe peremennoy Relay7: "); Serial.println(Relay7); digitalWrite(Relay7_pin, Relay7); } //-------------------------------relay8----------------------------- if (String(topic) == "/room31/relay8") { String value = String((char*)payload); Relay8 = value.substring(0, value.indexOf(';')).toInt(); Serial.print("Znachenie prisvoenoe peremennoy Relay8: "); Serial.println(Relay8); digitalWrite(Relay8_pin, Relay8); } //-------------------------------relay9----------------------------- if (String(topic) == "/room31/relay9") { String value = String((char*)payload); Relay9 = value.substring(0, value.indexOf(';')).toInt(); Serial.print("Znachenie prisvoenoe peremennoy Relay9: "); Serial.println(Relay9); digitalWrite(Relay9_pin, Relay9); } //--------------------------------relay10---------------------------- if (String(topic) == "/room31/relay10") { String value = String((char*)payload); Relay10 = value.substring(0, value.indexOf(';')).toInt(); Serial.print("Znachenie prisvoenoe peremennoy Relay10: "); Serial.println(Relay10); digitalWrite(Relay10_pin, Relay10); } } // ---------------------------------------- END - void callback -------------------------------------------
Если вставить в место импульсников обычные реле этот код будет работать идеально, но вот с импусниками дело обстоит иначе. В самом OpenHub я тоже не нашел никаких вариантов с кнопкой.
У Вас есть Raspberry Pi3 вот зачем Вам ардуинка? Для понтов? Пишите на питоне и не парьте нам моск.
Есть переменная "а" и переменная "b"(по умолчанию b = 0). Нужно прописать условие, если переменная "а" = 1, то переменной "b" нужно присвоить значение 1, а за тем(через 200мс) значение 0, один раз(для того, чтоб подать импульс для импульсного реле). Ну и точно также if(a == 0), то "b" нужно присвоить значение 1, а за тем(через 200мс) значение 0 один раз. КАК? Ну и к стати, важный момент, delay использовать нельзя.
Очень красивое, чисто аппаратное, решение от dimax - пользуйтесь!
mykaida, Нет. Почему для понтов? Я как и многие, в данное время, начал свое знакомство с микроконтроллерами именно с Arduino и как то привык) Возможно в будущем я изменю свое мнение. Почему? Ну еще так дешевле) Управление импульсниками нужно реализовать не в одном месте, в данный момент в 3-х, и скорее всего будут еще расширения и дополнение(датчики, полив, ворота, сигналка и прочее). Я представилю себе такую вот схему: один мозг в виде Raspberry и много дешевых ардуинок с навешенными на них датчиками и релюхами ) И потом, этот сайт вроде arduino.ru называется, я думал тут про Arduino говорят. И простите пожалуйста за ваш моск, я честно, не хотел.
ЕвгенийП, спасибо) Буду пробовать.
Добавляем переменную "_а".
if(_a!=a) {b=1;
if(millis()-lastSwitch>=200){
_a=a;b=0;
}
}
else {lastSwitch=millis();}
тоже подумалось про одновибратор на таймере, а тут уже всё давно придумано до нас )))
mykaida, Нет. Почему для понтов? Я как и многие, в данное время, начал свое знакомство с микроконтроллерами именно с Arduino и как то привык) Возможно в будущем я изменю свое мнение. Почему? Ну еще так дешевле) Управление импульсниками нужно реализовать не в одном месте, в данный момент в 3-х, и скорее всего будут еще расширения и дополнение(датчики, полив, ворота, сигналка и прочее). Я представилю себе такую вот схему: один мозг в виде Raspberry и много дешевых ардуинок с навешенными на них датчиками и релюхами ) И потом, этот сайт вроде arduino.ru называется, я думал тут про Arduino говорят. И простите пожалуйста за ваш моск, я честно, не хотел.
Ни в коем случае не хотел Вас обидеть, но малинка настолько мощная штука, что ардуинка ей нужна только в варианте расширения портов (по моему мнению - не нужна). Особенно в задачах, озвученных Вами.
Есть еще один вариант (гипотетический) - потеря связи с "центром", когда отдельные части сети принимают самостоятельные решения. Но тогда надо придумывать свои протоколы обмена.
Оно Вам надо? RS485 интерфейс, стандартные модули расширения портов.... и все!
Обманул - протокол в любом случае нужен, но нужен ли контроллер?
Особенно в задачах, озвученных Вами.
Скорее всего Вы правы. И да, я озвучил не все задачи. На первом ардуино должно висеть 10 реле(для управления импульсниками), 10 датчиков нал.напр.(для считывания состояния) и еще пара реле обычных и пара датчиков. На втором ардуино(уже в другом здании) еще 6 реле, 6 датчиков нал.напр. и пара датчиков (температуры и влажности). На третьем 4 реле и пара датчиков. Просто на фига ставить для примитивных задач целую Raspberry, если для этого вполне хватит недорогой китайской ардуинки?
Есть еще один вариант (гипотетический) - потеря связи с "центром", когда отдельные части сети принимают самостоятельные решения. Но тогда надо придумывать свои протоколы обмена.
А это, чувствую будет моей новой проблемой)
Спасибо Вам за комментарии.
А вот теперь подумаем - если у обычного реле Вы всегда знаете состояние контактов в начальном состоянии, то импульсные - это "терра инкогнита" и Вам нужно использовать обратные сигналы, что бы понять ее состояние. Дык нахера! Обоснуйте использование 10-ти обычных реле, состояние которых в начальный момент Вы будете знать. И используйте малинку с расширением портов в/в.
И забудьте про "самостоятельную работу части систетмы. Центр должен быть один.
А если надо сохранить данные - так у нас память есть в процкссоре
А вот теперь подумаем - если у обычного реле Вы всегда знаете состояние контактов в начальном состоянии, то импульсные - это "терра инкогнита" и Вам нужно использовать обратные сигналы, что бы понять ее состояние. Дык нахера! Обоснуйте использование 10-ти обычных реле, состояние которых в начальный момент Вы будете знать. И используйте малинку с расширением портов в/в.
Есть OpenHab и соответственно MQTT Broker, установленные на "малинку"- это мозг. Есть 10 импульсных реле в одном месте, 6 в другом, и 4 в третьем. Все установлено и смонтировано. Задача: заставить все это работать без демонтажа импульсников и переделки кнопок(потому как их ещё больше). Для импульсных реле как для включения, так и для выключения необходимо подать импульс 220В, обычная кнопка с этим справляется не плохо, а вот как бы так код прописать, чтоб с OpenHab все это паралельно работало? А состояние контактов будет нам озвучивать датчик наличия напряжения. Вы поймите, сей час речь не идет о том, что идеально подходит для работы таких систем. Есть константы в виде приобретенного железа, и уже частично установленного и стоит задача заставить все это работать. Как стабильно и с какими проблемами мы столкнемся потом время покажет.)
Обоснуйте использование 10-ти обычных реле, состояние которых в начальный момент Вы будете знать. И используйте малинку с расширением портов в/в.
Ведь все это дело еще будет и с кнопок управляться, с обычных(в место выключателей на стене), которые в любой момент могут включить или выключить. Для этого необходимо знать состояние реле.
На скольки квадратах все это безумие творится?
Где-то 30 соток
Ведь все это дело еще будет и с кнопок управляться, с обычных(в место выключателей на стене), которые в любой момент могут включить или выключить. Для этого необходимо знать состояние реле.
Дык я про это и говорю - или Вы изначально знаете состояние реле и выставляете его при загрузке программы или считываете, а потом выставляете...
Можно сказать "мне необходимо ловить бабочек и приобретен половник. Он не идеален, но есть. Как им орудовать, чтобы заменить сачок? "
Оборудование(инструмент) приобретают под задачу. Задача не определяется наличиствующим инструментом. Не надо наворачивать доп контуры в виде датчиков напряжения - они только снизят надёжность.
Дык я про это и говорю - или Вы изначально знаете состояние реле и выставляете его при загрузке программы или считываете, а потом выставляете...
Я в начале сообщил, что я новичок) Извините, но я, как минимум, половину не понял, из того что Вы писали) И следующие пару дней буду пытаться в этом разобраться) И в том, что тут писали до этого тоже) Спасибо Всем, кто откликнулся, буду пробовать все варианты, результат напишу.
Спасибо, sadman41.) Это слова мудрого человека.
И еще раз -сначала схема. Не верьте тем, кто говорит, что "все можно добить софтиной". Сначала схема!
Даже соврал - сначала алгоритм, по нему схема потом программа.
Хочу уточнить - датчики напряжения сами по себе злом не являются. Они лишь представляют собой сенсор, который может отказать и запутать ситуацию. Реле со второй (контрольной) группой контактов более надёжно сигнализирует о состоянии, так как расположено ближе к устройству переключения. Датчик напряжения - это доп. контрольный контур, подтверждающий исправность основного. Но вес его метрики не должен превышать вес ближайшего сенсора - второй пары контактов.
Всем спасибо! Вопрос решен таким вот способом:
Неделю назад эта тема помогла освоиться с управлением импульсными реле. Но тут был сложный способ определения состояния света. Возможно не у всех реле есть светодиод состояния. У меня белорусское релле BIS-412i. В нем такой светодиодик есть. На нем 2 вольта при включении релюхи (1.95 показывает мой мультиметр). Подпаялся и вывел контакты на пин esp-шки. Отлично определяет статус, хоть с физической кнопки хоть с Home Assistant (Openhab туда же).
К стати система работает! Единственное что пришлось навертеть - это перезагрузчики для каждой ардуино(которые с реле и датчиками), они зависали через неопределённый промежуток времени(от 15мин. до 1,5ч.)(Не знаю почему). Перезагрузчики выполнены на Arduino Nano(Примитивный код, который посылает сигнал на пин RESET каждые 15мин). Перезагрузка быстрая, около 8сек, каждые 15мин., по-этому особо не ощущается. Забегая вперёд писал тоже самое на основных Arduink`ах, но устройство зависало и не перезагружало само себя, потому внедрено такое решение.
А использовать внутреннюю собаку не судьба.
А использовать внутреннюю собаку не судьба.
Религия. Вроде, пастафарианцам нельзя.
Единственное что пришлось навертеть - это перезагрузчики для каждой ардуино(которые с реле и датчиками), они зависали через неопределённый промежуток времени(от 15мин. до 1,5ч.)(Не знаю почему).