- Внимание! Высокое напряжение, применяемое в схеме, представляет реальную опасность для жизни и здоровья в случае несоблюдения техники безопасности при работе с электроприборами. Симмисторное управление не обеспечивает физического разрыва питания исполнительного устройства. Применять это следует исключительно осторожно и в связке с УЗО.
- Приступим!
- Ещё пара слов о симмисторах.
Всем привет! Цветочки долго ждать не будут и пришлось немного ускориться.
В этой части подключу телеграм бота для контроля и управления за системой, всё прошью и запущу в тестовом режиме.
Внимание! Высокое напряжение, применяемое в схеме, представляет реальную опасность для жизни и здоровья в случае несоблюдения техники безопасности при работе с электроприборами. Симмисторное управление не обеспечивает физического разрыва питания исполнительного устройства. Применять это следует исключительно осторожно и в связке с УЗО.
Чтобы добавить бота в проект необходимо сначала зарегистрировать его в телеграме. Для этого есть специальный бот - @BotFather. Нужно отправить ему специальную команду /newbot, далее придумать ему имя, а затем имя пользователя в котором обязательно должно содержаться слово "bot". После того, как всё будет сделано @BotFather пришлет специальный токен, который можно будет использовать для наших целей.
Для реализации взаимодействия с ботом можно воспользоваться официальной документацией телеграм и формировать запросы вручную. А можно использовать что-то готовое. Например библиотеку от того же Алекса Гайвера. Я выбрал библиотеку FastBot2, которая, по заверениям автора, быстрая, легкая и универсальная*
*по сравнению с предыдущей версией)
Приступим!
#include <FastBot2.h> //первым делом подключаем библиотеку
FastBot2 bot; //создаем объект класса
void updateh(fb::Update& u) {// создаем функцию - обработчик сообщений
Serial.println("NEW MESSAGE");// для отладки и теста
Serial.println(u.message().from().username());
Serial.println(u.message().text());
bot.sendMessage(fb::Message(u.message().text(), u.message().chat().id()));// отправим эхо сообщения обратно в чат
}
В блок void setup(){} добавим следующие строки
bot.attachUpdate(updateh); // подключить обработчик обновлений
bot.setToken(F(BOT_TOKEN)); // установить полученный токен
bot.setPollMode(fb::Poll::Long, 20000);// режим опроса обновлений.
bot.sendMessage(fb::Message("В сети!", CHAT_ID));// сразу напишем что-то в чат для пользователя с установленным CHAT_ID
BOT_TOKEN и CHAT_ID нужно указать дефайнами. В примере по ссылке выше показано как это делается. Свой CHAT_ID можно узнать, например, у @getmyid_bot. В том же телеграме.
В блоке void loop(){} добавим обработчик событий
bot.tick();
Прошиваем, проверяем. Пишем "Привет!".
С кодировкой кириллицы какая-то беда. Но, если присмотреться к документам библиотеки там так и написано- "кириллица обрабатывается вручную" и даже пара способов дана! Сейчас поправим!
String text = u.message().text().decodeUnicode(); //декодирование сообщения в строковую переменную
bot.sendMessage(fb::Message(text, u.message().chat().id()));
Теперь попробуем чем-то поуправлять. Например линией L1.
if(u.message().text() == "/L1_ON") { //сравниваем текст сообщения с командой
digitalWrite(L1,1);// и если всё так - включаем линию
String text = "L1 включена в: "+ NTP.toString(); // и отправляем обратную связь c датой и временем просто для теста
bot.sendMessage(fb::Message(text, u.message().chat().id()));}// вот тут
if(u.message().text() == "/L1_OFF") { // и так же выключаем
digitalWrite(L1,0);
String text = "L1 выключена в "+ NTP.toString();
bot.sendMessage(fb::Message(text, u.message().chat().id()));}
Прошиваем. Проверяем.
Всё хорошо. Теперь можно расписать сценарий.
void time_script(byte number){// объявляем функцию с выбором режима во входном параметре
if (number == 0){ //первый режим
intence(0);}// выключаем всё
if (number == 1){ //второй режим
if((NTP >= DaySeconds(7, 30, 0))&&(NTP <= DaySeconds(18, 30, 0))){ // если попадаем во временной интервал
intence(1);} // включаем всё
else intence(0);// не попадаем - выключаем
}}
Добавим новый режим интенсивности в функцию void intence(byte temp){}:
if (temp==1){ // номер режима - один
bool state_new[5] = {1,1,1,1,1}; // просто включаем всё.
memcpy(state, state_new,5);
}
Проинициализируем глобальную переменную для хранения текущего номера сценария.
byte state = 0; // то же самое имя, что и у локальной. Возможно так легче запутаться.
И добавим два новых условия в обработчик сообщений:
if(u.message().text() == "/Script_0") {// если придет такое сообщение
state = 0; // запустим нуливой сценарий
String text = "Всё выключено всегда "+ NTP.toString();
bot.sendMessage(fb::Message(text, u.message().chat().id()));} // и отчитаемся
if(u.message().text() == "/Script_1") { // то же для второго сценария
state = 1;
String text = "Всё включено с 7:30 до 18:30 "+ NTP.toString();
bot.sendMessage(fb::Message(text, u.message().chat().id()));}
И в блоке void loop(){} будем обновлять значения состояния сценария:
if (NTP.tick()) {// тикер вернёт true каждую секунду
time_script(state);// воспользуемся тикером часов, чтобы не сравнивать каждый цикл, а пореже.
}
Загружаем. Прошиваем.
Этим уже можно пользоваться, но нужно помнить, что в моем случае платы две. Но вторая должна только выполнять команды первой и ее прошивка крайне проста. Вот она вся:
#include <Arduino.h>
#define L1 13 // объявление задействованных пинов
#define L2 5
#define L3 4
#define AP1 12
#define AP2 14
void setup() {
pinMode(L1, OUTPUT); // выбор режима
pinMode(L2, OUTPUT);
pinMode(L3, OUTPUT);
pinMode(AP1, INPUT);
pinMode(AP2, INPUT);
digitalWrite(L1,0); // сначала всё отключаем
digitalWrite(L2,0);
digitalWrite(L3,0);
}
void loop() {
if((digitalRead(AP1)== 0)&&(digitalRead(AP1)== 1)){ // а потом включаем только нужные
digitalWrite(L1,0);
digitalWrite(L2,1);
digitalWrite(L3,0);
}
else if((digitalRead(AP1)== 1)&&(digitalRead(AP1)== 0)){
digitalWrite(L1,1);
digitalWrite(L2,0);
digitalWrite(L3,1);
}
else if((digitalRead(AP1)== 1)&&(digitalRead(AP1)== 1)){
digitalWrite(L1,1);
digitalWrite(L2,1);
digitalWrite(L3,1);
}
else{
digitalWrite(L1,0);
digitalWrite(L2,0);
digitalWrite(L3,0);
}
delay (100); // ну и не торопимся никуда особо
}
Прошиваем, устанавливаем всё на места и тестируем.
Всё работает! И при отправке /Script_0 отключается.
Сзади пожухшее - это береза в спячке. Скоро зазеленеет.
И включается и выключается всё как нужно! Осталось дело за малым. Напечатать ещё четыре кроншнейна, сделать какой-никакой корпус устройству, расписать ещё сценариев и, возможно, сделать их сохранение, чтобы не приходилось снова выбирать при случайной перезагрузке или отключении электричества.
Ещё пара слов о симмисторах.
Как видно из схемы физического разрыва цепи питания нагрузки нет. Симмистор - это, крубо говоря, просто два тиристора, по одному для каждого направления тока. Просто полупроводниковый прибор, где прохождение тока ограничивается полями, дырками, электронами и вот этим всем колдунством, под контролем которое держит качество проекта, монтажа, элементов, программы и много других факторов.
Для управления симмистором применена специальная микросхема - оптосиммистор, которая сама отслеживает момент перехода синусоиды через ноль, чтобы включить нагрузку при разрешающем сигнале именно в этот момент. Но обратной связи для использования в качестве диммера микросхема не имеет, так что данная схема работает примерно как реле, только помельче, не щелкает и не искрит. За это как-то не особенно комфортно расплачиваться безопасностью. Но я осознаю риски и забыть отключить или включить освещение на все выходные или дольше - мне кажется не особенно полезным для жизнедеятельности растений. Возможно следующую версию сделаю или на реле или низковольтной.
Всем спасибо за просмотр! Как всегда буду рад комментариям, а обсудить всё, что есть на канале можно в телеграм-чате. Там пока что очень тихо, но я надеюсь, что это может измениться!