Уроки Arduino: автоматическая система полива (орошения)

В этом уроке - создание системы домашнего орошения растений на основе микроконтроллера Arduino (Ардуино). Есть тонны похожих проектов и обучающих программ, уже размещенных в Интернете, но, возможно, данный урок - это некая иная альтернатива, которая натолкнет на дополнительные мысли и идеи.

Шаг 1: Готовим инструменты и детали

Что нам понадобится:

  • 1 шт. - Arduino Uno (или чип atmega328 и программист)
  • 1 шт. - резистор 10 кОм
  • 1 шт. - резистор 20 кОм
  • 1 шт. - ULN2803a (или MOSFETS + диоды)
  • 1 шт. - дисплей TM1637
  • 2 шт. - гигрометрические датчики
  • 1 шт. - кратковременная кнопка
  • 1 шт. - релейная плата
  • 2 шт. - насосы
  • 1 шт. - 2-полюсная клемма
  • Сокеты (опционально, но настоятельно рекомендуется иметь возможность легко перепрограммировать чип atmega, если это необходимо)

И в зависимости от того, используете ли вы Arduino или Atmega:

  • 1 шт. - 16 МГц кристалл
  • 2 шт. - 22 пФ конденсатора
  • 1 шт. - 10 мкФ конденсатор
  • 1 шт. - 1N4001 диод
  • Соединительные провода и кабели
  • Трубка
  • Макетная плата
  • Источники питания (5 В или более и один блок питания для ваших насосов)

Вам понадобятся также основные инструменты, например:

  • Паяльник
  • Плоскогубцы
  • Кабельный стриппер
  • Цифровой мультиметр

Шаг 2: Схема подключения

Выше можно увидеть схемы как для автономной версии atmega328, так и для подключения к Arduino Uno. Поскольку устройство должно запускаться сам по себе после завершения урока, не будут нужны никакие функции arduino и просто используется чистый чип. Можно использовать чип от arduino или использовать arduino в качестве программера для другого чипа. Как можно увидеть из схема шины земли и питания (GND и 5V) есть с обеих сторон макетной платы. Все соединения GND и 5V на схеме идут на них.

Также ниже посмотрите распиновку чипа atmega в сравнении с ардуино:

Если вы собираетесь припаять все на печатной плате, обязательно используйте цифровой мультиметр, чтобы проверить все соединения и убедиться, что все силовые рельсы питаются от 5В. Если вы собираетесь использовать блок питания с напряжением более 5 В, добавьте соответствующие регуляторы напряжения (7805, например). Рекомендуется паять гнездо на плату вместо чипа напрямую, так что можно было бы легко вытащить его снова для перепрограммирования, поскольку нужно выполнять тонкую настройку.

Помимо этого, нужно иметь возможность воссоздать все соединения из схемы выше.

В уроке использован модуль ULN2803A, потому что выходные выводы atmega (и, следовательно, вероятно, arduino тоже) не обеспечивают достаточный ток для переключения реле. Реле требует около 60 мА, но на выводах atmega не должны быть превышения выше 40 мА. Кроме того вы не должны переключать индуктивные нагрузки как реле непосредственно так или иначе. Модуль защищает чип от повреждений. Модуль создает падение напряжения, поэтому, если ваше реле не может питаться с мощностью менее 5 В, используйте соответственно MOSFET и обратные диоды.

Шаг 3: Подключение реле и насосов

Плата реле состоит из 3 терминалов для каждого входа: NO, NC и COM. Уже есть привычка переключаться как на нейтраль, так и на фазу для каждого насоса, с конкретным источником питания, который был использован, было точное понимание какой провод куда идет. Это не всегда так, поскольку у вас может не быть защиты от полярности.

Отрезаем провода от источника питания и подключаем их к COM-портам. Затем подключаем разомкнутые клеммы к насосам. Когда реле включается, разомкнутое соединение закрывается и насос запускается. Чтобы иметь возможность использовать 1 блок питания для нескольких насосов, мы подключили закрытый порт к COM-порту следующего набора терминалов.

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

Когда насос 1 включен, терминалы 1 и 2 включаются, нейтраль и фаза соединены через клеммы «NO» и «COM», обычно закрытый терминал теперь открыт. Мы не включаем оба насоса одновременно, а включаем последовательно. Более подробное объяснение и пример того, как модули реле работают будет в следующих материалах.

Шаг 4: Код

Когда все подключено, пришло время погрузиться в код. Библиотека для 7-сегментного дисплея находится здесь.

Гигрометры будут корродировать довольно быстро, если они будут постоянно подключены к 5V, поэтому их нужно питать током только когда нам действительно нужно измерить влажность. По этой причине они не подключены к шине питания.

const int hygrometer1 = A0;  //Hygrometer sensor at pin A0
const int hygrometer2 = A1;  //Hygrometer sensor at pin A
int Pump1_1 = 11;  // Pump 1, cable 1
int Pump1_2 = 2;  // Pump 1, cable 2
int Pump2_1 = 3;  // Pump 2, cable 1
int Pump2_2 = 4;  // Pump 2, cable 2
int Hygro1 = 9;  // VCC Hygrometer 1
int Hygro2 = 10  ;  // VCC Hygrometer 2
int value1;
int value2;
int runs1 = 0; // counts how many times the pumps have been turned on
int runs2 = 0;

#include "SevenSegmentTM1637.h" 
const byte PIN_CLK = 8;   // define CLK pin (any digital pin)
const byte PIN_DIO = 7;   // define DIO pin (any digital pin)
int inPin = 6; // input of the push button
int val = 0; 
int push_count = 0; // counts how many times the button was pushed
int buttonState = 0; // saves the state of the button, low or high
SevenSegmentTM1637    display(PIN_CLK, PIN_DIO);
unsigned long previousMillis = 0; // taken from the blink with delay example
const long interval = 1800000; // only measure every 30 minutes

void setup() {
  display.begin(); // init the display
  display.setBacklight(20);  // set the brightness of the display to 20 %
  Serial.begin(9600);
 
  // set all the pin modes accordingly
  pinMode(Pump1_1, OUTPUT); 
  pinMode(Pump1_2, OUTPUT);
  pinMode(Pump2_1, OUTPUT);
  pinMode(Pump2_2, OUTPUT);
  pinMode(Hygro1, OUTPUT);
  pinMode(Hygro2, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(inPin, INPUT);

  // set all the pins to their initial states
  digitalWrite(8, LOW);
  digitalWrite(Pump1_1, LOW);
  digitalWrite(Pump1_2, LOW);
  digitalWrite(Pump2_1, LOW);
  digitalWrite(Pump2_2, LOW);
  digitalWrite(Hygro1, LOW);
  digitalWrite(Hygro2, LOW);
  // display that the system is booting
  display.clear();
  display.print("INIT");      
  delay(2000);               
  display.clear();
 
}

void loop() {
  // we are counting how many milli seconds have passed since the system booted, if we completed a 30 min intervall, run measure(), else run buttons()
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval || previousMillis == 0) { // note the || previousMillis == 0, we also want to measure on bootup, it's easier to identify mistakes
    // save the last time we measured the moisture
    previousMillis = currentMillis;
    
  measure();
  }
  buttons();
}

void measure() {
  display.clear();
  display.print("read");
  digitalWrite(Hygro1, HIGH); // supply the hygrometer with voltage
  digitalWrite(Hygro2, HIGH); // supply the hygrometer with voltage
  delay(2000);
  value1 = analogRead(hygrometer1); // read the value (0-1023)
  value2 = analogRead(hygrometer2); // read the value (0-1023)
  delay(2000);  
  digitalWrite(Hygro1, LOW); // turn off the hygrometer
  digitalWrite(Hygro2, LOW); // turn off the hygrometer
  display.clear();
  
  if (value1 <= 550) // check if the plant is well watered (lower values mean well watered)
{
  display.clear();
  display.print("1 OK");
  delay(2000);
  display.clear();
}
else
{
  digitalWrite(Pump1_1, HIGH);
  digitalWrite(Pump1_2, HIGH);

  delay(20000); // time in ms how long the pump is turned on, 20 s here

  digitalWrite(Pump1_1, LOW);
  digitalWrite(Pump1_2, LOW);
  runs1++; // increment the number of times pump 1 has run
}

  if (value2 <= 450)
{
  display.clear();
  display.print("2 OK");
  delay(2000);
  display.clear();
}
else
{
  digitalWrite(Pump2_1, HIGH);
  digitalWrite(Pump2_2, HIGH);

  delay(20000); // time in ms how long the pump is turned on, 20 s here

  digitalWrite(Pump2_1, LOW);
  digitalWrite(Pump2_2, LOW);
  runs2++; // increment the number of times pump 2 has run
}  
  }

// the script to print the values and cycle through the display
void buttons() {
  val = digitalRead(inPin); // read state of the button
  if (val != buttonState && val == HIGH){ // make sure we detect a change from LOW to HIGH
    push_count++; // count that the button has been pushed
  }
      else {
      // do nothing
    }

  buttonState = val; // save the current state
  
  switch (push_count) {
    case 0:    
      display.clear();  
      display.print("sns1");
      delay(2000);
      display.clear();
      push_count++;
      break;              
    case 1:    
      display.print(value1);  
      break;
    case 2:   
      display.clear();  
      display.print("sns2");
      delay(2000);
      display.clear();
      push_count++;
      break;
    case 3:   
      display.print(value2);  
      break;
    case 4:   
      display.clear();  
      display.print("no 1");
      delay(2000);
      display.clear();
      push_count++;
      break;
    case 5:   
      display.print(runs1);  
      break;
    case 6:   
      display.clear();  
      display.print("no 2");
      delay(2000);
      display.clear();
      push_count++;
      break;
    case 7:   
      display.print(runs2);  
      break;      
    default:
      push_count=0;  
  }
}

Шаг 5: Итоговый результат

Теперь вы знаете, что с помощью микроконтроллеров подобных Arduino при сильном желании можно создать всё что угодно.

Предупреждение! Мы не знаем, какие насосы или источники питания вы используете. При подключении реле обязательно отсоедините все от электропитания, прежде чем начинать отрезать или подключать любые провода и кабели. Возможно, у вас подключено сетевое напряжение! Ошибки могут привести к серьезным травмам или смерти. Если что-то сделано не правильно может возникнуть возгорание. Авторы урока не несут ответственность за любые убытки, причиненные вам, другим лицам или вашей собственности. Авторы урока не профессиональные электрики и есть вероятность, что отдельные рекомендации в уроке не верны. Если вы не знаете, что делаете и чувствуете себя некомфортно, не продолжайте проект или обратитесь к профессионалу. Вы действуете на свой страх и риск.

На этом всё, желаем вам отличных проектов.

15 марта 2018 в 13:58 | Обновлено 7 декабря 2019 в 02:17 (редакция)
Опубликовано:
Уроки

Добавить комментарий

Ваш E-mail не будет никому виден. Обязательные поля отмечены *