RDC1-0000, Контроллер полива растений

RDC1-0000, Контроллер полива растений
Только в рознице. Цена, возможность и сроки поставки потребуют уточнения
746.10 × = 746.10

Спецификация набора

То, что у вас уже есть, вы можете удалить в корзине.

НаименованиеЦенаКол-во
Печатная плата rdc1-0000, Печатная плата с разводкой, FR4 32х145мм (1.5мм, 18мкм) 190 1
ATTINY24-20SSU, Микроконтроллер 8-Бит, AVR, 20МГц, 2КБ Flash [SO14] 110 1
Конд.кер.диск. 0.1 мкФ х 50В,+80-20% 3 2
CF-25 (С1-4) 0.25 Вт, 47 Ом, 5%, Резистор углеродистый 0.90 3
CF-25 (С1-4) 0.25 Вт, 10 кОм, 5%, Резистор углеродистый 0.90 6
SL-30V1-A10K, 10 кОм, Резистор переменный движковый 26 2
BSS138LT1G, Транзистор, N-канал 50В 220мА [SOT-23] 4 4
BL-FL7600UGC, Светодиод "Пиранья" зеленый 100" 700мКд 574нМ (Ultra Green) 7 1
BL-FL7600URC, Светодиод "Пиранья" красный 100" 1000мКд 660нМ (Ultra Red) 16 1
BL-FL7600UYC, Светодиод "Пиранья" желтый 100" 1300мКд 590нМ (Ultra Yellow) 16 1
L-3DP3C (L-32P3C), Фототранзистор d=3мм, Iтемн=100нА 11 1
PLD-6 (DS1021-2x3S), Вилка штыревая 2.54мм 2x3 прямая тип1 6 1
PLS-3R (DS1022-1x3-R), Вилка штыревая 2.54мм 1х3 угловая (тип D1) 4 1
TC-3121, Кнопка тактовая h=5.0 мм 6 1
BH321 (BH603) (KLS5-802-B), Батарейный отсек AA 2x1 20 1
4106 (A316/LR6/AA)1, Элемент питания алкалиновый LONGLIFE (1шт) 1.5В 44 2
Troyka-Soi Moisture Sensor, Датчик влажности почвы для Arduino проектов 190 1

Описание

Это конструкция эффективно, эффектно и очень логично показывает влажность почвы в домашнем цветке или на грядке дачного участка.

Возможности:

  • настройка нормального уровня влажности
  • настройка чувствительности к дневному свету
  • отключение устройства ночью
  • индикация влажности исходя из заданной нормы, зоны пересчитываются автоматически
  • предусмотрен вывод МК и настройки ПО для автоматического полива

Внешний вид

Представьте себе светофор. Горит зеленый свет – влажность почвы достаточная и поливать еще рано. Когда гаснет зеленый и загорается желтый – можно ещё не поливать. Чрезмерный полив не всегда идет на пользу. А вот когда желтый меняется на красный, то всё, ищите лейку, открывайте кран, поднимайте шлюзы… Это про эффективно.

Теперь насчет эффектно. Представьте. Пять, шесть или ещё больше наших светофоров расставлены по дачному участку. Светящиеся светодиоды направлены к крыльцу. Красиво? А вечером? Гости счастливы.

Логично. Вы сами настраиваете, как должны работать ваши агросветофоры. На борту устройства установлен фототранзистор VT5 – он определяет светлое время суток. Именно днем должен работать наш датчик полива. Уровень освещенности (порог светового дня) устанавливается ползунковым резистором R11. А если посмотреть скетч, то в строке определения
#define WORK_AFTER_DAYLIGHT ((long) 28125000)
можно выставить время работы устройства после захода солнца и тогда на участке вечером ещё долго будет красиво. По умолчанию установлено время 1 час.

Уровень влажности почвы устанавливается ползунковым переменным резистором R10.

Установка режима работы устройства производится следующим образом:
1. Нажимаем кнопку SW1 и удерживаем пока все светодиоды не начнут моргать, показывая, что устройство перешло в режим настройки.
2. Отпускаем кнопку SW1 и выставляем значения влажности и освещенности.
3. Коротко нажимаем SW1. Все светодиоды моргнули. Устройство перешло в штатный режим.

Автоматический полив. Агросфетофор может выполнять роль контроллера автоматического полива. Для этого перед прошивкой необходимо раскомментировать определение
//#define AUTO_POLIV
Тогда в момент срабатывания красного светодиода на выводе PB2 выставится логическая единица. Этим сигналом можно будет включить помпу или кран. Единица снимется на уровне между желтым и красным.

Ниже приведена электрическая схема, монтажная схема, файлы печатной платы, которую можно изготовить по технологии ЛУТ или заказать на производстве. Файлы проекта, выполненные в KiCAD, можно скачать в разделе документация.

В скетче вы можете найти все комментарии и легко адаптировать устройство для ваших нужд.

Технические параметры

Напряжение питания, В 3 … 5
Потребляемый ток, мА 30

Электрическая схема

Электрическая схема

Монтажная схема

Монтажная схема

Печатная плата

Плату вы можете купить отдельно.

 Печатная плата

Скетч. Код программы

#include <avr/eeprom.h>


//Attiny24a
//обозначения выводов
//PORTA
#define          GREEN_LED                 5
#define          YELLOW_LED                6
#define          RED_LED                   4
#define          SENSOR_EN                 1

//PORTB
#define          KEY                       0
#define          WATER_CTRL                1

//каналы АЦП
#define          HUM_SET                   (~((1 << MUX0) | (1 << MUX1) | (1 << MUX2) | (1 << MUX3) | (1 << MUX4) | (1 << MUX5)))
#define          LIGHT_SET                 ((1 << MUX0) | (1 << MUX1))
#define          HUM_SENSOR                (1 << MUX1)
#define          LIGHT_SENSOR              ((1 << MUX0) | (1 << MUX1) | (1 << MUX2))


#define          NORM_LIGHT_DEFAULT        70 //нормальный уровень освещенности по умолчанию
#define          NORM_HUM_DEFAULT          140 //нормальный уровень влажности по умолчанию
#define          GREEN_NORMAL_MAX          220 //отметка полива по умолчанию

#define          THRESHOLD                 20

#define          WORK_AFTER_DAYLIGHT       ((long) 14400) //время работы устройства после уменьшения
                                                         //уровня освещенности ниже нормального
                                                         //1 с равна 4 единицам
                                                         //для настройки поставьте 4

#define          LED_ON_TIME               1 //соответствует 250 мс
#define          LED_OFF_TIME              12 //соответствует 3 с
#define          LED_BLINK_PERIOD          (LED_ON_TIME + LED_OFF_TIME)

#define          HUM_SET_ADR               64 //адрес в памяти для хранения настроек нормального уровеня влажности
#define          LIGHT_SET_ADR             (HUM_SET_ADR + 1) //адрес в памяти для хранения настроек нормального уровеня освещенности

//если используется автополив, раскомментируйте следующую строку
//#define          AUTO_POLIV             



volatile boolean KEY_PRESS_FLAG = false;
static boolean DAY_LIGHT_FLAG = false;
static byte DayLight;
static byte NormalHumidity;
static byte YELLOW_LINE;
static long DayLightCnt = 0;
static boolean DayLightCntStart = false;
static byte LedOnCnt = 0;

void setup()
{ 
  //настройка линий ввода/вывода
  DDRA = (1 << GREEN_LED) | (1 << YELLOW_LED) | (1 << RED_LED) | (1 << SENSOR_EN);
  PORTA &= ~((1 << GREEN_LED) | (1 << YELLOW_LED) | (1 << RED_LED) | (1 << SENSOR_EN));
  
  DDRB = 1 << WATER_CTRL;
  PORTB &= ~(1 << WATER_CTRL);
  PORTB |= 1 << KEY;
  //настройка АЦП
  ADMUX = LIGHT_SENSOR;
  ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
  ADCSRB = (1 << ADLAR);
  ACSR = (1 << ACD);
  DIDR0 |= (1 << ADC0D) | (1 << ADC2D) | (1 << ADC3D) | (1 << ADC7D);

  ADCSRA |= (1 << ADSC);
  while (ADCSRA & (1 << ADSC));
  //чтение настроек влажности
  NormalHumidity = eeprom_read_byte((uint8_t*)HUM_SET_ADR);
  if (NormalHumidity == 0xFF)
    NormalHumidity = NORM_HUM_DEFAULT;
  //чтение настроек освещенности
  DayLight = eeprom_read_byte((uint8_t*)LIGHT_SET_ADR);
  if (DayLight == 0xFF)
    DayLight = NORM_LIGHT_DEFAULT;
  //вычисление нижней границы желтой зоны
  YELLOW_LINE = (NormalHumidity / 3) * 2;
  
  //настройка прерываний
  PCMSK1 |= 1 << PCINT8;
  GIMSK |= 0x20;
  SREG |= 0x80;
}
//------------------------------------------------------
void loop()
{
  //измерение освещенности
  ADMUX &= HUM_SET;
  ADMUX |= LIGHT_SENSOR;
  ADCSRA |= (1 << ADSC);
  while (ADCSRA & (1 << ADSC));
  unsigned int  LightLevel = ADCH * 7;

  if (LightLevel >= DayLight) //если освещенность больше или равна заданной
  {
    DAY_LIGHT_FLAG = true; //"светлое" время суток

    if (DayLightCntStart) //если выставлен флаг "темного" времени суток
    {
      DayLightCntStart = false; //сброс флага
    }

    if (DayLightCnt > 0)
      DayLightCnt = 0;
  }
  else if (!DayLightCntStart) //иначе, если флаг "темного" времени суток сброшен
  {
    DAY_LIGHT_FLAG = true; //"светлое" время суток
    DayLightCnt++; //увеличение значения отсчета "темного" времени суток
    
    if (DayLightCnt > WORK_AFTER_DAYLIGHT) //если значение отсчета "темного" времени суток больше заданного
    {
      PORTA &= ~((1 << GREEN_LED) | (1 << YELLOW_LED) | (1 << RED_LED));
      DayLightCntStart = true; //выставление флага "темного" времени суток
      DAY_LIGHT_FLAG = false; //сброс флага "светлого" времени суток
      DayLightCnt = 0;
    }
  }

  if ((LedOnCnt < LED_ON_TIME) && (DAY_LIGHT_FLAG)) //если "светлое" время суток
  {
    PORTA |= 1 << SENSOR_EN; //включение датчика влажности
    //измерение влажности
    ADMUX &= HUM_SET;
    ADMUX |= HUM_SENSOR;
    ADCSRA |= (1 << ADSC);
    while (ADCSRA & (1 << ADSC));

    if (ADCH > THRESHOLD)
    {
#ifdef AUTO_POLIV //если выбран автополив

      if (ADCH < NormalHumidity) //если влажность меньше нормальной
      {
        PORTB |= 1 << WATER_CTRL; //включение полива
        //вычисление отметки, до которой поливаем: нормальная влажность + нормальная влажность/4
        unsigned int GREEN_NORMAL = NormalHumidity + NormalHumidity / 4;
        if (GREEN_NORMAL > GREEN_NORMAL_MAX)
          GREEN_NORMAL = GREEN_NORMAL_MAX;
        //пока не включен зеленый светодиод, т.е. пока влажность не достигла значения GREEN_NORMAL
        while ((PINA & (1 << GREEN_LED)) == 0)
        { //измерение влажности
          ADCSRA |= (1 << ADSC);
          while (ADCSRA & (1 << ADSC));
          
          if ((ADCH < YELLOW_LINE)&& (((PINA & (1 << RED_LED)) == 0))) //если меньше нижней границы желтой зоны
          {
            PORTA &= ~((1 << GREEN_LED) | (1 << YELLOW_LED) | (1 << RED_LED));
            PORTA |= (1 << RED_LED); //включение красного светодиода
          }

          else if ((ADCH < GREEN_NORMAL) && (((PINA & (1 << YELLOW_LED)) == 0))) //если меньше значения GREEN_NORMAL
          {
            PORTA &= ~((1 << GREEN_LED) | (1 << YELLOW_LED) | (1 << RED_LED));
            PORTA |= (1 << YELLOW_LED); //включение желтого светодиода
          }
    
          else //иначе
          {
            PORTA &= ~((1 << GREEN_LED) | (1 << YELLOW_LED) | (1 << RED_LED));
            PORTA |= (1 << GREEN_LED); //включение зеленого светодиода
          }
        }
      }
         
#else //если без автополива

      if ((ADCH < YELLOW_LINE)&& (((PINA & (1 << RED_LED)) == 0))) //если меньше нижней границы желтой зоны
      {
        PORTA &= ~((1 << GREEN_LED) | (1 << YELLOW_LED) | (1 << RED_LED));
        PORTA |= (1 << RED_LED); //включение красного светодиода
        delay(250);
        PORTA &= ~(1 << RED_LED);
        delay(250);
        PORTA |= (1 << RED_LED);
      }
      else if ((ADCH < NormalHumidity) && (((PINA & (1 << YELLOW_LED)) == 0))) //если меньше значения нормальной влажности NormalHumidity
      {
        PORTA &= ~((1 << GREEN_LED) | (1 << YELLOW_LED) | (1 << RED_LED));
        PORTA |= (1 << YELLOW_LED); //включение желтого светодиода
      }
            
#endif

      else if ((PINA & (1 << GREEN_LED)) == 0)//иначе
      {
        PORTA &= ~((1 << GREEN_LED) | (1 << YELLOW_LED) | (1 << RED_LED));
        PORTA |= (1 << GREEN_LED); //включение зеленого светодиода
      }
    }
    
    else if ((ADCH <= THRESHOLD) && (((PINA & (1 << RED_LED)) == 0)))
    {
      PORTA &= ~((1 << GREEN_LED) | (1 << YELLOW_LED) | (1 << RED_LED));
      PORTA |= (1 << RED_LED);
      delay(250);
      PORTA &= ~(1 << RED_LED);
      delay(250);
      PORTA |= (1 << RED_LED);
    }

    PORTA &= ~(1 << SENSOR_EN); //выключение датчика влажности
    DAY_LIGHT_FLAG = false;
    LedOnCnt++;
  }
  
  else if (LedOnCnt >= LED_ON_TIME)
  {
    if ((PINA & ((1 << GREEN_LED) | (1 << YELLOW_LED) | (1 << RED_LED))) != 0)
    {
      PORTA &= ~((1 << GREEN_LED) | (1 << YELLOW_LED) | (1 << RED_LED));
    }
    
    LedOnCnt++;

    if (LedOnCnt == LED_BLINK_PERIOD)
      LedOnCnt = 0;
  }

  if (KEY_PRESS_FLAG) //если нажата кнопка
  {
    PCMSK1 &= ~(1 << PCINT8); //деактивация прерывания по нажатию кнопки
    delay(70); //задержка

    if (((PINB >> KEY) & 1) == 0) //если кнопка нажата
    {
      while(((PINB >> KEY) & 1) == 0) //пока кнопка нажата
      {
        PORTA |= (1 << GREEN_LED) | (1 << YELLOW_LED) | (1 << RED_LED); //включение всех светодиодов
        delay(300); //задержка
        PORTA &= ~((1 << GREEN_LED) | (1 << YELLOW_LED) | (1 << RED_LED)); //выключение всех светодиодов
        delay(300); //задержка
      }

      while(((PINB >> KEY) & 1) == 1); //пока кнопка не нажата
      //измерение настроек влажности
      ADMUX &= HUM_SET;
      ADCSRA |= (1 << ADSC);
      while (ADCSRA & (1 << ADSC));
      NormalHumidity = ADCH;
      if (NormalHumidity >= GREEN_NORMAL_MAX)
        NormalHumidity -= 40;
      eeprom_write_byte((uint8_t*)HUM_SET_ADR, NormalHumidity); //сохранение нормальной влажности в памяти
      YELLOW_LINE = (NormalHumidity / 3) * 2; //вычисление нижней границы желтой зоны
      //измерение настроек освещенности
      ADMUX &= HUM_SET;
      ADMUX |= LIGHT_SET;
      ADCSRA |= (1 << ADSC);
      while (ADCSRA & (1 << ADSC));
      unsigned int DayLightVal = ADCH * 7;
      if (DayLightVal >= 0xFF)
        DayLightVal = 0xFE;
      DayLight = DayLightVal;
      eeprom_write_byte((uint8_t*)LIGHT_SET_ADR, DayLight); //сохранение освещенности в памяти
      
    }
    //включение всех светодиодов
    PORTA |= (1 << GREEN_LED) | (1 << YELLOW_LED) | (1 << RED_LED);
    delay(1000); //задержка
    PORTA &= ~((1 << GREEN_LED) | (1 << YELLOW_LED) | (1 << RED_LED)); //выключение всех светодиодов

    PCMSK1 |= 1 << PCINT8; //активация прерывания по нажатию кнопки
    KEY_PRESS_FLAG = false;
  }

  delay(250);
}
//----------------------------------------------------------
//обработчик прерывания по нажатию на кнопку
ISR(PCINT1_vect)
{
  if (((PINB >> KEY) & 1) == 0)
    KEY_PRESS_FLAG = true;
}
//----------------------------------------------------------

Техническая документация

Видео

Комментарии