Skip to content

Instantly share code, notes, and snippets.

@HorlogeSkynet
Last active November 21, 2016 19:57
Show Gist options
  • Save HorlogeSkynet/abfc05ee6a2c67c72afb9252a0422bd0 to your computer and use it in GitHub Desktop.
Save HorlogeSkynet/abfc05ee6a2c67c72afb9252a0422bd0 to your computer and use it in GitHub Desktop.
Two Arduino programs for GreenHouse system
#include "LCD4884.h"
//#include "Wire.h"
#include "Servo.h"
Servo servo;
//#include "Adafruit_BMP085.h"
//Adafruit_BMP085 bmp;
#define DEBOUNCE_MAX 15
#define DEBOUNCE_ON 10
#define DEBOUNCE_OFF 3
#define NUM_KEYS 5
#define NUM_MENU_ITEM 5 /* Valeurs Analogiques lues à la main [=1023 quand relaché]*/
#define LEFT_KEY 0 //842
#define CENTER_KEY 1 //143
#define DOWN_KEY 2 //0
#define RIGHT_KEY 3 //328
#define UP_KEY 4 //502
#define MENU_X 10
#define MENU_Y 1
unsigned int adc_key_val[NUM_KEYS] = {50, 200, 400, 600, 800};
boolean center_key = false;
byte button_count[NUM_KEYS];
byte button_status[NUM_KEYS];
byte button_flag[NUM_KEYS];
char menu_items[NUM_MENU_ITEM][12] = {"Temperature", "Humidite", /*"Pression",*/ "Luminosite", "Regl. Hygro", "Regl. Lum"};
void (*menu_funcs[NUM_MENU_ITEM])(void) = {temperature, humidite, /*pression,*/ luminosite, reglage_hygro, reglage_lum};
unsigned int luminosite_souhaitee = 0; //<-- en %
unsigned int humidite_souhaitee = 0; //<-- en %
float hygro = 0; //<-- On déclare Hygro en tant que variable globale
float temp = 0; //<-- On déclare Temp en tant que variable globale
unsigned long temps[4] = {0}; //<-- [0]: temps_op, [1]: temps_arrosage, [2]: temps_ecran, [3]: buttonFlasher
boolean arrosage = false;
boolean menuInit = false;
byte bGlobalErr;
byte dht_dat[5];
#define dht_dpin A1
#define photo_resistance A2
#define potentiometre A3
const int led_rouge = 10;
const int led_verte = 11;
const int led_bleue = 12;
const int electrovanne = 13; //<-- HIGH, relais collé électrovanne Ouverte; LOW, relais non-collé: électrovanne fermée.
#define ServoMoteur 9 //<-- Pin PWM
#define ServoFerme 0 //<-- Angle (en °)
#define ServoEntreOuvert1 10
#define ServoEntreOuvert2 20
#define ServoOuvert 30
unsigned int angle_servo;
int current_menu_item = 0;
const int max_menu_item = NUM_MENU_ITEM - 1;
const int min_menu_item = 0;
unsigned int nombreBoucleEcran = 0;
void setup()
{
Serial.begin(9600);
pinMode(electrovanne, OUTPUT);
pinMode(led_rouge, OUTPUT);
pinMode(led_verte, OUTPUT);
pinMode(led_bleue, OUTPUT);
digitalWrite(led_bleue, LOW);
digitalWrite(led_verte, LOW);
digitalWrite(led_rouge, LOW);
servo.attach(ServoMoteur); //<-- ServoMoteur sur la Pin déclarée plus haut.
Serial.println();
Serial.println("Interface Arduino / PC Initialise a 9600 bits par secondes. [1/8]");
delay(200);
InitDHT();
Serial.println("DHT11 KY015 Initialise. [2/8]");
delay(900);
lcd.LCD_init(); //<-- Initialisation Ecran
lcd.LCD_clear(); //<-- Nettoyage de l'écran
lcd.LCD_backlight(0); //<-- Off du rétro-éclairage
Serial.println("Ecran Initialise, Nettoye et Retro-eclairage eteint. [3/8]");
delay(250);
for(byte i = 0; i < NUM_KEYS; i++)
{
button_count[i] = 0;
button_status[i] = 0;
button_flag[i] = 0;
}
Serial.println("Tableau des boutons Initialise. [4/8]");
delay(150);
lcd.LCD_backlight(1);
reglage_hygro();
Serial.println("Reglage Hygrometrie pris en compte. [5/8]");
delay(500);
reglage_lum();
Serial.println("Reglage Luminosite pris en compte. [6/8]");
delay(500);
lcd.LCD_backlight(0);
init_MENU();
if(!menuInit)
{
digitalWrite(led_bleue, LOW);
Serial.println("Erreur fatale. Veuillez fixer l'erreur.");
lcd.LCD_clear();
lcd.LCD_write_string(0, 0, "Erreur menu !", MENU_NORMAL);
for(;;)
{
digitalWrite(led_verte, HIGH);
delay(100);
digitalWrite(led_verte, LOW);
delay(100);
}
}
delay(500);
//Test des LEDS\\
lcd.LCD_clear();
delay(500);
Serial.print("Leds: ");
lcd.LCD_write_string(0, 0, "Test LED.", MENU_NORMAL);
delay(1500);
lcd.LCD_clear();
digitalWrite(led_verte, HIGH);
Serial.print("verte, ");
lcd.LCD_write_string(0, 0, "Led Verte.", MENU_NORMAL);
delay(2000);
digitalWrite(led_verte, LOW);
lcd.LCD_clear();
digitalWrite(led_bleue, HIGH);
lcd.LCD_write_string(0, 0, "Led bleue.", MENU_NORMAL);
Serial.print("bleue, ");
delay(2000);
digitalWrite(led_bleue, LOW);
lcd.LCD_clear();
digitalWrite(led_rouge, HIGH);
lcd.LCD_write_string(0, 0, "Led Rouge.", MENU_NORMAL);
Serial.println("rouge. [7/8]");
delay(2000);
digitalWrite(led_rouge, LOW);
lcd.LCD_clear();
delay(400);
Serial.println("Menu initialise. [8/8]");
temps[0] = temps[1] = millis(); //<-- On initialise les minuteurs
servo.write(ServoOuvert); //<-- On ouvre complètement dès le lancement
op();
TCCR2A &= ~((1<<WGM21) | (1<<WGM20));
TCCR2B &= ~(1<<WGM22);
TCCR2B = (1<<CS22)|(1<<CS21);
ASSR |=(0<<AS2);
TCCR2A =0;
TIMSK2 |= (0<<OCIE2A);
TCNT2 = 0x6;
TIMSK2 = (1<<TOIE2);
SREG|=1<<SREG_I;
current_menu_item = 0;
init_MENU();
}
void loop()
{
digitalWrite(led_bleue, HIGH);
for(byte g = 0; g < NUM_KEYS; g++)
{
if(button_flag[g] != 0)
{
button_flag[g] = 0;
lcd.LCD_backlight(1);
temps[2] = millis();
switch(g)
{
case UP_KEY: //<-- On monte d'une ligne
lcd.LCD_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_NORMAL);
current_menu_item--;
if(current_menu_item < min_menu_item)
{
current_menu_item = max_menu_item;
}
lcd.LCD_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_HIGHLIGHT);
break;
case LEFT_KEY: //<-- On monte tout en-haut
lcd.LCD_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_NORMAL);
current_menu_item = min_menu_item;
lcd.LCD_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_HIGHLIGHT);
break;
case RIGHT_KEY: //<-- On descend tout en-bas
lcd.LCD_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_NORMAL);
current_menu_item = max_menu_item;
lcd.LCD_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_HIGHLIGHT);
break;
case DOWN_KEY: //<-- On descend d'une ligne
lcd.LCD_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_NORMAL);
current_menu_item++;
if(current_menu_item > max_menu_item)
{
current_menu_item = min_menu_item;
}
lcd.LCD_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_HIGHLIGHT);
break;
case CENTER_KEY: //<-- On exécute le choix sélectionné
lcd.LCD_clear();
(*menu_funcs[current_menu_item])();
lcd.LCD_clear();
delayMicroseconds(80);
//current_menu_item = 0; //<-- Pour éviter un surlignage au mauvais endroit, nécessite de revenir en-haut à chaque fois
init_MENU();
g = NUM_KEYS; //<-- On sort de la boucle actuelle
break;
default:
break;
}
}
}
nombreBoucleEcran++;
if(millis() - temps[3] > 5) //<-- ButtonFlasher
{
update_adc_key();
temps[3] = millis();
}
if((millis() - temps[2]) / 1000 > 10) //<-- Si l'écran n'a pas été touché depuis plus de 10 secondes
{
lcd.LCD_backlight(0);
}
if(((millis() - temps[0]) / 1000) > 60*5) //<-- On lance les opérations toutes les 5 min
{
Serial.println();
Serial.println("Lancement des operations.");
temps[0] = millis();
unsigned long temps_boucleOp = millis();
op();
temps_boucleOp = (millis() - temps_boucleOp) / 1000;
Serial.println();
Serial.print("Fin des operations. [en");
Serial.print(temps_boucleOp);
Serial.println("secondes]");
}
if(nombreBoucleEcran > 100000)
{
nombreBoucleEcran = 0;
digitalWrite(led_bleue, LOW);
delay(10);
digitalWrite(led_verte, HIGH);
delay(1500);
digitalWrite(led_verte, LOW);
delay(10);
}
}
void op()
{
delay(10);
digitalWrite(led_verte, LOW);
digitalWrite(led_bleue, LOW);
delay(10);
digitalWrite(led_rouge, HIGH);
// Lecture des données \\
/*Serial.println();
float temp = bmp.readTemperature();
Serial.print("Temperature BMP085: ");
Serial.print(temp);
Serial.println(" oC");
float pression = bmp.readPressure();
Serial.print("Pression BMP085: ");
Serial.print(pression);
Serial.println(" hPa");*/
u:
ReadDHT();
switch(bGlobalErr)
{
case 0:
Serial.println();
Serial.println("<< Informations du DHT11 KY015 lues. >>");
Serial.println();
delayMicroseconds(80);
Serial.print("Humidite actuelle: ");
Serial.print(dht_dat[0], DEC);
Serial.print(".");
Serial.print(dht_dat[1], DEC);
Serial.println(" %");
Serial.print("Temperature actuelle: ");
Serial.print(dht_dat[2], DEC);
Serial.print(".");
Serial.print(dht_dat[3], DEC);
Serial.println(" oC");
hygro = dht_dat[0];
temp = dht_dat[2];
break;
case 1:
case 2:
case 3:
default:
digitalWrite(led_rouge, LOW);
Serial.println();
Serial.print("Erreur fatale. Veuillez fixer l'erreur.");
lcd.LCD_clear();
lcd.LCD_write_string(0, 0, "Erreur DHT11.", MENU_NORMAL);
for(unsigned int y = 0; y < 10; y++)
{
digitalWrite(led_bleue, HIGH);
delay(100);
digitalWrite(led_bleue, LOW);
delay(100);
}
digitalWrite(led_rouge, HIGH);
goto u;
break;
}
delay(150);
float lum_percent = (100.00 * analogRead(photo_resistance)) / 900.00;
Serial.print("Luminosite: ");
Serial.print(lum_percent);
Serial.println(" %");
delay(150);
// Application des modifications [si nécessaire] \\
//Humidite\\
if(hygro < humidite_souhaitee && !arrosage)
{
digitalWrite(electrovanne, HIGH); //<-- Si le taux est inférieur, et que ça n'arrose pas déjà , on ouvre
arrosage = true;
}
else
{
digitalWrite(electrovanne, LOW); //<-- Sinon, on ferme
arrosage = false;
}
//Luminosite\\
o:
lum_percent = (100.00 * analogRead(photo_resistance)) / 900.00;
if(lum_percent > luminosite_souhaitee)
{
if(lum_percent > luminosite_souhaitee + 20)
{
servo.write(ServoFerme);
angle_servo = ServoFerme;
}
else
{
servo.write(ServoEntreOuvert2);
angle_servo = ServoEntreOuvert2;
}
}
else
{
if(lum_percent < luminosite_souhaitee - 10)
{
servo.write(ServoEntreOuvert1);
angle_servo = ServoEntreOuvert1;
}
else
{
servo.write(ServoOuvert);
angle_servo = ServoOuvert;
}
}
delay(1500);
if(servo.read() != angle_servo)
{
goto o;
}
lcd.LCD_clear();
//Arrosage\\
if(((millis() - temps[1]) / 1000) >= 60*60 && !arrosage) //s'il s'est écoulé 1 heure, ET que ça n'arrose pas déjà , on ouvre
{
temps[1] = millis();
digitalWrite(electrovanne, HIGH);
arrosage = true;
}
if((millis() - temps[1]) / 1000 >= 60*5 && arrosage) //s'il s'est écoulé 5 minutes, ET que ça arrose, on ferme
{
temps[1] = millis();
digitalWrite(electrovanne, LOW);
arrosage = false;
}
digitalWrite(led_rouge, LOW);
delay(500);
}
void temperature()
{
lcd.LCD_backlight(1);
lcd.LCD_clear();
delay(150);
lcd.LCD_write_string(38, 5, "OK", MENU_HIGHLIGHT);
Serial.print("Temperature: ");
Serial.print(temp);
Serial.println(" oC");
char tempX[2];
dtostrf(temp, 1, 1, tempX);
lcd.LCD_write_string(0, 0, "Temperature:", MENU_NORMAL);
lcd.LCD_write_string_big(15, 1, tempX, MENU_NORMAL);
lcd.LCD_write_string(55, 3, " oC", MENU_NORMAL);
waitfor_OKkey();
}
void humidite()
{
lcd.LCD_backlight(1);
lcd.LCD_clear();
delay(150);
lcd.LCD_write_string(38, 5, "OK", MENU_HIGHLIGHT);
Serial.print("Humidite: ");
Serial.print(hygro);
Serial.println(" %");
char hygroX[2];
dtostrf(hygro, 1, 0, hygroX);
lcd.LCD_write_string(5, 0, "Humidite:", MENU_NORMAL);
lcd.LCD_write_string_big(20, 1, hygroX, MENU_NORMAL);
lcd.LCD_write_string(45, 3, " %", MENU_NORMAL);
waitfor_OKkey();
}
/*void pression()
{
lcd.LCD_backlight(1);
lcd.LCD_clear();
delay(150);
lcd.LCD_write_string(38, 5, "OK", MENU_HIGHLIGHT);
float pression = bmp.readPressure();
Serial.print("Pression: ");
Serial.print(pression);
Serial.println(" hPa");
char pressionX[5];
dtostrf(pression,1,0,pressionX);
lcd.LCD_write_string(0, 0, "Pression:", MENU_NORMAL);
lcd.LCD_write_string_big(0, 1, pressionX, MENU_NORMAL);
lcd.LCD_write_string(58, 3, " hPa", MENU_NORMAL);
waitfor_OKkey();
}*/
void luminosite()
{
lcd.LCD_backlight(1);
lcd.LCD_clear();
delay(150);
lcd.LCD_write_string(38, 5, "OK", MENU_HIGHLIGHT);
float lum_percent = (100.00 * analogRead(photo_resistance)) / 900.00;
Serial.print("Luminosite: ");
Serial.print(lum_percent);
Serial.println(" %");
char lumX[2];
dtostrf(lum_percent, 1, 1, lumX);
lcd.LCD_write_string(0, 0, "Luminosite:", MENU_NORMAL);
lcd.LCD_write_string_big(10, 1, lumX , MENU_NORMAL);
lcd.LCD_write_string(50, 3, " %", MENU_NORMAL);
waitfor_OKkey();
}
void reglage_hygro()
{
lcd.LCD_clear();
lcd.LCD_backlight(1);
delay(150);
boolean poursuivre = false;
while(!poursuivre) //<-- Nécessite un appui long pour validé !
{
lcd.LCD_clear();
lcd.LCD_write_string(0, 0, "Regl.Humidite:", MENU_NORMAL);
lcd.LCD_write_string(38, 5, "OK", MENU_HIGHLIGHT);
float sensorValue = analogRead(potentiometre);
humidite_souhaitee = (80 * sensorValue) / 1023;
if(humidite_souhaitee < 40)
{
humidite_souhaitee = 40;
}
char humX[2];
dtostrf(humidite_souhaitee, 1, 0, humX);
lcd.LCD_write_string_big(20, 1, humX, MENU_NORMAL);
lcd.LCD_write_string(42, 3, " %", MENU_NORMAL);
if(analogRead(0) == 143)
{
poursuivre = true;
}
delay(500);
}
delay(100);
}
void reglage_lum()
{
lcd.LCD_clear();
lcd.LCD_backlight(1);
delay(500);
boolean poursuivre = false;
while(!poursuivre) //<-- Nécessite un appui long pour validé !
{
lcd.LCD_clear();
lcd.LCD_write_string(0, 0, "Regl. Lum.:", MENU_NORMAL);
lcd.LCD_write_string(38, 5, "OK", MENU_HIGHLIGHT);
char lumX[2];
float sensorValue = analogRead(potentiometre);
luminosite_souhaitee = (45 * sensorValue) / 1023;
if(luminosite_souhaitee < 10)
{
luminosite_souhaitee = 10;
}
dtostrf(luminosite_souhaitee, 1, 0, lumX);
lcd.LCD_write_string_big(10, 1, lumX, MENU_NORMAL);
lcd.LCD_write_string(42, 3, " %", MENU_NORMAL);
if(analogRead(0) == 143)
{
poursuivre = true;
}
delay(500);
}
}
void init_MENU()
{
lcd.LCD_clear();
lcd.LCD_write_string(19, 0, "MENU OSE", MENU_NORMAL);
for(byte i = 0; i < NUM_MENU_ITEM; i++)
{
lcd.LCD_write_string(MENU_X, MENU_Y + i, menu_items[i], MENU_NORMAL);
}
delayMicroseconds(80);
lcd.LCD_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_HIGHLIGHT);
delayMicroseconds(80);
menuInit = true;
}
void waitfor_OKkey()
{
byte key = 0xFF;
update_adc_key();
while(key != CENTER_KEY) //<-- Boucle infinie tant que l'on ne presse pas OK (c'est la Pause)
{
for(byte i = 0; i < NUM_KEYS; i++)
{
if(button_flag[i] != 0)
{
button_flag[i] = 0;
if(i == CENTER_KEY)
{
key = CENTER_KEY;
}
}
update_adc_key();
}
}
}
void update_adc_key()
{
int adc_key_in;
char key_in;
adc_key_in = analogRead(0);
key_in = get_key(adc_key_in);
for(byte i = 0; i < NUM_KEYS; i++)
{
if(key_in == i)
{
if(button_count[i] < DEBOUNCE_MAX)
{
button_count[i]++;
if(button_count[i] > DEBOUNCE_ON)
{
if(button_status[i] == 0)
{
button_flag[i] = 1;
button_status[i] = 1;
}
}
}
}
else
{
if (button_count[i] > 0)
{
button_flag[i] = 0;
button_count[i]--;
if(button_count[i] < DEBOUNCE_OFF)
{
button_status[i] = 0;
}
}
}
}
}
char get_key(unsigned int input)
{
char k;
for(k = 0; k < NUM_KEYS; k++)
{
if(input < adc_key_val[k])
{
return k;
}
}
if(k >= NUM_KEYS)
{
k = -1;
return k;
}
}
void InitDHT()
{
pinMode(dht_dpin, OUTPUT);
digitalWrite(dht_dpin, HIGH);
}
void ReadDHT()
{
bGlobalErr = 0;
digitalWrite(dht_dpin, LOW);
delay(20);
digitalWrite(dht_dpin, HIGH);
delayMicroseconds(40);
pinMode(dht_dpin, INPUT);
delayMicroseconds(40);
byte dht_in;
dht_in = digitalRead(dht_dpin);
if(dht_in)
{
bGlobalErr = 1;
return;
}
delayMicroseconds(80);
dht_in = digitalRead(dht_dpin);
if(!dht_in)
{
bGlobalErr = 2;
return;
}
delayMicroseconds(80);
for(unsigned int p = 0; p < 5; p++)
{
dht_dat[p] = read_dht_dat();
}
pinMode(dht_dpin, OUTPUT);
digitalWrite(dht_dpin, HIGH);
byte dht_check_sum;
dht_check_sum = dht_dat[0] + dht_dat[1] + dht_dat[2] + dht_dat[3];
if(dht_dat[4] != dht_check_sum)
{
bGlobalErr = 3;
}
}
byte read_dht_dat()
{
byte result = 0;
for(unsigned int u = 0; u < 8; u++)
{
while(digitalRead(dht_dpin) == LOW)
{}
delayMicroseconds(30);
if(digitalRead(dht_dpin) == HIGH)
{
result |=(1<<(7-u));
}
while(digitalRead(dht_dpin) == HIGH)
{}
}
return result;
}
ISR (TIMER2_OVF_vect)
{
TCNT2 = 6;
update_adc_key();
}
/*
// Diagnostic LED\\
LED_Bleue:
fixe --> Arduino en train de gérer le Menu de l'écran
clignotante --> Problème au niveau du DHT11 KY015
//LED_Rouge:
//fixe --> Arduino en train d'effectuer les opérations
//clinotante --> Problème au niveau du BMP085
LED_Verte:
fixe --> Arduino inactive
clignotante --> Problème au niveau du Menu
LED éteinte --> Arduino non-alimentée OU en cours de lancement
*/
#define seuil_feu 940 //Avec une Résistance de 10kOhms
#define flame_sensor A2
const int ventilateur = 1;
const int electrovanne = 3;
const int hp = 8;
boolean ancien_etat = false; //<-- Par défaut, il n'y avait pas le feu
boolean etat_ventilateur = false; //<-- True = Allumé, False = éteint
unsigned long temps_marche, temps_pause;
void setup()
{
Serial.begin(9600);
pinMode(ventilateur, OUTPUT);
digitalWrite(ventilateur, HIGH); //<-- On lance la ventilation dès l'allumage
etat_ventilateur = true;
temps_marche = millis();
}
void loop()
{
if(!ancien_etat) //<-- Si le feu s'est arrêté...
{
digitalWrite(ventilateur, HIGH);
etat_ventilateur = true;
temps_marche = millis();
ancien_etat = true;
}
Serial.print("Sensor Value: ");
Serial.println(analogRead(flame_sensor));
Serial.println();
if(analogRead(flame_sensor) >= seuil_feu)
{
ancien_etat = true;
digitalWrite(ventilateur, LOW); //<-- S'il y a le feu, par mesure de sécurité, on coupe la ventilation
digitalWrite(electrovanne, HIGH); //<-- On ouvre l'électrovanne
etat_ventilateur = false;
temps_pause = millis();
Serial.println("Il y a le feu !");
while(analogRead(flame_sensor) >= seuil_feu)
{
for(int i = 500; i < 1000; i += 4)
{
tone(hp, i, 1000);
delay(10);
if(i >= 1000)
{
i = 500;
}
}
}
}
else //<-- Sinon, on ne fait rien...
{
ancien_etat = false;
}
// Régulation automatique de la ventilation \\
if((temps_marche - millis()) / 1000 > 60*60*1 && etat_ventilateur) //<-- Arrêt toutes les heures, avec pause de 5 minutes
{
temps_pause = millis();
digitalWrite(ventilateur, LOW);
etat_ventilateur = false;
}
if(((temps_pause - millis()) / 1000) > 60*5 && !etat_ventilateur)
{
temps_marche = millis();
digitalWrite(ventilateur, HIGH);
etat_ventilateur = true;
}
delay(5000);
}
/*
// Diagnostic \\
Buzzer:
éteint --> Tout se passe correctement
Alarme à fréquence variable --> Feu
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment