ENIB 2020 : Ruche connectée : Différence entre versions
(→Photo du projet) |
(→l'enfumoire) |
||
(4 révisions intermédiaires par le même utilisateur non affichées) | |||
Ligne 152 : | Ligne 152 : | ||
=='''Code'''== | =='''Code'''== | ||
+ | ===La population de la ruche, la température et L'humidité=== | ||
<pre> | <pre> | ||
+ | #include "DHT.h" | ||
+ | #include "rgb_lcd.h" | ||
+ | #include <string.h> | ||
+ | |||
+ | #define DHTPIN 8 // broche ou l'on a branche le capteur | ||
+ | #define DHTTYPE DHT22 // DHT 22 (AM2302) | ||
+ | DHT dht(DHTPIN, DHTTYPE);//déclaration du capteur | ||
+ | |||
+ | |||
+ | //definition de l ecran lcd | ||
+ | |||
+ | rgb_lcd ecranRGB; | ||
+ | |||
+ | // pin leds | ||
+ | |||
+ | const int ledRouge = 6; | ||
+ | const int ledBleue = 7; | ||
+ | int laserPin = 13; | ||
+ | int photoR1= A0; | ||
+ | int photoR2=A1; | ||
+ | int result; | ||
+ | const int vcc = 5; | ||
+ | int score; | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | void setup() { | ||
+ | // put your setup code here, to run once: | ||
+ | pinMode(vcc, OUTPUT); | ||
+ | pinMode(ledRouge, OUTPUT); | ||
+ | pinMode(ledBleue, OUTPUT); | ||
+ | pinMode(photoR1, INPUT); | ||
+ | pinMode(photoR2, INPUT); | ||
+ | Serial.begin(9600); | ||
+ | dht.begin(); | ||
+ | ecranRGB.begin(16,2,0x00); | ||
+ | score=0; | ||
+ | } | ||
+ | |||
+ | void loop() { | ||
+ | // put your main code here, to run repeatedly: | ||
+ | digitalWrite(vcc, HIGH); | ||
+ | delay(2000); | ||
+ | float h = dht.readHumidity();//on lit l'hygrometrie | ||
+ | float t = dht.readTemperature();//on lit la temperature en celsius (par defaut) | ||
+ | |||
+ | //On verifie si la lecture a echoue, si oui on quitte la boucle pour recommencer. | ||
+ | if (isnan(t) || isnan(h)) | ||
+ | { | ||
+ | Serial.println("Failed to read from DHT sensor!"); | ||
+ | ecranRGB.clear(); | ||
+ | ecranRGB.setRGB(255,0,0); | ||
+ | ecranRGB.print("error !"); | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | |||
+ | // Calcul de l'indice de temperature en Celsius | ||
+ | float hic = dht.computeHeatIndex(t, h, false); | ||
+ | |||
+ | //Affichages : | ||
+ | Serial.print("Humidite: "); | ||
+ | Serial.print(h); | ||
+ | Serial.print(" %\t"); | ||
+ | Serial.print("Temperature: "); | ||
+ | Serial.print(t); | ||
+ | Serial.print(" *C "); | ||
+ | Serial.print("Indice de temperature: "); | ||
+ | Serial.print(hic); | ||
+ | Serial.print(" *C "); | ||
+ | Serial.print("\n"); | ||
+ | |||
+ | //Affichages sur l ecran LCD | ||
+ | |||
+ | if(t<25) | ||
+ | { | ||
+ | ecranRGB.setCursor(0, 0); | ||
+ | ecranRGB.clear(); | ||
+ | ecranRGB.setRGB(0,0,255); | ||
+ | ecranRGB.print("Temp : "); | ||
+ | ecranRGB.print(String(t)); // on nettoie l'ecran avant un nouvel affichage | ||
+ | ecranRGB.print(" deg"); | ||
+ | ecranRGB.setCursor(0, 2); | ||
+ | ecranRGB.print("Entrees: "); | ||
+ | ecranRGB.print(score); | ||
+ | digitalWrite(ledRouge,HIGH); | ||
+ | digitalWrite(ledBleue,LOW); | ||
+ | } | ||
+ | |||
+ | if(t>25) | ||
+ | { | ||
+ | ecranRGB.setCursor(0, 0); | ||
+ | ecranRGB.clear(); | ||
+ | ecranRGB.setRGB(255,0,0); | ||
+ | ecranRGB.print("Temp : "); | ||
+ | ecranRGB.print(String(t)); // on nettoie l'ecran avant un nouvel affichage | ||
+ | ecranRGB.print(" deg"); | ||
+ | ecranRGB.setCursor(0, 2); | ||
+ | ecranRGB.print("Entrees: "); | ||
+ | ecranRGB.print(score); | ||
+ | digitalWrite(ledRouge,LOW); | ||
+ | digitalWrite(ledBleue,HIGH); | ||
+ | } | ||
+ | int valeur1 = analogRead(photoR1); | ||
+ | int valeur2 = analogRead(photoR2); | ||
+ | Serial.println(valeur1); | ||
+ | |||
+ | if((valeur1>500)){ | ||
+ | ecranRGB.setCursor(0, 2); | ||
+ | score=score+1; | ||
+ | ecranRGB.print("Entrees: "); | ||
+ | ecranRGB.print(score); | ||
+ | Serial.println(valeur1); | ||
+ | }/* | ||
+ | if((valeur1<800)&&(valeur2>800)){ | ||
+ | ecranRGB.setCursor(0, 1); | ||
+ | ecranRGB.clear(); | ||
+ | result="ENTRE"; | ||
+ | ecranRGB.print(result); | ||
+ | delay(1000); | ||
+ | } | ||
+ | if((valeur2<800)&&(valeur1>800)){ | ||
+ | ecranRGB.setCursor(0, 1); | ||
+ | ecranRGB.clear(); | ||
+ | result="SORT"; | ||
+ | ecranRGB.print(result); | ||
+ | delay(1000); | ||
+ | } | ||
+ | else{ | ||
+ | ecranRGB.setCursor(0, 1); | ||
+ | ecranRGB.clear(); | ||
+ | result="RIEN"; | ||
+ | ecranRGB.print(result); | ||
+ | delay(1000); | ||
+ | }*/ | ||
+ | |||
+ | |||
+ | }//loop | ||
+ | |||
</pre> | </pre> | ||
− | === | + | ===l'enfumoire=== |
<pre> | <pre> | ||
− | + | //Code repris du site "https://www.instructables.com/id/Tutorial-of-MP3-TF-16P/" | |
+ | |||
+ | #include "Arduino.h" | ||
+ | #include "SoftwareSerial.h" | ||
+ | #include "DFRobotDFPlayerMini.h" | ||
+ | |||
+ | SoftwareSerial mySoftwareSerial(10, 11); // RX, TX | ||
+ | DFRobotDFPlayerMini myDFPlayer; | ||
+ | void printDetail(uint8_t type, int value); | ||
+ | const int buttonPin = 2; | ||
+ | int buttonState=0; | ||
+ | |||
+ | void setup() | ||
+ | { | ||
+ | mySoftwareSerial.begin(9600); | ||
+ | Serial.begin(115200); | ||
+ | |||
+ | Serial.println(); | ||
+ | Serial.println(F("DFRobot DFPlayer Mini Demo")); | ||
+ | Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)")); | ||
+ | |||
+ | if (!myDFPlayer.begin(mySoftwareSerial)) { //Use softwareSerial to communicate with mp3. | ||
+ | Serial.println(F("Unable to begin:")); | ||
+ | Serial.println(F("1.Please recheck the connection!")); | ||
+ | Serial.println(F("2.Please insert the SD card!")); | ||
+ | while(true); | ||
+ | } | ||
+ | Serial.println(F("DFPlayer Mini online.")); | ||
+ | |||
+ | |||
+ | myDFPlayer.volume(30); //Set volume value. From 0 to 30 | ||
+ | //Play the first mp3 | ||
+ | Serial.begin(9600); | ||
+ | pinMode(buttonPin, INPUT); | ||
+ | |||
+ | } | ||
+ | |||
+ | void loop() | ||
+ | { | ||
+ | buttonState = digitalRead(buttonPin); | ||
+ | Serial.println(buttonState); | ||
+ | if(buttonState){ | ||
+ | |||
+ | myDFPlayer.play(1); | ||
+ | static unsigned long timer = millis(); | ||
+ | |||
+ | |||
+ | |||
+ | if (myDFPlayer.available()) { | ||
+ | printDetail(myDFPlayer.readType(), myDFPlayer.read()); //Print the detail message from DFPlayer to handle different errors and states. | ||
+ | } | ||
− | + | } | |
− | + | ||
− | + | } | |
+ | void printDetail(uint8_t type, int value){ | ||
+ | switch (type) { | ||
+ | case TimeOut: | ||
+ | Serial.println(F("Time Out!")); | ||
+ | break; | ||
+ | case WrongStack: | ||
+ | Serial.println(F("Stack Wrong!")); | ||
+ | break; | ||
+ | case DFPlayerCardInserted: | ||
+ | Serial.println(F("Card Inserted!")); | ||
+ | break; | ||
+ | case DFPlayerCardRemoved: | ||
+ | Serial.println(F("Card Removed!")); | ||
+ | break; | ||
+ | case DFPlayerCardOnline: | ||
+ | Serial.println(F("Card Online!")); | ||
+ | break; | ||
+ | case DFPlayerPlayFinished: | ||
+ | Serial.print(F("Number:")); | ||
+ | Serial.print(value); | ||
+ | Serial.println(F(" Play Finished!")); | ||
+ | break; | ||
+ | case DFPlayerError: | ||
+ | Serial.print(F("DFPlayerError:")); | ||
+ | switch (value) { | ||
+ | case Busy: | ||
+ | Serial.println(F("Card not found")); | ||
+ | break; | ||
+ | case Sleeping: | ||
+ | Serial.println(F("Sleeping")); | ||
+ | break; | ||
+ | case SerialWrongStack: | ||
+ | Serial.println(F("Get Wrong Stack")); | ||
+ | break; | ||
+ | case CheckSumNotMatch: | ||
+ | Serial.println(F("Check Sum Not Match")); | ||
+ | break; | ||
+ | case FileIndexOut: | ||
+ | Serial.println(F("File Index Out of Bound")); | ||
+ | break; | ||
+ | case FileMismatch: | ||
+ | Serial.println(F("Cannot Find File")); | ||
+ | break; | ||
+ | case Advertise: | ||
+ | Serial.println(F("In Advertise")); | ||
+ | break; | ||
+ | default: | ||
+ | break; | ||
+ | } | ||
+ | break; | ||
+ | default: | ||
+ | break; | ||
+ | } | ||
− | + | } | |
− | |||
</pre> | </pre> | ||
− | |||
==='''Photo du projet'''=== | ==='''Photo du projet'''=== |
Version actuelle datée du 20 janvier 2020 à 18:06
Photo de l'équipe
Que fait ce projet ?
La ruche connectée est un ruche (surprenant) mais indiquant des données utiles à l'apiculteur. Cela permet alors une meilleur gestion de la ruche. Plusieurs données sont alors recueillies.
La température
Pendant l'hiver le froid pousse les abeilles à maintenir la température de la ruche à un certain niveau (à peu près 35 degrés). Pour maintenir cette température les abeilles se relayent à tour de rôle pour battre des ailes et ainsi réchauffer la ruche. Comme ces dernières sont actives, elles doivent se nourrir et donc consommer du miel. Les apiculteurs estiment que cette perte peut aller jusqu'à 20 kilogramme !!! En détectant la température avec un capteur on peut donc maintenir cette dernière artificiellement avec un chauffage et donc gagner des kilo de miel. A l'inverse si il fait trop chaud on déclenche un ventilateur pour aérer la ruche. Par souci de matériel on a symbolisé le chauffage par une led rouge et la ventilation par une led blanche.
L'humidité
Un facteur encore plus dangereux que le froid pour une ruche est l’humidité (normalement entre 60% et 85%). En effet si cette dernière est trop élevée les abeilles peuvent attraper des maladies. Du fait qu'elles soient littéralement les unes sur les autres si cette maladie est transmissible cela peut créer une épidémie dans la ruche. Le contrôle de humidité est donc indispensable. En détectant l’humidité avec un capteur on règle ce problème.
La population de la ruche
Il est intéressant de connaitre la population de la ruche. En effet une population qui viendrait à diminuer signifierait une perte d'abeille qui, si se poursuit, finirait par transformer la ruche en une ruche abandonnée. A l'inverse une population qui augmenterai trop se transformerait en une surpopulation dans la ruche et poserait donc un problème de place pour les abeilles. Pour surveiller la population de la ruche on va donc fixer au départ une population (ex:10 000 individus en hiver et 40 000 en individus en été). Selon les entrées ou les sorties des abeilles on enlève ou on ajoute au nombre fixé au départ ces allers-retours. Pour cela on fixe 2 lasers l'un derrière l'autre à l'entrée de la ruche pointant chacun sur une photo-résistance. Le laser 1 le plus à l'intérieur de la ruche et le laser 2 le plus à l'extérieur de la ruche. Lorsqu'une abeille passe entre entre le laser et la photorésistance le laser et coupé ce qui se traduit par une chute de tension au niveau de la photorésistance. Donc si on a une chute de tension au niveau du laser 1 puis du laser 2 l'abeille sort de la ruche (population -1). Inversement si on a une chute de tension au niveau du laser 2 puis du laser 1 l'abeille rentre dans la ruche (population +1).
l'enfumoire
L'apiculteur se sert de l'enfumoire pour récolter le miel. En effet contrairement aux idées reçues l'enfumoire n'endort pas les abeilles mais simule un incendie. Les abeilles se mettent alors en position de défense en se recroquevillants sur elles-même. Pour des raisons pratiques nous n'avons pas utilisés d'enfumoire mais on symbolise sont fonctionnement par une enceinte qui se déclenche par l'appui d'un bouton poussoir. En effet l'idée serait qu'en appuyant sur un bouton un enfumoire se déclenche, ici c'est une musique (youtube:MIEL POPS 2012) qui se déclenche.
Liste des composants
Carte Arduino 1
Nombre | type de pièce | Propriétés |
---|---|---|
1 |
Arduino Uno (Rev3) - ICSP |
type Arduino UNO (Rev3) - ICSP |
1 |
DFRobot DFPlayer Mini |
variante variant 1; numéro du composant DFR0299 |
1 |
1kΩ Resistor |
résistance 1kΩ; tolérance ±5%; boîtier 2512 [SMD] |
1 |
Round Pushbutton |
default state Normally Open; switching circuit SPST |
1 |
SPEAKER |
boîtier pcb_mount_speaker |
Carte Arduino 2
Nombre | type de pièce | Propriétés |
---|---|---|
1 |
Arduino Uno (Rev3) - ICSP |
type Arduino UNO (Rev3) - ICSP |
1 |
DHT22 Humidity and Temperature Sensor |
|
1 |
Grove OLED 128x96 |
variante variant 5; taille 1x2; interface I2C |
2 |
Laser |
variante variant 1; boîtier keys; numéro du composant 1219301 |
1 |
Red (660nm) LED |
couleur Red (660nm); boîtier 1206 [SMD] |
1 |
White (4500K) LED |
couleur White (4500K); boîtier 1206 [SMD] |
2 |
PHOTOCELL |
variante pth-kit; boîtier photocell-kit |
2 |
10kΩ Resistor |
résistance 10kΩ; tolérance ±5%; boîtier 1206 [SMD] |
1 |
4.7kΩ Resistor |
résistance 4.7kΩ; tolérance ±5%; boîtier 2512 [SMD] |
2 |
220Ω Resistor |
résistance 220Ω; tolérance ±5%; boîtier 2512 [SMD] |
Code
La population de la ruche, la température et L'humidité
#include "DHT.h" #include "rgb_lcd.h" #include <string.h> #define DHTPIN 8 // broche ou l'on a branche le capteur #define DHTTYPE DHT22 // DHT 22 (AM2302) DHT dht(DHTPIN, DHTTYPE);//déclaration du capteur //definition de l ecran lcd rgb_lcd ecranRGB; // pin leds const int ledRouge = 6; const int ledBleue = 7; int laserPin = 13; int photoR1= A0; int photoR2=A1; int result; const int vcc = 5; int score; void setup() { // put your setup code here, to run once: pinMode(vcc, OUTPUT); pinMode(ledRouge, OUTPUT); pinMode(ledBleue, OUTPUT); pinMode(photoR1, INPUT); pinMode(photoR2, INPUT); Serial.begin(9600); dht.begin(); ecranRGB.begin(16,2,0x00); score=0; } void loop() { // put your main code here, to run repeatedly: digitalWrite(vcc, HIGH); delay(2000); float h = dht.readHumidity();//on lit l'hygrometrie float t = dht.readTemperature();//on lit la temperature en celsius (par defaut) //On verifie si la lecture a echoue, si oui on quitte la boucle pour recommencer. if (isnan(t) || isnan(h)) { Serial.println("Failed to read from DHT sensor!"); ecranRGB.clear(); ecranRGB.setRGB(255,0,0); ecranRGB.print("error !"); return; } // Calcul de l'indice de temperature en Celsius float hic = dht.computeHeatIndex(t, h, false); //Affichages : Serial.print("Humidite: "); Serial.print(h); Serial.print(" %\t"); Serial.print("Temperature: "); Serial.print(t); Serial.print(" *C "); Serial.print("Indice de temperature: "); Serial.print(hic); Serial.print(" *C "); Serial.print("\n"); //Affichages sur l ecran LCD if(t<25) { ecranRGB.setCursor(0, 0); ecranRGB.clear(); ecranRGB.setRGB(0,0,255); ecranRGB.print("Temp : "); ecranRGB.print(String(t)); // on nettoie l'ecran avant un nouvel affichage ecranRGB.print(" deg"); ecranRGB.setCursor(0, 2); ecranRGB.print("Entrees: "); ecranRGB.print(score); digitalWrite(ledRouge,HIGH); digitalWrite(ledBleue,LOW); } if(t>25) { ecranRGB.setCursor(0, 0); ecranRGB.clear(); ecranRGB.setRGB(255,0,0); ecranRGB.print("Temp : "); ecranRGB.print(String(t)); // on nettoie l'ecran avant un nouvel affichage ecranRGB.print(" deg"); ecranRGB.setCursor(0, 2); ecranRGB.print("Entrees: "); ecranRGB.print(score); digitalWrite(ledRouge,LOW); digitalWrite(ledBleue,HIGH); } int valeur1 = analogRead(photoR1); int valeur2 = analogRead(photoR2); Serial.println(valeur1); if((valeur1>500)){ ecranRGB.setCursor(0, 2); score=score+1; ecranRGB.print("Entrees: "); ecranRGB.print(score); Serial.println(valeur1); }/* if((valeur1<800)&&(valeur2>800)){ ecranRGB.setCursor(0, 1); ecranRGB.clear(); result="ENTRE"; ecranRGB.print(result); delay(1000); } if((valeur2<800)&&(valeur1>800)){ ecranRGB.setCursor(0, 1); ecranRGB.clear(); result="SORT"; ecranRGB.print(result); delay(1000); } else{ ecranRGB.setCursor(0, 1); ecranRGB.clear(); result="RIEN"; ecranRGB.print(result); delay(1000); }*/ }//loop
l'enfumoire
//Code repris du site "https://www.instructables.com/id/Tutorial-of-MP3-TF-16P/" #include "Arduino.h" #include "SoftwareSerial.h" #include "DFRobotDFPlayerMini.h" SoftwareSerial mySoftwareSerial(10, 11); // RX, TX DFRobotDFPlayerMini myDFPlayer; void printDetail(uint8_t type, int value); const int buttonPin = 2; int buttonState=0; void setup() { mySoftwareSerial.begin(9600); Serial.begin(115200); Serial.println(); Serial.println(F("DFRobot DFPlayer Mini Demo")); Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)")); if (!myDFPlayer.begin(mySoftwareSerial)) { //Use softwareSerial to communicate with mp3. Serial.println(F("Unable to begin:")); Serial.println(F("1.Please recheck the connection!")); Serial.println(F("2.Please insert the SD card!")); while(true); } Serial.println(F("DFPlayer Mini online.")); myDFPlayer.volume(30); //Set volume value. From 0 to 30 //Play the first mp3 Serial.begin(9600); pinMode(buttonPin, INPUT); } void loop() { buttonState = digitalRead(buttonPin); Serial.println(buttonState); if(buttonState){ myDFPlayer.play(1); static unsigned long timer = millis(); if (myDFPlayer.available()) { printDetail(myDFPlayer.readType(), myDFPlayer.read()); //Print the detail message from DFPlayer to handle different errors and states. } } } void printDetail(uint8_t type, int value){ switch (type) { case TimeOut: Serial.println(F("Time Out!")); break; case WrongStack: Serial.println(F("Stack Wrong!")); break; case DFPlayerCardInserted: Serial.println(F("Card Inserted!")); break; case DFPlayerCardRemoved: Serial.println(F("Card Removed!")); break; case DFPlayerCardOnline: Serial.println(F("Card Online!")); break; case DFPlayerPlayFinished: Serial.print(F("Number:")); Serial.print(value); Serial.println(F(" Play Finished!")); break; case DFPlayerError: Serial.print(F("DFPlayerError:")); switch (value) { case Busy: Serial.println(F("Card not found")); break; case Sleeping: Serial.println(F("Sleeping")); break; case SerialWrongStack: Serial.println(F("Get Wrong Stack")); break; case CheckSumNotMatch: Serial.println(F("Check Sum Not Match")); break; case FileIndexOut: Serial.println(F("File Index Out of Bound")); break; case FileMismatch: Serial.println(F("Cannot Find File")); break; case Advertise: Serial.println(F("In Advertise")); break; default: break; } break; default: break; } }