Objectifs
Dans cette activité, il s'agit de concevoir le programme qui va gérer la mini-serre :
- le programme python qui envoie les commandes de lectures des capteurs et qui, en fonction des valeurs reçues, enverra les ordres de commande aux actionneurs
Voici le schéma de principe de l'ensemble :
Programme Arduino
Voici le programme à téléverser dans l'arduino :
//=======appel des bibliothèques requises
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//=======Configuration utilisation bibliothèques pour capteur température
//branchement de la sortie du capteur DS18B20 sur broche digitale n°4
#define ONE_WIRE_BUS 4
//configuration liason série
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
//========Configuration de l'adressage de l'afficheur numérique
// En cas de non fonctionnement, mettez la ligne 8 en
// commentaire et retirez le commentaire à la ligne 9.
LiquidCrystal_I2C lcd(0x27, 20, 4);
//LiquidCrystal_I2C lcd(0x3F,20,4);
//=======Déclaration des variables
//la led est branchée sur la broche digitale n°10
const int led = 10;
//le capteur eau est branché sur la broche analogique n°A1
const int eau= A1;
//le capteur de lumière est branché sur la broche analogique n°A0
const int lum= A0;
//les variables reception et potarLevel sont de type integer
int reception, eauLevel, lumLevel;
//déclaration variable nombre décimal (type float)
float tempC;
//sorties pour les actionneurs
const int Slum = 5, Seau = 6, Stemp = 7;
//déclaration des variables de type string
String message, commande = "";
//=======Fonction d'initialisation - exécutée 1 seule fois
void setup() {
// initialisation de l'afficheur
lcd.init();
lcd.backlight();
//définit le type d'entrée/sortie des broches utilisées
pinMode(led, OUTPUT);
pinMode(eau, INPUT);
pinMode(lum, INPUT);
pinMode(Slum, OUTPUT);
pinMode(Seau, OUTPUT);
pinMode(Stemp, OUTPUT);
//définit les paramètres de la liaison série (cable USB)
Serial.begin(115200);
Serial.flush();
//Active la librairie du capteur de température
sensors.begin();
}
void affiche() {
lcd.clear();
//Lumière 1ère ligne à gauche
lcd.setCursor(0, 0);
lcd.print("Lum:");
lcd.print(lumLevel);
//Lumière 1ère ligne au milieu
lcd.setCursor(8, 0);
lcd.print("Eau:");
lcd.print(eauLevel);
//Temp 2ème ligne à gauche
lcd.setCursor(0, 1);
lcd.print("Temp:");
lcd.print(tempC);
}
//=======Boucle principale
void loop() {
//++++++++++++++Lecture des valeurs des capteurs
eauLevel = analogRead(eau);
lumLevel = analogRead(lum);
sensors.requestTemperatures();
tempC = sensors.getTempCByIndex(0);
//++++++++++++++Traitement des ordres
//-------Boucle de réception de données en provenance de la console
while (Serial.available() > 0) {
//lecture du code ASCII d'un caractère
reception = Serial.read();
//vérifie si c'est le dernier caractère Line Feed "\ln"
if (reception !=10) {
commande += char(reception);
}
//delais de 5/1000s
delay(5);
}
//==========traitement des capteurs========
//------Traitement de la commande potar
if (commande == "eau") {
Serial.println(eauLevel);
}
//------Traitement de la commande potar
if (commande == "lum") {
Serial.println(lumLevel);
}
//------Traitement de la commande temp
if (commande == "temp") {
Serial.println(tempC);
}
//==========traitement des actionneurs=====
//------Traitement de l'éclairage
if (commande == "lumOn") {
digitalWrite(Slum, HIGH);
}
if (commande == "lumOff") {
digitalWrite(Slum, LOW);
}
//------Traitement de l'eau
if (commande == "eauOn") {
digitalWrite(Seau, HIGH);
}
if (commande == "eauOff") {
digitalWrite(Seau, LOW);
}
//------Traitement du rafraichissement
if (commande == "airOn") {
digitalWrite(Stemp, HIGH);
}
if (commande == "airOff") {
digitalWrite(Stemp, LOW);
}
//efface la variable commande
commande = "";
affiche();
}
Programmepython
L'activité 3 nous a permis de concevoir le programme qui gère l'utilisation des capteurs : il est donc à utiliser comme base de départ.
Pour mémoire les commandes pour lire les valeurs des capteurs sont :
- pour le lumière : lum
- pour l'eau : eau
- pour la température : temp
Il faut y ajouter les commandes des actionneurs
Nous avons déjà vu le principe pour commander un actionneur dans l'activité 2 : nous utilisions les commandes on et off pour allumer ou éteindre une led.
La différence est qu'il y a 3 actionneurs à commander et que les commandes on et off sont insuffisantes.
C'est donc avec les commandes suivantes que nous commanderons les actionneurs :
- la pompe : eauOn et eauOff
- le ventilateur : airOn et airOff
- le ruban led : lumOn et lumOff
Ne modifier pas votre programme d'un seul coup : procéder par un premier actionneur, tester le bon fonctionnement, puis procéder au suivant et ainsi de suite.
En dernier recours, vous pouvez reprendre le code suivant comme base de départ : seul la régulation de la lumière est gérée.
# coding: utf-8
#!/usr/bin/python
#=======appel des bibliothèques======================
import serial
import time
#=======fonction lecture potentiomètre====================
def lumiere():
#envoi de la commande de lecture du niveau de luminosité
commande='lum'
portCom.write(commande.encode())
time.sleep(0.3)
#réception des données sur la liaison série
nbCar = portCom.in_waiting
retour = portCom.read(nbCar)
val = retour.decode()
#val est une suite de caractères et non un nombre
#si val n'est pas vide
if (retour.decode()!=''):
val=int(retour.decode())
else:
val=0.1
return val
#=======paramétrage de la liaison série==============
portCom = serial.Serial()
portCom.port = "/dev/ttyACM1"
portCom.baudrate = 115200
portCom.open()
#=======boucle de lecture/affichage des capteurs
#++++ATTENTION : il faut trouver une condition de sortie de la boucle
ordre='yes'
while (ordre!='stop'):
#appel de la fonction pour envoie et réception de la valeur
lumLevel = lumiere()
#affichage de la valeur du capteur dans la console python
print("Niveau de lumière :",lumLevel)
#envoi de la commande pour allumer/éteindre en fonction du niveau de lumière
if (lumLevel<300):
commande='lumOn'
else:
commande='lumOff'
#la ligne suivante est à placer qu'une seule fois dans la boucle while
portCom.write(commande.encode())
#délai de 2s avnt de recommencer la boucle
time.sleep(2)
#---déconnecter python du port série
portCom.close()