Помогите с выбором реле времени

Тема в разделе "Посоветуйте детальки", создана пользователем EandV, 20 окт 2018.

  1. EandV

    EandV Нерд

    Всем привет!

    Кто разбирается в реле времени с Али, подскажите, пожалуйста, конкретную модель для следующего кейса:

    Хочу сделать аварийное отключения для автополива растений. Столкнулся со случаем, что Ардуинка зависла и не отключила помпу вовремя, вода качалась, пока не кончилась в резервуаре.
    Хочу поставить перед помпой дополнительное реле, которое разорвет цепь, если время работы превысит минуту.
    Реле должно питаться от 5В. Еще очень важно, чтобы реле до активации помпы находилось в выключенном состоянии и не потребляло энергию.

    Нашел вот такое на Али:
    https://ru.aliexpress.com/item/1/32..._expid=347f5f39-f016-46dd-994c-53f7e7953877-5

    Не знаю подойдет ли для этой цели.
     
  2. Почитайте про watchdog. В вашем случае должно помочь. И датчик протечек явно пригодился бы.
     
    Tomasina, Daniil и parovoZZ нравится это.
  3. parovoZZ

    parovoZZ Гуру

    Ну если горе программист не может совладать с МК, то и обозначенное реле также не поможет(
     
  4. EandV

    EandV Нерд

    Я согласен, что возможно проблема в коде (хотя до этого 3 месяца всё нормально работало без сбоев), вопрос был в выборе реле (или может какое-нибудь другое решение есть) для резервной системы, которую я в любом случае буду теперь делать.

    Прямо приговор...
     
    Последнее редактирование модератором: 20 окт 2018
  5. Daniil

    Daniil Гик

    Резервная система отключения?
    Как сказали выше лучше начать с вотчдога - дешевле, быстрее.
    Если вы сделали ошибку в коде, то ее быстрее исправить самому, чем ждать готовое решение от кого-то.
    Если эта ошибка из-за китайской ардуинки, то новый модуль из китая только увеличит количество точек отказа.
    По тому модулю, что вы ссылку дали.
    Да, это может вам подойти. Только там максимум 24 сек.
     
  6. EandV

    EandV Нерд

    Благодарю!
    В описании написано, что продолжительность можно увеличить, заменив конденсатор на более емкий.

    По поводу кода
    Код (C++):

    #include <Wire.h>                           // Подключаем библиотеку Wire                          
    #include <TimeLib.h>                        // Подключаем библиотеку TimeLib
    #include <DS1307RTC.h>                      // Подключаем библиотеку DS1307RTC
    #include <Adafruit_GFX_rus.h>               // Подключаем библиотеку Экран Нокиа
    #include <Adafruit_PCD8544_rus.h>           // Подключаем библиотеку Экран Нокиа
    #include <avr/wdt.h>                        // Подключаем библиотеку сторожевого таймера
    #include <avr/sleep.h>                      // Подключаем библиотеку энергосбережения
    Adafruit_PCD8544 display = Adafruit_PCD8544(3, 4, 5, 6, 7); // Обозначаем пины для экрана
    // Обозначаем переменные

    boolean flag;
    int startminute ;
    int nowminute;

    int periodwork;
    int hourwork;
    int contwork;
    int dayscount;
    int startday;
    int nowday;
    int delaytime;
    int polivflag;
    int nowhour;


    boolean  pomp2activate;
    int periodwork2;
    int hourwork2;
    int contwork2;
    int dayscount2;
    int startday2;
    int nowday2;
    int delaytime2;
    int polivflag2;
    int nowhour2;

    boolean  pomp3activate;
    int periodwork3;
    int hourwork3;
    int contwork3;
    int dayscount3;
    int startday3;
    int nowday3;
    int delaytime3;
    int polivflag3;
    int nowhour3;

    void setup() {
     
    // Настройки полива

    periodwork = 4; // Раз в сколько дней производится полив
    hourwork = 19;   // час когда производится полив
    contwork = 30;  // время полива в секундах

    pomp2activate = 1;
    periodwork2 = 5; // Раз в сколько дней производится полив
    hourwork2 = 20;   // час когда производится полив
    contwork2 = 25;  // время полива в секундах

    pomp3activate = 1;
    periodwork3 = 5; // Раз в сколько дней производится полив
    hourwork3 = 21;   // час когда производится полив
    contwork3 = 35;  // время полива в секундах

    pinMode(A2,INPUT_PULLUP);

    // Настраиваем дисплей
    //display.begin();
    //display.clearDisplay();
    //display.display();
    //display.setContrast(60); // установка контраста
    //delay(1000);
    //display.setTextSize(1);  // установка размера шрифта
    //display.setTextColor(BLACK); // установка цвета текста
    //display.setCursor(0,0); // установка позиции курсора

    dayscount = 0;
    nowday =0;
    delaytime = contwork*1000;
    pinMode(9,OUTPUT);
    polivflag=0;


    tmElements_t tm;
    if (RTC.read(tm)) {
     
    startday = (tm.Day);
    if (pomp2activate == 1){
    startday2 = (tm.Day);
    }
    if (pomp3activate == 1){
    startday3 = (tm.Day);
    }

    } // if (RTC.read(tm))

    if (pomp2activate == 1){
    dayscount2 = 0;
    nowday2 =0;
    delaytime2 = contwork2*1000;
    pinMode(10,OUTPUT);
    polivflag2=0;
    }

    if (pomp3activate == 1){
    dayscount3 = 0;
    nowday3 =0;
    delaytime3 = contwork3*1000;
    pinMode(11,OUTPUT);
    polivflag3=0;
    }

    } // void setup()

    void loop(){
    //Включаем энергосбережение
    wdt_enable(WDTO_8S); //Задаем интервал сторожевого таймера (8с)
    WDTCSR |= (1 << WDIE); //Устанавливаем бит WDIE регистра WDTCSR для разрешения прерываний от сторожевого таймера
    set_sleep_mode(SLEEP_MODE_PWR_DOWN); //Устанавливаем интересующий нас режим
    sleep_mode(); // Переводим МК в спящий режим

     
    delay(50);
    tmElements_t tm;
    if (RTC.read(tm)) {
    nowminute  = (tm.Minute);
    boolean button1 = !digitalRead(A2); // инвертируем сигнал
    //Serial.println(button1);

    // Вывод на экран

    if (button1==1) {
    flag = 1;
    startminute = nowminute;

    display.begin();
    display.clearDisplay();
    display.display();
    display.setContrast(60); // установка контраста
    delay(1000);
    display.setTextSize(1);  // установка размера шрифта
    display.setTextColor(BLACK); // установка цвета текста
    display.setCursor(0,0); // установка позиции курсора

    display.clearDisplay();
    display.display();

    display.print("   ПР ЧР ВР ДО");
    display.print("П1 ");
    if (periodwork < 10)  {
       display.print(" ");
       display.print (periodwork);
    } else {
    display.print (periodwork);
    }
    display.print(" ");
    if (hourwork < 10)  {
    display.print(" ");
    display.print (hourwork);
    } else {
    display.print (hourwork);
    }
    display.print(" ");
    if (contwork < 10)  {
    display.print(" ");
    display.print (contwork);
    } else {
    display.print (contwork);
    }
    if (contwork < 100)  {
       display.print(" ");
    }
    if (periodwork - dayscount < 10)  {
    display.print(" ");
    display.print (periodwork - dayscount);
    } else {
    display.print (periodwork - dayscount);
    }
    } // if (button1==1)



    nowday  = (tm.Day);

    if (nowday != 0 && nowday != startday ) {
    dayscount=dayscount+1;
    polivflag=0;
    startday = nowday;
    }
    if(dayscount == periodwork){
    nowhour = (tm.Hour);

    if (nowhour == hourwork && polivflag==0) {
      digitalWrite(9,HIGH);
      delay (2000);
      digitalWrite(9,LOW);
      delay (5000);
      digitalWrite(9,HIGH);
      delay(delaytime);
      digitalWrite(9,LOW);
      polivflag=1;
      dayscount=0;
    } // if (nowhour == hourwork && polivflag==0)

    } // if(dayscount == periodwork)

    // Такой же блок, для 2 помпы

    if (pomp2activate == 1){



      if (button1==1) {
    display.print("П2 ");
    if (periodwork2 < 10)  {
       display.print(" ");
       display.print (periodwork2);
    } else {
    display.print (periodwork2);
    }
    display.print(" ");
    if (hourwork2 < 10)  {
    display.print(" ");
    display.print (hourwork2);
    } else {
    display.print (hourwork2);
    }
    display.print(" ");
    if (contwork2 < 10)  {
    display.print(" ");
    display.print (contwork2);
    } else {
    display.print (contwork2);
    }
    if (contwork2 < 100)  {
       display.print(" ");
    }
    if (periodwork2 - dayscount2 < 10)  {
    display.print(" ");
    display.print (periodwork2 - dayscount2);
    } else {
    display.print (periodwork2 - dayscount2);
    }
    }//if (button1==1) {

    nowday2  = (tm.Day);

    if (nowday2 != 0 && nowday2 != startday2 ) {
    dayscount2=dayscount2+1;
    polivflag2=0;
    startday2 = nowday2;
    }
    if(dayscount2 == periodwork2){
    nowhour2 = (tm.Hour);

    if (nowhour2 == hourwork2 && polivflag2==0) {
      digitalWrite(10,HIGH);
      delay (2000);
      digitalWrite(10,LOW);
      delay (5000);
      digitalWrite(10,HIGH);
      delay(delaytime2);
      digitalWrite(10,LOW);
      polivflag2=1;
      dayscount2=0;
    } // if (nowhour2 == hourwork2 && polivflag2==0)

    } // if(dayscount2 == periodwork2)

     

     
    } // if (pomp2activate == 1)

    // Такой же блок, для 3 помпы

    if (pomp3activate == 1){
      if (button1==1) {
    display.print("П3 ");
    if (periodwork3 < 10)  {
       display.print(" ");
       display.print (periodwork3);
    } else {
    display.print (periodwork3);
    }
    display.print(" ");
    if (hourwork3 < 10)  {
    display.print(" ");
    display.print (hourwork3);
    } else {
    display.print (hourwork3);
    }
    display.print(" ");
    if (contwork2 < 10)  {
    display.print(" ");
    display.print (contwork3);
    } else {
    display.print (contwork3);
    }
    if (contwork3 < 100)  {
       display.print(" ");
    }
    if (periodwork3 - dayscount3 < 10)  {
    display.print(" ");
    display.print (periodwork3 - dayscount3);
    } else {
    display.print (periodwork3 - dayscount3);
    }
    } //if (button1==1) {
    nowday3  = (tm.Day);

    if (nowday3 != 0 && nowday3 != startday3 ) {
    dayscount3=dayscount3+1;
    polivflag3=0;
    startday3 = nowday3;
    }
    if(dayscount3 == periodwork3){
    nowhour3 = (tm.Hour);

    if (nowhour3 == hourwork3 && polivflag3==0) {
      digitalWrite(11,HIGH);
      delay (2000);
      digitalWrite(11,LOW);
      delay (5000);
      digitalWrite(11,HIGH);
      delay(delaytime3);
      digitalWrite(11,LOW);
      polivflag3=1;
      dayscount3=0;
    } // if (nowhour3 == hourwork3 && polivflag3==0)

    } // if(dayscount3 == periodwork3)
     
    } // if (pomp3activate == 1){



    //Вывод текущих даты и времени
    //display.println(" ");
    if (button1==1) {
    display.print(tm.Hour);
    display.print(':');
    if (tm.Minute < 10)  {
    display.print("0");
    display.println (tm.Minute);
    } else {
    display.println (tm.Minute);
    }
    display.print(tm.Day);
    display.print('/');
    display.print(tm.Month);
    display.print('/');
    display.print(tmYearToCalendar(tm.Year));
    display.print(" ");
    display.display();
    }//if (button1==1) {

    if (startminute != nowminute) {
       flag = 0;
    }

    if (flag == 0) {
    digitalWrite(3, LOW);
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
    }

    } // if (RTC.read(tm))

    } // void loop()

    ISR (WDT_vect) {
      wdt_disable();
    }
    Сбой произошел в куске кода:

    digitalWrite(11,HIGH);
    delay (2000);
    digitalWrite(11,LOW);
    delay (5000);
    digitalWrite(11,HIGH);
    delay(delaytime3);
    digitalWrite(11,LOW);
    не сработала вот эта строчка : digitalWrite(11,LOW);

    Вроде как это происходит внутри пробуждения и пока код не отработает, в сон не должно уходить. Или я не прав?
     
  7. Daniil

    Daniil Гик

    Взглянув на ваш код, сразу хочется засунуть однотипные блоки управления помпами в одну отдельную процедуру. Они же ничем не отличаются, только номером пина. Таким образом можно пройтись по всей программе и выкинуть из лупа громоздкие опреации с дисплеем и сериал портом.
    Если у вас ардуинка, то засыпание не шибко то и экономит энергию. (или вы с отдельным камнем работаете?)
    Если она постоянно отправляет данные по ком-порту, значит к ней подводятся провода? и питание? зачем спать? А дисплей спать не идёт?
    ВотчДог создавался не для таких целей:(. ВотчДог это таймер, в процессе работы программы его сбрасывают, если сброса не происходит достаточно долго (программа попала в непредусмотренный беск. цикл или ещё какой-то сбой, который требует на себя много времени), то вызывается программный ресет, о чём вам и говорили выше.
    Может, ещё чего посоветуют тут...
     
  8. vvr

    vvr Инженерище

    не обращайте внимания, паровозз он такой)))))
     
    Daniil нравится это.
  9. EandV

    EandV Нерд

    Я уж понял )

    Спасибо за инфо. Код однозначно требует оптимизации. Написал для начала лишь бы работало, теперь как понял, работает не всегда.

    Если вкратце, то код отсюда:

    http://forum.amperka.ru/threads/Автономный-автополив-на-1-12-комнатных-растений-на-arduino.16526/

    В КОМ порт данные не отправляет, это осталась закомменченая строка, которую я использовал во время отладки. Информация выводится на дисплей и только в период, когда нажата кнопка. Всё делается с целью энергосбережения, т.к. система автономная и питается от солнечной батареи и аккумуляторов. Уход в сон Ардуинки заметно улучшает энергосбережение (разница около 10-15 мА).
     
    Последнее редактирование модератором: 20 окт 2018
  10. Daniil

    Daniil Гик

    А кто у вас считает время? Большие интервалы считаются? Точность нужна? (ардуина может уплыть по времени) применяют микросхемы часов реального времени. Эти часы могут дёргать ногой (если слишком часто дёргают, то можно примитивный счётчик поставить), по дёргании ноги и можно просыпаться, а ВотчДог оставить на слежку за "зависанием".
    Так же можно попробовать проводить самоконтроль, если пины должны быть выключены, но это не так, то принудительное выключение. Проверку делать секунд через N после полива.
     
  11. EandV

    EandV Нерд

    Время считает модуль DS3231. Интервалы примерно 4-5 дней. Точность срабатывания 1 час. Алгоритм сделан так, что как только наступает заданный час, начинается полив, далее идет Delay с количеством секунд в зависимости от продолжительности полива, когда Delay заканчивается на Пин подается низкий сигнал.
    Идея с проверкой пинов интересная, нужно попробовать.
     
    Daniil нравится это.
  12. Не увеличит, если система работоспособна без него.
     
  13. parovoZZ

    parovoZZ Гуру

    конечно.
    У меня лежит ваша кетайская абдурина прямо на балконе. На неё задувает, заливает, снегом сыплет. Полтора года работает. Вачдог в качестве таймера, т.е. ресетить отучен.