Bonjour,
Je suis débutant en programmation et j’adapte des codes trouvés sur internet pour correspondre à mes besoins. Dans ce cas je désire gérer l’affichage de la température d’un aquarium, sa valeur mini et maxi.
Matériel utilisé :
- Arduino nano
- Ecran lcd i2c 16 x 2
- Sonde étanche DS18B20
- 3 boutons poussoirs
Fonctionnement :
- sur la ligne 1 affichage de la température en cours
- sur la ligne 2 la valeur mini et la valeur maxi
- En pressant un bouton, reset de la valeur mini, sur le 2ème bouton reset valeur maxi et sur le 3ème bouton arrêt/marche du lcd.
Le code suivant fonctionne, même s’il est loin d’être optimisé. Le problème se trouve au niveau du delay de 1 seconde entre la prise de la mesure et la lecture de la valeur. Du coup pour allumer/éteindre le lcd, le bouton n’est pas très réactive. J’ai pensé utiliser la fonction millis pour le code
ds.reset(); // Reset le bus 1-Wire
// skip saute la sélection du composant qui doit normalement être faite avec la fonction search.
//Ceci fonctionne uniquement si vous utilisez un seul composant : vous pouvez éviter de le rechercher et vous pouvez l'utiliser immédiatement
ds.skip();
ds.write(0x44, 0); // Déclenche la prise de mesure
ça va mieux, mais le code continuant ça ne respecte pas la temporisation avant la lecture.
Merci de mon conseiller sur une procédure plus adaptée.
Cordialement
// Gestion température Mini Aquarium
#include <OneWire.h> // Appel de la bibliothèque protocole dédié pour les capteurs "One Wire" (température Sonde étanche DS18B20)
OneWire ds(2); // Création de l'objet (sonde température) sur la pin 2
#include <Wire.h> // Appel de la bibliothèque protocole de communication avec composants I2C
#include <LiquidCrystal_I2C.h> // Appel de la bibliothèque contrôleur d'un affichage LCD (circuit intégré PCF8574)
LiquidCrystal_I2C lcd(0x27,16,2); // Déclare l'adresse 0x27 du LCD pour 16 caractères et 2 lignes d'affichage
// --- Déclaration des variables globales pour la température ---
byte data[12]; // Tableau de 12 octets pour lecture des 9 registre de RAM et des 3 registres d'EEPROM du capteur One Wire
float celsius; // Déclaration de la variable celsius en numérique avec décimales (virgules flottantes)
float minimum, maximum; // Déclaration des variables pour les températures minimum et maximum
int MAJ; // Variable pour l'initialisation de la température minimum
// Constantes des bouttons
const int buttonEcran = 3; // Broche du boutton marche/arrêt Ecran
const int buttonMin = 4; // Broche du boutton reset Mini
const int buttonMax = 5; // Broche du boutton reset Maxi
// variables etat écran et + -
int EtatEcran = 0; // Variable pour lire l'état du boutton marche/arrêt Ecran
int EtatMin = 0; // Variable pour lire l'état du boutton reset Mini
int EtatMax = 0; // Variable pour lire l'état du boutton reset Maxi
int FonctEcran = 1; // Variable du fonctionnement du LCD (1 Allumé, 0 éteint)
// --- Déclaration des tableaux de caractères spéciaux ---
byte plus[] = {
B11000,
B11100,
B11110,
B11111,
B11111,
B11110,
B11100,
B11000
};
byte moins[] = {
B00011,
B00111,
B01111,
B11111,
B11111,
B01111,
B00111,
B00011
};
void setup()
{
// Initialisation des bouttons en input:
pinMode(buttonEcran, INPUT);
pinMode(buttonMin, INPUT);
pinMode(buttonMax, INPUT);
// --- Initialisation du LCD ---
lcd.init();
lcd.backlight();
// --- Initialisation des caractères spéciaux ---
lcd.createChar(0, plus);
lcd.createChar(1, moins);
// --- Affichage du texte permanent (temp, °C, < et > ---
lcd.setCursor(1,0);
lcd.print("Temp : ");
lcd.setCursor(13,0);
lcd.print((char)223);
lcd.print("C");
lcd.setCursor(0,1);
lcd.write(byte(1));
lcd.setCursor(15,1);
lcd.write(byte(0));
}
void loop()
{
// Lecture le l'état des bouttons
EtatEcran = digitalRead(buttonEcran);
EtatMin = digitalRead(buttonMin);
EtatMax = digitalRead(buttonMax);
// Récupération de la température
ds.reset(); // Reset le bus 1-Wire
// skip saute la sélection du composant qui doit normalement être faite avec la fonction search.
//Ceci fonctionne uniquement si vous utilisez un seul composant : vous pouvez éviter de le rechercher et vous pouvez l'utiliser immédiatement
ds.skip();
ds.write(0x44, 0); // Déclenche la prise de mesure
delay(1000); // Délais entre renvoie d'infos de 1000ms soit 1 seconde
ds.reset(); // Reset le bus 1-Wire
ds.skip(); // skip saute la sélection du composant
ds.write(0xBE); // Envoie une demande de lecture du scratchpad
for (unsigned char i = 0; i < 9; i++) { // Lecture du scratchpad, nous avons besoin de 9 octets
data[i] = ds.read();
}
// Convertir les données en température réelle
// parce que le résultat est un entier signé de 16 bits, il devrait
// être stocké dans un type "int16_t", qui a toujours 16 bits
// même lorsqu'il est compilé sur un processeur 32 bits.
int16_t raw = (data[1] << 8) | data[0];
byte cfg = (data[4] & 0x60);
// en basse résolution, les bits bas sont indéfinis, alors remettons-les à zéro
if (cfg == 0x00) raw = raw & ~7; // Résolution de 9 bits, 93,75 ms
else if (cfg == 0x20) raw = raw & ~3; // Résolution 10 bits, 187,5 ms
else if (cfg == 0x40) raw = raw & ~1; // Résolution 11 bits, 375 ms
// Calcul en celsius.
celsius = (float)raw / 16.0;
// Reset température Mini
if (EtatMin == LOW) {
minimum=celsius;
}
// Reset température Max
if (EtatMax == LOW) {
maximum=celsius;
}
// Marche / arrêt LCD
if (EtatEcran == LOW) {
if (FonctEcran == 1) {
lcd.noBacklight(); // Eteindre le retro-eclairage
lcd.noDisplay(); // Eteind le LCD
FonctEcran = 0;
}
else {
lcd.backlight(); // Allumer le retro-eclairage
lcd.display(); // Allumer le LCD
FonctEcran = 1;
}
}
// Initialisation pour la première lecture de valeur minimale
if (MAJ != 1) {
minimum=celsius;
MAJ=1;
}
// Mise à jour des valeurs mini et maxi en fonction de la temp. en cours
if (minimum > celsius) {
minimum = celsius;
}
if (maximum<celsius) {
maximum=celsius;
}
// Affichage des valeurs temp, mini et maxi
lcd.setCursor(8,0);
lcd.print(celsius);
lcd.setCursor(2,1);
lcd.print(minimum);
lcd.print(" ");
lcd.print(maximum);
}