Создание GrowBox на базе Arduino Mega 2560 & Lcd Shield с полним меню настройки
- Войдите на сайт для отправки комментариев
Втр, 14/06/2016 - 07:07
#include <EEPROM.h>
#include <Wire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <BH1750.h>
#include <LiquidCrystal.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "DHT.h"
#include <avr/wdt.h>
#define DHTTYPE DHT11 // DHT 11
#define DHTPIN 18 // к какому пину будет подключен вывод Data
#define ONE_WIRE_BUS 24 // пин для дс18б20 ( one wire)
DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal lcd (8,9,4,5,6,7); // пини подключения перепутани с завода китайцами на шилде
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
////////////////////////////// адреса каждого 18б20 ( посмотреть можно запрограмировав пример файл-примери-dallasTemperature-Multiple)
DeviceAddress Thermometer2 = { //у мене для першого термомет.- 28FF5A620216031C
0x28, 0xFF, 0x5A, 0x62, 0x02, 0x16, 0x03, 0x1C };
DeviceAddress Thermometer1 = { //для другого термомет без корпуса.-28FF937B231604DA
0x28, 0xFF, 0x93, 0x7B, 0x23, 0x16, 0x04, 0xDA };
////////////////переменные для меню, которые сохраняем в енергонезависимую память
int plase=0;
int TempMin;
int T0=1;
int T01=50;
int TempMax;
int HumAirMin;
int HumAirMax;
int SoilHumMin;
int SoilHumMax;
int Hour;
int Minute;
int Second;
int TimeToOn;
int TimeToOff;
int invSensor1;
int Lux;
/////////
BH1750 lightMeter; //Conection pins SDA-A4 SCL-A5 VCC= +3.5V */
int Sensor1= 7; // датчик влажности грунта
int litening= 41; // пин для доосветки
int heating = 43; // подогрев при минимальной температуре ( нагревательний елемент дуйки или обогревателя)
int watering = 45; // полив грунта
int humidification =52; // пин для увлажнения воздуха
int cooling =48; // пин для проветревального куллера
int cooling2 =46; // пин для проветревального куллера
int FanFromHeating = 42; // пин для подключения нижнего вентилятора ( в моём случае стоит обогревательная дуйка и её куллер работает независимо от нагревательного елемента )
int FanFromHeating2 = 44; // пин для подключения нижнего вентилятора ( от дуйки для продувки бокса свежим воздухом)
/* float tempMin = 25; // температура для начала обогрева
float tempMax = 26; // температура для включения нижнего и верхнего вентеляторов на проветривание
int soil_moistureMIN = 55 ;// минимальная граница включения полива грунта ( вкл. полив)
int soil_moistureMID = 60 ;// максимальная граница влажности грунта для виключения полива (викл. полив)
*/
int ComboHumidity ; // (влажность психрометра+влажность DHT11)/2
float T ; // переменная для регулирования температури
float h; // переменная для влажности воздуха по DHT11
double fi; // переменная для влажности воздуха согласно потенцыометру ( влажний и сухой термометри )
float tempC1; // температура первого датчика DS18B20
float tempC2; // температура второго DS18B20
//// //перезагрузка ардуино
void(* resetFunc) (void) = 0; // перезагрузка мк ( не полная ) для нормальной роботи DS18B20
unsigned long time;
byte gradus [8] = { // вручную дописаний значок каторий обозначает градус цельсия ( маленький кружок вверху, перед С)
B00100,
B01010,
B01010,
B00100,
B00000,
B00000,
B00000,
B00000,
};
byte KEY(){ //// для кнопок ЛСДшилда
int val = analogRead(0);
if (val < 50) return 5;
else if ((val>130) & (val < 140)) return 4;
else if ((val>300)& (val < 320)) return 3;
else if ((val>480)& (val < 500)) return 2;
else if ((val >700)& (val < 730)) return 1;
else return 0;
}
void setup()
{
wdt_enable (WDTO_4S); // устанавливаем таймер Arduino watchdog или автоматический RESET на срабативание после 4-х секунд,
// после того как в конце void loop не визовется функцыя wdt_reset();( тоесть после не полного срабативания цыкла МК принудительно перезагрузится)
sensors.begin();
sensors.setResolution(Thermometer1, 10);
sensors.setResolution(Thermometer2, 10);
////////////////////дисплей
TempMin = EEPROM.read(1);
TempMax = EEPROM.read(2);
HumAirMin=EEPROM.read(3);
HumAirMax=EEPROM.read(4);
SoilHumMin=EEPROM.read(5);
SoilHumMax=EEPROM.read(6);
TimeToOn=EEPROM.read(7);
TimeToOff=EEPROM.read(8);
lcd.createChar (1,gradus);
lcd.begin(16, 2);
analogWrite (10,80); // делаем подсветку менее яркой с помощью ШИМ ( от 0>255)
/////////////////////////////////////////
pinMode(FanFromHeating, OUTPUT);
pinMode ( heating , OUTPUT );
pinMode ( litening, OUTPUT);
pinMode ( watering, OUTPUT);
pinMode (cooling, OUTPUT);
pinMode (cooling2, OUTPUT);
pinMode (humidification, OUTPUT);
/// психрометр
//////////////
Serial.begin(9600);
lightMeter.begin();
Serial.println("Running...");
while (!Serial) ; // wait for serial
delay(10);
}
void loop()
{ /// меню для дисплея
if (plase == 0){ // если в первой позиции
lcd.clear();
lcd.setCursor(0,0); lcd.write("T=");
lcd.setCursor(7,0); lcd.write((byte)1);
lcd.setCursor(8,0); lcd.write("C");
lcd.setCursor(9,0); lcd.write("H=");
lcd.setCursor(15,0); lcd.write("%");
lcd.setCursor(0,1); lcd.write("S.H=");
lcd.setCursor(6,1); lcd.write("%");
lcd.setCursor(8,1); lcd.write("Lx=");
lcd.setCursor ( 2, 0) ; lcd.print (sensors.getTempC(Thermometer1));
lcd.setCursor ( 4,1); lcd.print (invSensor1);
lcd.setCursor ( 11,2); lcd.print ( Lux) ;
lcd.setCursor (11, 0 ); lcd.print ( h );
}
if ((KEY()==2)& (plase==1)) {resetFunc(); }
// задаём температуру воздуха используя меню дисплея
if (KEY()==1 ){
lcd.clear () ;
plase=1;
lcd.setCursor ( 3,0 );
lcd.print ("Set" );
lcd.setCursor ( 0,1 );
lcd.print ("Temperature" );
delay ( 300);}
if ((KEY()==5)& (plase==1) ){
lcd.clear () ;
plase=11;
lcd.print ("TempMin=" );
delay ( 300);}
if ((KEY()==5)& (plase==11) ){
lcd.clear () ;
lcd.print ("TempMin++" );
plase=21; }
if ((KEY()==4)& (plase==21) ){
lcd.clear () ;
lcd.print ("TempMin++" );
TempMin++; EEPROM.write(1, TempMin);
lcd.setCursor (0,1); lcd.print (EEPROM.read(1));
delay (200);}
if ((KEY()==3)& (plase==21) ){
lcd.clear () ;
lcd.print ("TempMin--" );
TempMin--; EEPROM.write(1, TempMin);
lcd.setCursor (0,1); lcd.print (EEPROM.read(1));
delay(200);}
if ((KEY()==3)& (plase==11) ){
lcd.clear () ;
plase=12;
lcd.print ("TempMax=" );
delay ( 300);}
if ((KEY()==5)& (plase==12) ){
lcd.clear () ;
lcd.print ("TempMax++" );
plase=22; }
if ((KEY()==4)& (plase==22) ){
lcd.clear () ;
lcd.print ("TempMax++" );
TempMax++; EEPROM.write(2, TempMax);
lcd.setCursor (0,1); lcd.print (EEPROM.read(2));
delay (200);}
if ((KEY()==3)& (plase==22) ){
lcd.clear () ;
lcd.print ("TempMax--" );
TempMax--; EEPROM.write(2, TempMax);
lcd.setCursor (0,1); lcd.print (EEPROM.read(2));
delay(200);}
//задаём влажность воздуха
if ((KEY()==3) & (plase==1 )){
lcd.clear () ;
plase=2;
lcd.setCursor ( 4,0 );
lcd.print ("Set" );
lcd.setCursor ( 0,1 );
lcd.print ("AirHumidity" );
delay ( 300);
}
if ((KEY()==5)& (plase==2) ){
lcd.clear () ;
plase=23;
lcd.print ("HumAirMin=" );
delay ( 300); lcd.setCursor (0, 1 ); lcd.print ( fi );
lcd.setCursor (13, 1 ); lcd.print ( h );}
if ((KEY()==5)& (plase==23) ){
lcd.clear () ;
lcd.print ("HumAirMin++" );
plase=33;
}
if ((KEY()==4)& (plase==33) ){
lcd.clear () ;
lcd.print ("HumAirMin++" );
HumAirMin++; EEPROM.write(3, HumAirMin);
lcd.setCursor (0,1); lcd.print (EEPROM.read(3));
lcd.setCursor (2,1); lcd.print ("%");
delay (10);}
if ((KEY()==3)& (plase==33) ){
lcd.clear () ;
lcd.print ("HumAirMin--" );
HumAirMin--; EEPROM.write(3, HumAirMin);
lcd.setCursor (0,1); lcd.print (EEPROM.read(3));
lcd.setCursor (2,1); lcd.print ("%");
delay(10);}
if ((KEY()==3)& (plase==23) ){
lcd.clear () ;
plase=24;
lcd.print ("HumAirMax=" );
delay ( 300);}
if ((KEY()==5)& (plase==24) ){
lcd.clear () ;
lcd.print ("HumAirMax++" );
plase=34; }
if ((KEY()==4)& (plase==34) ){
lcd.clear () ;
lcd.print ("HumAirMax++" );
HumAirMax++; EEPROM.write(4, HumAirMax);
lcd.setCursor (0,1); lcd.print (EEPROM.read(4));
lcd.setCursor (2,1); lcd.print ("%");
delay (10);}
if ((KEY()==3)& (plase==34) ){
lcd.clear () ;
lcd.print ("HumAirMax--" );
HumAirMax--; EEPROM.write(4, HumAirMax);
lcd.setCursor (0,1); lcd.print (EEPROM.read(4));
lcd.setCursor (2,1); lcd.print ("%");
delay(10);}
// задаём влажность почвы
if ((KEY()==3) & (plase==2 )){
lcd.clear () ;
plase=3;
lcd.setCursor ( 4,0 );
lcd.print ("Set" );
lcd.setCursor ( 0,1 );
lcd.print ("SoilHumidity" );
delay ( 300);
}
if ((KEY()==5)& (plase==3) ){
lcd.clear () ;
plase=35;
lcd.print ("SoilHumMin=" );
delay ( 300);}
if ((KEY()==5)& (plase==35) ){
lcd.clear () ;
lcd.print ("SoilHumMin++" );
plase=36; }
if ((KEY()==4)& (plase==36) ){
lcd.clear () ;
lcd.print ("SoilHumMin++" );
SoilHumMin++; EEPROM.write(5, SoilHumMin);
lcd.setCursor (0,1); lcd.print (EEPROM.read(5));
lcd.setCursor (2,1); lcd.print ("%");
delay (10);}
if ((KEY()==3)& (plase==36) ){
lcd.clear () ;
lcd.print ("SoilHumMin--" );
SoilHumMin--; EEPROM.write(5, SoilHumMin);
lcd.setCursor (0,1); lcd.print (EEPROM.read(5));
lcd.setCursor (2,1); lcd.print ("%");
delay(10);}
if ((KEY()==3)& (plase==35) ){
lcd.clear () ;
plase=37;
lcd.print ("SoilHumMax=" );
delay ( 300);}
if ((KEY()==5)& (plase==37) ){
lcd.clear () ;
lcd.print ("SoilHumMax++" );
plase=38; }
if ((KEY()==4)& (plase==38) ){
lcd.clear () ;
lcd.print ("SoilHumMax++" );
SoilHumMax++; EEPROM.write(6, SoilHumMax);
lcd.setCursor (0,1); lcd.print (EEPROM.read(6));
lcd.setCursor (2,1); lcd.print ("%");
delay (10);}
if ((KEY()==3)& (plase==38) ){
lcd.clear () ;
lcd.print ("SoilHumMax--" );
SoilHumMax--; EEPROM.write(6, SoilHumMax);
lcd.setCursor (0,1); lcd.print (EEPROM.read(6));
lcd.setCursor (2,1); lcd.print ("%");
delay(10);}
//смотрим время и устанавливаем время включения и выключения доосвечевания
if ((KEY()==3) & (plase==3 )){
lcd.clear () ;
plase=4;
lcd.print ("Time:" );
delay ( 300);
lcd.setCursor (5,0); lcd.print (Hour);
lcd.setCursor (7,0); lcd.print (":");
lcd.setCursor (8,0); lcd.print (Minute);
lcd.setCursor (10,0); lcd.print (":");
lcd.setCursor (11,0); lcd.print (Second);
}
if ((KEY()==5) & (plase==4 )){
lcd.clear();
plase=45;
lcd.print ("Set Time For ");
lcd.setCursor (0,1); lcd.print ("litening onn/off");
delay(300);
}
if ((KEY()==5) & (plase==45)){
lcd.clear();
lcd.setCursor (0,0); lcd.print ("Hour to tern On");
plase=55;
delay(300);
}
if ((KEY()==5)& (plase==55) ){
lcd.clear () ;
lcd.print ("Set Time to On" );
plase=65;
delay(10);
}
if ((KEY()==4)& (plase==65))
{ lcd.clear ();
TimeToOn++; EEPROM.write(7, TimeToOn);
lcd.print ("Set Time to On" );
lcd.setCursor (6,1); lcd.print (EEPROM.read(7));
lcd.setCursor (0,1); lcd.print ("++Hour");
delay (10);
}
if ((KEY()==3)& (plase==65) ){
lcd.clear () ;
lcd.print ("Set Time to On" );
TimeToOn--; EEPROM.write(7, TimeToOn);
lcd.setCursor (6,1); lcd.print (EEPROM.read(7));
lcd.setCursor (0,1);lcd.print ("--Hour" );
delay(10);}
if ((KEY()==3) & (plase==55)){
lcd.clear();
lcd.setCursor (0,0); lcd.print ("Hour to tern Off");
plase=66; }
delay(300);
if ((KEY()==5)& (plase==66) ){
lcd.clear () ;
lcd.print ("Set Time to OFF" );
plase=67;
delay(300);
}
if ((KEY()==4)& (plase==67))
{ lcd.clear ();
TimeToOff++; EEPROM.write(8, TimeToOff);
lcd.print ("Set Time to Off" );
lcd.setCursor (6,1); lcd.print (EEPROM.read(8));
lcd.setCursor (0,1); lcd.print ("++Hour");
delay (10);
}
if ((KEY()==3)& (plase==67) ){
lcd.clear () ;
lcd.print ("Set Time to Off" );
TimeToOff--; EEPROM.write(8, TimeToOff);
lcd.setCursor (6,1); lcd.print (EEPROM.read(8));
lcd.setCursor (0,1);lcd.print ("--Hour" );
delay(10);}
// перезагрузка ардуино каждые 60 сек//////////////////////////////////////////////////
time = millis();
if (time > 60000) {resetFunc();}
//датчик освещения BH1750 /////////////////////////////////////////////////
uint16_t lux = lightMeter.readLightLevel();
Lux= lux;
Serial.print("_Light: ");
Serial.print(lux);
Serial.println(" lx");
////////////////////////
// ds18b20 + регулирование температурой
sensors.requestTemperatures(); // Send the command to get temperatur
float tempC1 = sensors.getTempC(Thermometer1);
float tempC2 = sensors.getTempC(Thermometer2);
int T=(sensors.getTempC(Thermometer1));
if ((T >= (EEPROM.read(2)))& (T > T0)&(T<T01))
{ digitalWrite (FanFromHeating , HIGH);
digitalWrite ( heating , LOW);
digitalWrite ( cooling , HIGH);
}
else if (( T>T0 )&( T>=(EEPROM.read(1))) & ( T<(EEPROM.read(2))) &(T<T01))
{
digitalWrite (FanFromHeating , LOW);
digitalWrite ( cooling , LOW);
digitalWrite ( heating , LOW);
}
else if (( T <(EEPROM.read(1)))& (T>T0) &(T<T01))
{
digitalWrite (FanFromHeating ,LOW);
digitalWrite ( heating , HIGH);
digitalWrite ( cooling , LOW);
}
Serial.print("Sensor1 ");
Serial.println(tempC1);
Serial.print("Sensor2 ");
Serial.println(tempC2);
//Пихрометр
float delta = (tempC1-tempC2);
if (delta<=0) {fi=100.00;}
else {fi=pow(100.00, (1.00-(0.006+((pow((120.00-(float)tempC1), 1.46))/100000))*pow(((float)tempC1-(float)tempC2), (1.074+((pow((146.00-(float)tempC1), 7.77))/100000000000000000)))));}
Serial.print("HumidityPotensiometr:");
Serial.print(fi);
/////////////////////////////////////////////////// датчик влажности грунта( самодельный , аналоговый )
int Sensor1 = analogRead(7);
invSensor1 = map(Sensor1, 0,1024, 0, 100);
if(invSensor1 <= (EEPROM.read(5)))
{digitalWrite(watering , HIGH ); }
if ((invSensor1 >= (EEPROM.read(6)))& ( invSensor1 > (EEPROM.read(5))))
{digitalWrite (watering , LOW ); }
Serial.print("Soil moisture:");
Serial.print(invSensor1);
Serial.println("%");
Serial.println("----------------------");
//DHT11
h = dht.readHumidity();
Serial.print("Humidity_DHT");
Serial.print(h);
if ( h< EEPROM.read(3)) { digitalWrite (humidification, HIGH); }
else if ((h>= EEPROM.read(3)) & (h<=EEPROM.read(4))){digitalWrite (humidification, LOW);}
else if ( h> EEPROM.read(4)) { digitalWrite (humidification, LOW); }
else { digitalWrite (humidification, LOW);}
ComboHumidity = ((fi+h)/2);
//часы реального времени DS1307 + включение и выключение доосветки + включение принудительного вентилирования по времени
tmElements_t tm;
delay(10);
if (RTC.read(tm))
{ Serial.print("_Time = ");
delay(1);
print2digits(tm.Hour);
delay(10);
Hour=(tm.Hour);
Serial.write(':');
delay(1);
print2digits(tm.Minute);
delay(1);
Minute=(tm.Minute);
Serial.write(':');
print2digits(tm.Second);
delay(1);
Second= (tm.Second);
//// Включение доосветки задаём с помощю кнопок на лсд шилде и нашего меню , читаем данные с енергонезависимой памяти
if (( tm.Hour >= TimeToOn) && ( tm.Hour <TimeToOff)) { digitalWrite ( litening , HIGH) ;}
else {digitalWrite ( litening , LOW) ;}
}
//принудительное вентилирование
if (( tm.Minute >= 1) && ( tm.Minute <2)) {digitalWrite ( cooling2 , HIGH);digitalWrite (FanFromHeating2 , HIGH);}
else if (( tm.Minute >= 11) && ( tm.Minute <13)) {digitalWrite ( cooling2 , HIGH);digitalWrite (FanFromHeating2 , HIGH);}
else if (( tm.Minute >= 21) && ( tm.Minute <23)) {digitalWrite ( cooling2 , HIGH);digitalWrite (FanFromHeating2 , HIGH);}
else if (( tm.Minute >= 31) && ( tm.Minute <33)){digitalWrite ( cooling2 , HIGH);digitalWrite (FanFromHeating2 , HIGH);}
else if (( tm.Minute >= 41) && ( tm.Minute <43)){digitalWrite ( cooling2 , HIGH);digitalWrite (FanFromHeating2 , HIGH);}
else if (( tm.Minute >= 51) && ( tm.Minute <53)){digitalWrite ( cooling2 , HIGH);digitalWrite (FanFromHeating2 , HIGH);}
else {digitalWrite ( cooling2 , LOW );digitalWrite (FanFromHeating2 , LOW); }delay (10);
}
void print2digits(int number) {
if (number >= 0 && number < 10) {Serial.write('0'); }
Serial.print(number);
delay ( 10) ;
wdt_reset(); // при визове етой функции таймер Arduino watchdog, или автоматический RESET, обнуляется и ресет не проводится
}
Что это за бред ?
Это исходник какого-то "МЕГО-термо-влаго-анализатора-авто-поливщика" на супер дисплее 1602, для парничка на веранде, который чел, рискуя всем на свете, отважно похитил из секретной лаборатории NASA и выложил в открытый доступ для всеобщего блага!
Здравствуйте Znatok!
Очень заинтересовал Ваш проект управления климатом в боксе. Есть нсколько вопросов. Как с Вами можно связаться?
Особенно впечатлило
ссылка на него
https://www.youtube.com/watch?v=cOMNPxSO3fY