Здравствуйте!
Поступил заказ изготовить прибор, для контроля уровня углекислого газа (CO2) в четырех помещениях, а также контроля уровня влажности в одном помещении (в ванной). Чтобы была возможность получать данные о содержании углекислого газа со всех датчиков MH-Z19B, и возможность принудительного включения проветривания.
Рабочая модель без подключенных вентиляторов, представлена на фото которое ниже.
В данном проекте используется:
Плата Arduino Uno
4 датчика MH-Z19B
4 сервомотора
Двухканальный модуль с твердотельными реле G3MB-202P
Bluetooth модуль HC-06, но можно и HC-05
Датчик влажности и температуры DHT11
Провода разъемы и кусок платы, к которой все припаял
Ниже представлен код проекта. Как он работает я рассказывал в видео, ссылку на которое найдете в конце этой статьи.
Данный проект можем работать самостоятельно, то есть без использования Bluetooth модуля HC-06 и Android устройства. Но если проветривание будет слишком частым, то в 47 строке кода можете повысить лимиты для срабатывания по датчикам.
Строка выглядит следующим образом limit_1s = 800, limit_2s = 800, limit_3s = 800, limit_4s = 800; .
На пример переменная limit_1s равна 800, значение 800 это и есть предел для срабатывания по первому датчику.
Можете скопировать, и загрузить этот код на плату Arduino.
//Начало скетча
#include "EEPROM.h"
#include "Servo.h"
#include "SimpleDHT.h"
#define DHT_Sensor 6 //контакт для подключения датчика DHT11
SimpleDHT11 dht11(DHT_Sensor);
int temperature_ = 0, humidity_ = 0;
Servo myservo_1;
Servo myservo_2;
Servo myservo_3;
Servo myservo_4;
//контакты к которым подключены сервомоторы
#define servo_1 2
#define servo_2 3
#define servo_3 4
#define servo_4 5
//значения углов в открытом и закрытом состоянии
#define angle_open_1 90
#define angle_close_1 0
#define angle_open_2 90
#define angle_close_2 0
#define angle_open_3 90
#define angle_close_3 0
#define angle_open_4 90
#define angle_close_4 0
boolean flag_1 = 0, flag_2 = 0, flag_3 = 0, flag_4 = 0, flag_1p = 0, flag_2p = 0, flag_3p = 0, flag_4p = 0;
boolean flags_1234 = 0, flags_1234p = 0;
#define kuller_general 18 //подписан на плате как A4
#define kuller_bathroom 19 //подписан на плате как A5
int time_ = 5; //периодичность опроса датчиков в секундах (оптимально от 5 до 120 секунд)
int SensorPins[4][4] = {
{A0, A1, A2, A3}, //A0, A1, A2, A3 контакты для подключения датчиков MH-Z19B
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
};
String sost1, sost2, sost3, sost4, vannaya;
int limit_1, limit_2, limit_3, limit_4, limit_1s = 800, limit_2s = 800, limit_3s = 800, limit_4s = 800;
int addres_0 = 23, addres_1 = 25, addres_2 = 28, addres_3 = 30, addres_4 = 32, flag_start = 4, flag_st;
int count = 0, scan_count = 1, ppm_BUF = 0, result = 0, while_count = 0;
long ppm, timing1 = 0;
void setup() {
Serial.begin(9600);
//чтение из энергонезависимой памяти
EEPROM.get(addres_0, flag_st);
//однократная запись первоначальных настроек при первом запуске после прошивки
if (flag_st != flag_start){
EEPROM.put(addres_0, flag_start);
EEPROM.put(addres_1, limit_1s);
EEPROM.put(addres_2, limit_2s);
EEPROM.put(addres_3, limit_3s);
EEPROM.put(addres_4, limit_4s);
}
//чтение из энергонезависимой памяти
EEPROM.get(addres_1, limit_1);
EEPROM.get(addres_2, limit_2);
EEPROM.get(addres_3, limit_3);
EEPROM.get(addres_4, limit_4);
//подключение сервомоторов
myservo_1.attach(servo_1);
myservo_2.attach(servo_2);
myservo_3.attach(servo_3);
myservo_4.attach(servo_4);
//установка валов сервомоторов в закрытое состояние заслонок
myservo_1.write(angle_close_1);
myservo_2.write(angle_close_2);
myservo_3.write(angle_close_3);
myservo_4.write(angle_close_4);
pinMode(kuller_general, OUTPUT); digitalWrite(kuller_general, HIGH);
pinMode(kuller_bathroom, OUTPUT); digitalWrite(kuller_bathroom, HIGH);
}
void loop() {
//------- Проверка концентрации CO2 по 4 датчикам MH-Z19B ---------
if (millis() - timing1 > time_ * 1000){
timing1 = millis();
while(while_count < 20){
int Val = analogRead(SensorPins[0][count]);
ppm = map(Val, 18, 650, 650, 2000);
if(scan_count > 1 && (ppm > ppm_BUF - 8 && ppm < ppm_BUF + 8)){
ppm_BUF = ppm; SensorPins[scan_count][count] = ppm;
scan_count++;
if(scan_count > 3){
scan_count = 1; count++; if(count > 3){ count = 0;}
}
}else{ scan_count = 1;}
if(scan_count == 1){ SensorPins[scan_count][count] = ppm; ppm_BUF = ppm;
scan_count++;
}
while_count++;
}
while_count = 0;
//------------- Проверка влажности по датчику DHT11 ----------------
byte temperature = 0;
byte humidity = 0;
dht11.read(&temperature, &humidity, NULL);
temperature_ = (int)temperature; humidity_ = (int)humidity;
if(humidity_ > 70){digitalWrite(kuller_bathroom, LOW); vannaya = " ON";
}else{digitalWrite(kuller_bathroom, HIGH); vannaya = " OFF";}
}//millis() - timing1 > 5000
//------------- Настройка лимитов для датчика MH-Z19B ---------------
if (Serial.available()) {
char c = Serial.read();
if (c == 'A') {
limit_1 += 5; EEPROM.put(addres_1, limit_1);
Serial.print(F("Gostinaya +5 LIMIT = ")); Serial.println(limit_1);
}
if (c == 'a') {
limit_1 -= 5; EEPROM.put(addres_1, limit_1);
Serial.print(F("Gostinaya -5 LIMIT = ")); Serial.println(limit_1);
}
if (c == 'B') {
limit_2 += 5; EEPROM.put(addres_2, limit_2);
Serial.print(F("Detskaya +5 LIMIT = ")); Serial.println(limit_2);
}
if (c == 'b') {
limit_2 -= 5; EEPROM.put(addres_2, limit_2);
Serial.print(F("Detskaya -5 LIMIT = ")); Serial.println(limit_2);
}
if (c == 'C') {
limit_3 += 5; EEPROM.put(addres_3, limit_3);
Serial.print(F("Spalnya +5 LIMIT = ")); Serial.println(limit_3);
}
if (c == 'c') {
limit_3 -= 5; EEPROM.put(addres_3, limit_3);
Serial.print(F("Spalnya -5 LIMIT = ")); Serial.println(limit_3);
}
if (c == 'D') {
limit_4 += 5; EEPROM.put(addres_4, limit_4);
Serial.print(F("Kabinet +5 LIMIT = ")); Serial.println(limit_4);
}
if (c == 'd') {
limit_4 -= 5; EEPROM.put(addres_4, limit_4);
Serial.print(F("Kabinet -5 LIMIT = ")); Serial.println(limit_4);
}
//------ Запрос данных состояния датчиков MH-Z19B, DHT11 и лимитов -----
if (c == 'E') {
Serial.print(F("Gostinaya = ")); Serial.print(SensorPins[3][0]);
Serial.print(F(" LIMIT = ")); Serial.print(limit_1);
Serial.print(F(" ")); Serial.println(sost1);
Serial.print(F("Detskaya = ")); Serial.print(SensorPins[3][1]);
Serial.print(F(" LIMIT = ")); Serial.print(limit_2);
Serial.print(F(" ")); Serial.println(sost2);
Serial.print(F("Spalnya = ")); Serial.print(SensorPins[3][2]);
Serial.print(F(" LIMIT = ")); Serial.print(limit_3);
Serial.print(F(" ")); Serial.println(sost3);
Serial.print(F("Kabinet = ")); Serial.print(SensorPins[3][3]);
Serial.print(F(" LIMIT = ")); Serial.print(limit_4);
Serial.print(F(" ")); Serial.println(sost4);
Serial.print(F("Temperatura= ")); Serial.print(temperature_); Serial.println(F("*C"));
Serial.print(F("Vlagnoct = ")); Serial.print(humidity_); Serial.print(F("%"));
Serial.println(vannaya);
}
//------- Принудительное управление сервомоторами и сентилятором -------
if (c == 'F') {Serial.println(F("Gostinaya ON")); flag_1p = 1;}
if (c == 'f') {Serial.println(F("Gostinaya OFF")); flag_1p = 0;}
if (c == 'G') {Serial.println(F("Detskaya ON")); flag_2p = 1;}
if (c == 'g') {Serial.println(F("Detskaya OFF")); flag_2p = 0;}
if (c == 'H') {Serial.println(F("Spalnya ON")); flag_3p = 1;}
if (c == 'h') {Serial.println(F("Spalnya OFF")); flag_3p = 0;}
if (c == 'I') {Serial.println(F("Kabinet ON")); flag_4p = 1;}
if (c == 'i') {Serial.println(F("Kabinet OFF")); flag_4p = 0;}
}//Serial.available
//------ алгоритмы для автоматической работы по датчикам MH-Z19B -------
if(SensorPins[3][0] > limit_1 + 5){flag_1 = 1;}
if(SensorPins[3][0] < limit_1 - 5){flag_1 = 0;}
if(SensorPins[3][1] > limit_2 + 5){flag_2 = 1;}
if(SensorPins[3][1] < limit_2 - 5){flag_2 = 0;}
if(SensorPins[3][2] > limit_3 + 5){flag_3 = 1;}
if(SensorPins[3][2] < limit_3 - 5){flag_3 = 0;}
if(SensorPins[3][3] > limit_4 + 5){flag_4 = 1;}
if(SensorPins[3][3] < limit_4 - 5){flag_4 = 0;}
//------------- алгоритмы для включения сервомоторов -------------
if(flag_1 == 1 || flag_1p == 1){myservo_1.write(angle_open_1); sost1 = "ON";}
else{myservo_1.write(angle_close_1); sost1 = "OFF";}
if(flag_2 == 1 || flag_2p == 1){myservo_2.write(angle_open_2); sost2 = "ON";}
else{myservo_2.write(angle_close_2); sost2 = "OFF";}
if(flag_3 == 1 || flag_3p == 1){myservo_3.write(angle_open_3); sost3 = "ON";}
else{myservo_3.write(angle_close_3); sost3 = "OFF";}
if(flag_4 == 1 || flag_4p == 1){myservo_4.write(angle_open_4); sost4 = "ON";}
else{myservo_4.write(angle_close_4); sost4 = "OFF";}
//------------- алгоритмы для включения общего вентилятора -------------
if (flag_1 == 1 || flag_2 == 1 || flag_3 == 1 || flag_4 == 1){
flags_1234 = 1;}else{flags_1234 = 0;}
if (flag_1p == 1 || flag_2p == 1 || flag_3p == 1 || flag_4p == 1){
flags_1234p = 1;}else{flags_1234p = 0;}
if (flags_1234 == 1 || flags_1234p == 1){
digitalWrite(kuller_general, LOW);
}else{ digitalWrite(kuller_general, HIGH);}
}//void loop
//Конец скетча
После загрузки скетча на плату Arduino, соберите все как показано на этой схеме
После сборки убедитесь что все верно, и можно подключать питание.
Для управления прибором при помощи Android устройства необходимо настроить Bluetooth модуль HC-06, а также скачать и настроить приложение. Ссылка на информацию по данной теме появится здесь в ближайшее время!