Авто полив с датчиком влажности на ATtiny85

YusupOFF

★✩✩✩✩✩✩
9 Дек 2018
6
11
Доработанный скетч AlexGyver Тема в форуме
Добавил опрос датчика влажности, при достижения порога срабатывании включается помпа
Проект пока сырой, не проверялось в железе.
Предполагается использовать следующие компоненты:
Ёмкостный датчик влажности
ATtiny85-20PU в корпусе DIP8
Питание от батареек


C++:
/*
* Авто полив с датчиком влажности
* Датчик влажноси потредляет - 5,55мА
* Порог срабатывания помпы нужно настроить под ваш датчик
*
*
*              ________
* RESET 5/A0 -|        |- VCC
*       3/A3 -| ATtiny |- A1/2 SCK
*       3/A2 -|   85   |- 1    MISO
*        GND -|________|- 0    MOSI
*      
* Author:  Yusupoff
* 09.12.18
*/
// Нужно настроить                                                                сек   мин  час  день
#define PERIOD 172800                        // период работы в секундах (пример:  60 * 60  * 24 * 2  =  172800сек
#define WORK 20                              // время работы в секундах
#define VLAG 100                             // Порог срабатывания помпы
// Нужно настроить ^^^^^^^


#include <avr/wdt.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>

#define adc_disable() (ADCSRA &= ~(1<<ADEN)) // Отключить АЦП
#define adc_enable()  (ADCSRA |=  (1<<ADEN)) // Включить АЦП

#define PIN_SENSOR A1                        // Пин датчика, аналоговый вход
#define POW_SENSOR  1                        // Пин питания датчика
#define PIN_MOSFET 0                         // Пин мосфета помпы

uint32_t mainTimer, myTimer;                 // Таймеры
uint8_t  sensVLAG;
boolean  state = false;                       // Флаг работы помпы

void setup() {
  for (byte i = 0; i < 6; i++) pinMode(i, INPUT);         // все пины как входы, экономия энергии
  adc_disable();                                          // отключить АЦП (экономия энергии)
  wdt_reset();                                            // инициализация ватчдога
  wdt_enable(WDTO_1S);                                    // разрешаем ватчдог
                                                          // 15MS, 30MS, 60MS, 120MS, 250MS, 500MS, 1S, 2S, 4S, 8S
  delay(2000);
  WDTCR |= _BV(WDIE);                                     // разрешаем прерывания по ватчдогу. Иначе будет резет.
  sei();                                                  // разрешаем прерывания
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);                    // максимальный сон
}

void loop() {
  mainTimer++;

  if (!state) {                                  // если помпа не включена 1 - if
    if ((long)mainTimer - myTimer > PERIOD) {    // таймер периода
      myTimer = mainTimer;                       // Сброс таймера
     
      adc_enable();                              // Включить АЦП
      powerSavePin(false,POW_SENSOR);            // Подать питание на пин
      delay(50);                                 // Задержка
      sensVLAG = analogRead(PIN_SENSOR);         //
      powerSavePin(true,POW_SENSOR);             // Отключить питание на пине
      adc_disable();                             // Отключить АЦП
     
      if (sensVLAG <= VLAG) {                    // Если влажность упала то...
        state = true;                            // Поднять флаг работы помпы
        powerSavePin(false,PIN_MOSFET);          // Подать питание на пин
      }
    }
  } else {                                       // если помпа включена    1 - if
    if ((long)mainTimer - myTimer > WORK) {      // таймер времени работы
      myTimer = mainTimer;                       // Сброс таймера
      state = false;                             // Отпустить флаг работы помпы
      powerSavePin(true,PIN_MOSFET);             // Отключить питание на пине
    }
  }

  sleep_enable();                               // разрешаем сон
  sleep_cpu();                                  // спать!
}

void powerSavePin (boolean saveF, int pinN) {
  if (saveF) {                        // Если пин как вход
    digitalWrite(pinN, LOW);          // Отключить питание на пине
    pinMode(pinN, INPUT);             // Пин как вход
  } else {                            // Если пин ка выход
    pinMode(pinN, OUTPUT);            // Пин как выход
    digitalWrite(pinN, HIGH);         // Подать питание на пин
  }
}
ISR (WDT_vect) {
  WDTCR |= _BV(WDIE); // разрешаем прерывания по ватчдогу. Иначе будет реcет.
}
 

Вложения

Изменено:

EandV

★★★✩✩✩✩
4 Авг 2018
288
167
Приветствую!
Вот тут по коду не совсем понял:
if (sensVLAG >= VLAG) { // Если влажность упала то...
Вроде как читается : если влажность выше или равна заданного уровня.

И вообще с точки зрения общего алгоритма, как зависит срабатывание помпы от таймера и датчика? Если в указанное время влажность ниже необходимого уровня, то поливаем или как?
Спрашиваю вот почему: например настроил я полив раз в 7 дней, а датчик показал, что почва влажная, следующая проверка на влажность через сколько будет? только через 7 дней?
 

YusupOFF

★✩✩✩✩✩✩
9 Дек 2018
6
11
@EandV,
if (sensVLAG <= VLAG) { Да надо <=
Поднимает флаг работы помпы и запускает ее.
Срабатывание зависит от #define PERIOD 172800 и #define VLAG 100
С начало проверяет прошло ли 172800 секунд если да то проверяет влажность почвы. Если влажность почвы упало то включает помпу на время #define WORK 20
Дальше проверяет сколько секунд работает помпа если 20 сек то отключает ее