Привіт, захопленим електронікою читачам. У цій статті і відео нам належить розробити, змонтувати і налагодити проект під назвою регулятор вологості повітря на Ардуіно. Це реальний замовлений мені проект, виконання якого хочу показати вам. Ми разом з вами підберемо компоненти, накреслимо схему їх електричного з'єднання. Змонтуємо прилад в корпусі. Напишемо і налагодимо програму. І в кінці шляху отримаємо готовий пристрій - регулятор вологості повітря для передачі замовнику.
Обов'язково підпишіться на наш канал Youtube
Звучить завдання просто: необхідно вимірювати вологість в приміщенні, схильному до її збільшення і включати вентилятор при вологості, вище заданої. Вентилятор живиться від мережі 220В. Так само в завданні чітко вказано, що повинна бути можливість зміни величини заданої вологості повітря. І найскладніше я в цьому проекті виділю реалізацію інтерфейсу для введення завдання на регулювання вологості, що потягне за собою індикатор для відображення цифр, а також інструмент введення даних.
За описом замовника, приміщення з датчиком схильне до конденсації вологи. Тому пристрій регулювання буде знаходитися в сухому сусідньому приміщенні, а датчик буде винесено на проводах. Сам датчик я виберу BME280 - він, якщо добре плату загерметизувати лаком або термоклеєм, менше інших боїться конденсату. Він може також заміряти і температуру і тиск повітря, але в цьому проекті ці дані будуть не задіяні. Індикатор буде чотиризначний на світлодіодах з дробовими точками між цифрами. Корпус з прозорою кришкою для безпроблемного монтажу індикатора.
Блок живлення візьмемо на 9В, підключимо на вхід VIN контролера Arduino і всі модулі будуть живитися від стабілізатора напруги 5В 800мА на його борту.
Модуль реле буде найдешевший одноканальний на 5В. З одним недоліком - логіка зворотна і при подачі живлення реле може проклацувати короткочасно.
Розроблена схема спрощує монтаж, а так само розробку програми. Тому я вам раджу не нехтувати схемою при реалізації своїх проектів. Я розроблю схему в улюбленій безкоштовній програмі KiCad. Результуюча схема регулятора вологості перед вами.
Тепер монтуємо всі компоненти в корпус згідно принципової схеми. Вивід проводів на вентилятор зробимо через гермоввод. І так само зробимо з відведенням кабелю для датчика вологості BME280. Свердлимо отвори в корпусі для енкодера, введення живлення та двох гермовводів. Монтуємо дроти, приклеюємо модулі на своє місце. Залізо для регулятора на Ардуіно готове.
Тепер накидаємо скетч для завантаження в контроллер. У ньому потрібно передбачити зчитування поточного значення вологості повітря з датчика по мережі I2C, обробку енкодера і кнопки енкодера, управління релешкою, відображення на індикаторі двох режимів: поточного і введення завдання. Так само необхідно програмно передбачити запис останнього значення заданої вологості в постійну енергонезалежну пам'ять контролера, щоб при виключенні живлення завдання не скидалося на нуль.
Програма під Arduino IDE вийшла така
#include <Wire.h> #include <BME280.h> #include <EEPROM.h> BME280 bme; #define SCLK 10 #define RCLK 9 #define DIO 8 #define button 4 #define relay 5 byte digitBuffer[4]; unsigned long previousMillis = 0; const long interval = 1000; int pinA = 2; int pinB = 3; int encoderPosCount = 0; int pinALast; byte mode; float h_set, humidity; void setup(){ pinMode(RCLK, OUTPUT); pinMode(SCLK, OUTPUT); pinMode(DIO, OUTPUT); pinMode(relay, OUTPUT); digitalWrite(relay, HIGH); EEPROM.get(0, h_set); bme.begin(); Serial.begin(9600); pinMode (button,INPUT_PULLUP); pinMode (pinA,INPUT); pinMode (pinB,INPUT); pinALast = digitalRead(pinA); attachInterrupt(0, doEncoderA, CHANGE); } void loop() { unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis; if(digitalRead(button) == LOW) {if (mode==1) {mode=0; EEPROM.put(0, h_set);} else {mode=1; encoderPosCount=h_set;}} Serial.print("h_set="); Serial.println(h_set); humidity = bme.readHumidity(); unsigned int intvar; if(mode==0) intvar = humidity * 10.0; else intvar = h_set * 10.0; digitBuffer[0] = intvar / 1000; digitBuffer[1] = intvar % 1000 / 100; digitBuffer[2] = intvar % 1000 % 100 / 10; digitBuffer[3] = intvar % 1000 % 100 % 10; out_func(); } showDisplay(); }
void doEncoderA() { if (pinALast != digitalRead(pinA)){ if (digitalRead(pinA) == HIGH) { if ((digitalRead(pinB) == LOW)&&(encoderPosCount<100)) { encoderPosCount ++; // CW } else if(encoderPosCount>0){ encoderPosCount--; // CCW } } Serial.println (encoderPosCount); } pinALast = digitalRead(pinA); if (mode==1) h_set=encoderPosCount; }
void out_func(){ if (humidity > h_set) digitalWrite(relay, LOW); if (humidity < h_set-2.0) digitalWrite(relay, HIGH); }
void showDisplay(){ const byte digit[10] = { 0b11000000, // 0 0b11111001, // 1 0b10100100, // 2 0b10110000, // 3 0b10011001, // 4 0b10010010, // 5 0b10000010, // 6 0b11111000, // 7 0b10000000, // 8 0b10010000, // 9 }; const byte chr[4] = { 0b00001000, 0b00000100, 0b00000010, 0b00000001 }; for(byte i = 0; i <= 3; i++){ digitalWrite(RCLK, LOW); byte chislo = digit[digitBuffer[i]]; if(i==2) chislo &=~(1<<7); shiftOut(DIO, SCLK, MSBFIRST, chislo); shiftOut(DIO, SCLK, MSBFIRST, chr[i]); digitalWrite(RCLK, HIGH); delay(1); } }