Station météo Arduino – 2
C’est parti pour la suite du projet! Je ne pense pas que copier coller tout le code soit une bonne idée, alors je vais vous le détailler bout à bout, puis vous donnerai un lien pour télécharger le fichier avec le code complet à la fin de l’article.
Explications algorithmiques
Alors tout d’abord voici quelques explications concernant les méthodes utilisées pour coder les fonctionnalités:
- Obsolète (voir annexes)
: Historique des données: Il semblait risqué d’écrire sur la carte SD chaque donnée lue en temps réel. Nous avons donc décidé de passer par des tableaux intermédiaires. Une fois remplies la totalité des tableaux seront écris dans un fichier texte sur la carte SD. De plus le capteur se met à jour une fois toutes les deux secondes, donc pour ne pas remplir les tableaux de valeurs inutiles nous remplissons une case toutes les deux secondes. D’où la tempo. - Le ventilateur (moteur à courant continu) est branché directement sur le motor shield. Donc pas besoin de monter un pont en H ou de transistor. Par contre, chose assez troublante, la carte utilise d’emblé les pins 3, 9 et 12 pour un éventuel moteur branché sur la voie A. Il ne faut donc rien brancher sur ces pins là, et les utiliser comme si le moteur y était relié.
- La station aura deux modes de fonctionnement: celui par defaut est l’affichage des données, tandis que lorsqu’on appuiera sur le bouton, l’écran affichera les seuils et le potentiomètre deviendra actif (pour régler les seuils). Chaque pression sur le bouton permettra de passer au seuil suivant, puis de repasser en mode normal.
Les libraries
Pour que tout fonctionne correctement, voici la liste des librairies nécessaires au projet. Vous pouvez télécharger celles qui ne sont pas incluses directement dans Arduino en allant voir l’article annexe sur le projet, un lien a été posté!
//Nécessaire pour le capteur BMP #include//Capteur humidité #include //Librairie nécessaire à l'écran LCD #include #include //Gestion des I/O #include //Capteurs météo #include
Initialisation
Voici quelques initialisations / déclarations de variables nécessaires (à placer avant le setup):
using namespace std; #define NUMFLAKES 10 #define XPOS 0 #define YPOS 1 #define DELTAY 2 #define LOGO16_GLCD_HEIGHT 16 #define LOGO16_GLCD_WIDTH 16 #define LED A2 #define BUZZER 10 #define BT A3 #define PT A0 #define DHTPIN 2 #define DHTTYPE DHT22 #define SON 200 const int TEMP=1; const int HUM=0; const int NORMAL=-1; //const int PRES = 2; //const int ALT = 3; int MAXT = 38; int MAXH = 75; int MAXP = -40000; int MAXA = 100; int mode = NORMAL; DHT dht(DHTPIN, DHTTYPE); Adafruit_BMP085 bmp; const String TITLE = " STATION MEETEO"; const String FAIL = "Failed to rread"; //Chaines de caractères pour l'affichage String strSerie, str1="Hum = ",str2,str3="n Temp = ", str4="%", str8="Pan",str5="Cn", str6="Pre = ", str7="Alt = ", str9 = "m", str10 = " "; Adafruit_PCD8544 display = Adafruit_PCD8544(8, 4, 5, 7, 6);
Les fonctions annexes
Voici quelques fonctions que nous avons codé pour nous simplifier la vie:
//Fait sonner le buzzer deux fois avec un intervalle de delayms void beep(unsigned int delayms) { analogWrite(BUZZER, SON); delay(delayms); analogWrite(BUZZER, 0); } //Allume le moteur, si pas de parametre alors vitesse max void motorOn(int speedx) { //forward @ full speed digitalWrite(12, HIGH); //Establishes forward direction of Channel A digitalWrite(9, LOW); //Disengage the Brake for Channel A analogWrite(3, speedx); //Spins the motor on Channel A at full speed } //Eteint le moteur void motorOff() { digitalWrite(9, HIGH); //Eengage the Brake for Channel A delay(100); analogWrite(3, 0); //Spins the motor on Channel A at none speed } //Lis la valeur de chaque capteur int read(int& h, int& t, int& p, int& a) { int temp = 0; // check if returns are valid, if they are NaN (not a number) then something went wrong! // Reading temperature or humidity takes about 250 milliseconds! // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) if((temp = dht.readHumidity()) != 0 && !isnan(temp)) h = temp; else return 1; if((temp = bmp.readTemperature()) != 0 && !isnan(temp)) t = temp; else return 1; if((temp = bmp.readPressure()) != 0 && !isnan(temp)) p = temp; else return 1; if((temp = bmp.readAltitude()) != 0 && !isnan(temp)) a = temp; else return 1; return 0; } //Gère l'affichage du mode seuils void modeMeteo(int mode) { display.clearDisplay(); String str1 = "MAXH = ", str2 = "nnMAXT = ", str3 = "nMAXP = ", str4 = "MAXA = ", str; String str1_2 = "%", str2_2 = "C", str3_2 = "Pa", str4_2 = "m"; /*Mise à l'échelle des valeurs récupérées par le potentiomètre*/ int valPot = analogRead(PT); if(mode == TEMP){ MAXT = valPot * 100 / 1000; } if(mode == HUM){ MAXH = valPot * 100 / 1000; } /*if(mode == PRES){ MAXP = valPot * 100; } if(mode == ALT){ MAXA = valPot * 100 / 10; }*/ str = str1 + MAXH + str1_2 + str2 + MAXT + str2_2 + str3 + MAXP + str3_2 + str4 + MAXA + str4_2; display.drawchar(str); delay(500); }
Setup
Voici le contenu de la fonction setup:
pinMode(LED, OUTPUT); pinMode(BUZZER, OUTPUT); pinMode(BT,INPUT); pinMode(PT,INPUT); // Setup Channel A for motor pinMode(12, OUTPUT); //Initiates Motor Channel A pin pinMode(9, OUTPUT); //Initiates Brake Channel A pin // Initialisation de l'écran LCD display.begin(); /* init done you can change the contrast around to adapt the display for the best viewing! */ display.setContrast(50); // Show splashscreen display.display(); delay(2000); // Clears the screen and buffer display.clearDisplay(); display.drawchar(TITLE); delay(1000); display.clearDisplay(); display.drawchar("Initialisattion..."); // Test des leds analogWrite(LED, 250); delay(1000); analogWrite(LED, 0); // Test buzzer beep(500); // Test du moteur motorOn(255); delay(1000); motorOff(); // Initialisation port série Serial.begin(9600); // Test port série //Serial.println("OP Cambodge Chuck Norris a la plage de Phnom Penh"); // Initialisation des capteurs dht.begin(); bmp.begin(); display.clearDisplay(); display.drawchar(" DONE"); delay(500); display.clearDisplay();
Loop
Et voilà le contenu de la fonction loop()
//Déclaration des variables pour sensors int h = 0, a = 0, t = 0; long int p = 0; //Int plus gros car pression > 10000 int val; //Détection si changement de mode val=analogRead(BT); if(val >= 800) { switch(mode) { case NORMAL: mode=HUM;break; case HUM: mode=TEMP;break; case TEMP: mode=NORMAL;break; /*case PRES: mode=ALT;break; case ALT: mode=NORMAL;break;*/ } beep(100); } //Sélection du mode if(mode != NORMAL) modeMeteo(mode); else { if (read(h, t, p, a) != 0) { //Si problèmes il y a eu //Serial.println(FAIL); display.clearDisplay(); display.drawchar(FAIL); delay(3000); return; } //Affichage des leds int vitesse = 250; if (t >= MAXT) { analogWrite(LED, 255); beep(300); motorOn(); } else if (h >= MAXH) { analogWrite(LED, 255); beep(300); motorOn(); } else { analogWrite(LED, 0); motorOff(); } //Construction de la chaine d'affichage: str2=str1+h+str4; str2=str2+str3+t+str5+str6+p+str8+str7+a+str9; /* str2=str2+str3+t+str5+str6+MAXH+str4+str7+MAXT+str5; */ strSerie = h + str10 + t + str10 + p + str10 + a; //Affichage à l'écran + envoie sur port série display.clearDisplay(); display.drawchar(str2); Serial.print(strSerie); Serial.println(""); delay(100); }
Voili voilou! Si quelque chose vous pose problème n’hésitez pas à poster un commentaire! Pour l’ensemble du code, voir l’article annexe pour télécharger le projet.
A bientôt!
le code est tellement clair, j’ai presque tout compris !
Ironie?! En tout cas j’ai retouché quelques trucs niveau mise en forme qui avaient bugué!
Sur l’île aux lapins j’ai rencotré un ingénieur américain, il vit actuellement à Bangkok mais a toujours sa maison à Boston. Et il contrôle sa plantation de weed (à Boston) par Arduino de partout dans le monde xD