Dans ce deuxième projet de débutant je souhaite, à partir d’une UNO, gérer deux modules thermocouples de Type MAX31855 K reliés à des capteurs de type K 1300°.
- Le premier permettra de déclencher des alarmes (led + buzzer) pour les températures hautes et basses du four d’un poêle bouilleur. Les seuils haut et bas de ces alarmes pourront être incrémentés avec 4 boutons.
- Le deuxième permettra de contrôler la températures des fumées en haut du conduit. Les alarmes (led et buzzer) me permettront de réagir rapidement si les fumées sont trop chaudes, voir en cas de feu de conduit.
- Cerise sur le gâteau, un “bouton silence” me permettra de mettre en veille le buzzer tout en laissant clignoter la led de l’alarme en cours et parallèlement, d’allumer une led rouge durant ce “mode silence”.
Le seuil concernant le thermocouple du conduit sera réglable dans le programme.
La durée du “mode silence” sera réglable dans le programme.
Il y aura deux buzzer placés dans des pièces différentes, ils seront reliés à la carte par l’intermédiaire d’un transistor.
Je n’ai pas pu faire tourner mon programme sur wokwi car je n’y ai pas trouvé de thermocouple mais voici le dessin correspondant aux branchements.
J’ai écrit le programme à partir de l’exemple que l’on trouve dans l’IDE Arduino : Fichier / Exemples / AdafruitMax31855 / librairy / lcdthermocouple et de mon premier programme écrit avec l’aide des membres du forum sur Problème pour brancher 7 sondes DS18B20 sur le même bus - #106 by mjb
Il fonctionne très bien sur mon banc d’essai réel, avec du vrai matériel, et avec les branchements dessinés plus haut mais je suis certain qu’il peut être amélioré. Cela me ferait plaisir que vous m’apportiez votre avis et vos conseils.
/*
J'ai placé "animations" dans la loop car je ne parvenais pas à déclarer "cfour" et "cfeu" avant "animation" le téléversement m'était refusé.
*/
#include <OneWire.h>
//#include <SPI.h> // dans certaines configurations, les capteurs utilisent SPI pour communiquer, SPI travaille avec Adafruit MAX31855
#include "Adafruit_MAX31855.h" // j'inclue Adafruit_MAX31855 pour gérer les thermocouples
#include <LiquidCrystal_I2C.h> // J'inclue LiquidCrystal-I2C pour gérer le LCD
#include <Toggle.h> // j'inclue Toggle pour gérer le bouton silence
LiquidCrystal_I2C lcd(0x27, 20, 5); // adresse du LCD i2c , nombre de colonnes, nombre de lignes de l'écran
#define MAXDO 2 // sortie DO du Max 31855
#define MAXCS 3 // sortie CS " " " "
#define MAXCLK 4 // sortie CLK " " " "
#define MAXCS2 5 // sortie CS 2 " " "
const int pinbtn1 = 6, pinbtn2 = 7, pinbtn3 = 8, pinbtn4 = 9, pinbuzzer = 10, pinledfourH = 11 , pinledfourB = 12, pinledfeu = 13, pinBoutonSilence = A0, pinLedSilence = A1 ; // le bouton n°1 est relié en broche 6 , ...
Toggle boutonSilence(pinBoutonSilence); //création d'une variable nommée bouton Silence, du type Toggle, qui est initialisée en utilisant le N° de la broche pinBoutonSilence (13)
bool etat1 ; // déclare l'état du bouton 1 (bleu -)pour connaître l'état du bouton s'il est à 0 ou à 1 ... est-ce que j'établis le contact ou non... 0 contact non ; 1 contact oui.
bool etat2 ; // déclare l'état du bouton 2 (bleu +) pour connaître l'état du bouton s'il est à 0 ou à 1 ... est-ce que j'établis le contact ou non... 0 contact non ; 1 contact oui.
bool etat3 ; // déclare l'état du bouton 3 (rouge -) pour connaître l'état du bouton s'il est à 0 ou à 1 ... est-ce que j'établis le contact ou non... 0 contact non ; 1 contact oui.
bool etat4 ; // déclare l'état du bouton 4 (rouge +) pour connaître l'état du bouton s'il est à 0 ou à 1 ... est-ce que j'établis le contact ou non... 0 contact non ; 1 contact oui.
int seuil_fourbas = 21; // 21° seuil de la sonde four - Basse (pour l'expérimentation) qui s'affiche lors de la réinitialisation, elle peut être incrémentée.
int seuil_fourhaut = 23; // 23° seiol de la sonde four - Haute (pour l'expérimentation) qui s'affiche lors de la réinitialisation, elle peut être incrémentée.
int seuil_feu = 25; // 25° seuil de la sonde placée en haut du conduit fumée pour détecter un incendie de cheminée (ne pourra pas s'incrémenter)
Adafruit_MAX31855 thermocouple1(MAXCLK, MAXCS, MAXDO); // création d'une variable nommée thermocouple1, du type Adafruit_MAX31855 , qui est initialisée en utilisant les N° des broches qui concernent le thermocouple 1
Adafruit_MAX31855 thermocouple2 (MAXCLK, MAXCS2, MAXDO); // création d'une variable nommée thermocouple2, du type Adafruit_MAX31855 , qui est initialisée en utilisant les N° des broches qui concernent le thermocouple 2
enum : uint8_t {AUCUNE_ALARME = 0, ALARME_FOUR_H = 1, ALARME_FOUR_B = 2, ALARME_FEU = 4};
uint8_t alarmesEnCours = AUCUNE_ALARME;
//*******************************************************************************************************************************************
//void animations() {
// *******************************************************************************************************************************
void setup() {
lcd.init(); // active le LCD
lcd.backlight(); // active le rétroéclairage
pinMode (pinbtn1, INPUT_PULLUP) ; // active l'entrée du signal envoyé par le bouton poussoir 1 (bleu-) avec un mode pullup qui ajoute une résistance sur le circuit afin de le stabiliser.
pinMode (pinbtn2, INPUT_PULLUP) ; // active l'entrée du signal envoyé par le bouton poussoir 2 (bleu+) avec un mode pullup qui ajoute une résistance sur le circuit afin de le stabiliser.
pinMode (pinbtn3, INPUT_PULLUP) ; // active l'entrée du signal envoyé par le bouton poussoir 1 (rouge-) avec un mode pullup qui ajoute une résistance sur le circuit afin de le stabiliser.
pinMode (pinbtn4, INPUT_PULLUP) ; // active l'entrée du signal envoyé par le bouton poussoir 1 (rouge+) avec un mode pullup qui ajoute une résistance sur le circuit afin de le stabiliser.
pinMode (pinbuzzer, OUTPUT) ; digitalWrite(pinbuzzer, LOW); // active la sortie 13 du buzzer
pinMode (pinledfourH, OUTPUT) ; digitalWrite(pinledfourH, LOW); // active la sortie 11 de la led alarme four Haut
pinMode (pinledfourB, OUTPUT) ; digitalWrite(pinledfourB, LOW); // active la sortie 11 de la led alarme four Bas
pinMode (pinledfeu, OUTPUT) ; digitalWrite(pinledfeu, LOW); // active la sortie 12 de la led alarme feu
pinMode (pinLedSilence, OUTPUT) ; digitalWrite(pinLedSilence, LOW); // active la sortie A1 de la led silence
boutonSilence.begin(pinBoutonSilence);
Serial.begin(115200);
Serial.println("PRET");
delay(1000); // pour stabiliser la lecture
}
void loop() {
// relevé des températures
double cfour = thermocouple1.readCelsius(); // Lecture en degrés Celcius du capteur 1
double cfeu = thermocouple2.readCelsius(); // Lecture en degrés Celcius du capteur 2
//***************************************************************************************************************************
// relevé de l'état des boutons et incrémentation
etat1 = digitalRead(pinbtn1) ; // lire l'état de mon bouton 1 bleu-
if (etat1 == 0) { // si j'appuies sur le bouton bleu-, je baisse de 1°C
seuil_fourbas--; // deg-- est équivalent à deg = deg -1 ;
}
etat2 = digitalRead(pinbtn2) ; // lire l'état de mon bouton 2 bleu+
if (etat2 == 0) { // si j'appuies sur le bouton bleu+, je monte de 1°C
seuil_fourbas++; // deg-- est équivalent à deg = deg -1 ;
}
etat3 = digitalRead(pinbtn3) ; // lire l'état de mon bouton 3 rouge -
if (etat3 == 0) { // si j'appuies sur le bouton rouge - , je baisse de 1°C
seuil_fourhaut--; // deg-- est équivalent à deg = deg -1 ;
}
etat4 = digitalRead(pinbtn4) ; // lire l'état de mon bouton 4 rouge +
if (etat4 == 0) { // si j'appuies sur le bouton 4 rouge +, je monte de 1°C
seuil_fourhaut++;
}
//**************************************************************************************************************************///////////////////////////////////////////
//void animations() {
static bool modeSilence = false; // Variable persistante conservant l’état du mode silence entre deux appels de la fonction.
static uint32_t debutModeSilence = 0; // Instant, en millisecondes depuis le démarrage, auquel le mode silence a été activé.
static const uint32_t dureeModeSilence = 10000ul; // définition d'une constante pour la durée maximale du mode silence en millisecondes.
boutonSilence.poll();
if (boutonSilence.onPress()) { // si le bouton est appuyé on rentre dans ce if
modeSilence = not modeSilence; // Inversion explicite de l’état du mode silence à chaque appui.
digitalWrite(pinLedSilence, modeSilence ? HIGH : LOW); // La LED reflète directement l’état logique du mode silence. on interroge l'état du mode silence, s'il est "true" la pinledSilence devient HIGH sinon on retourne LOW ???
/*static uint32_t chrono = 0; // Référence temporelle persistante utilisée pour cadencer le clignotement….(le compteur est relevé)
if (millis() - chrono >= 100) { // Inversion de l’état de la LED toutes les 100 ms, ce qui fixe la fréquence de clignotement.
digitalWrite(pinLedSilence, digitalRead(pinLedSilence) == HIGH ? LOW : HIGH); // la led HP clignote… l'écriture de cette fonction s'appelle l'opérateur ternaire elle Inverse l'état en sortie pinLedHP… si pinLedHP est HIGH alors retourne LOW sinon retourne HIGH …on pourrait l'écrire digitalWrite(pinLedHP, !(digitalRead(pinLedHP)));
chrono = millis();
}*/
if (modeSilence) debutModeSilence = millis(); // Mémorisation de l’instant d’activation pour mesurer la durée écoulée.
}
if (modeSilence && millis() - debutModeSilence >= dureeModeSilence) { // si la durée maximale du mode silence est dépassée.(si le compteur continue moins le compte relevé au début du MS est supérieur ou égal à 10 secondes (dureeModeSilence) )
modeSilence = false; // le mode silence devient faux (est désactivé… le buzzer sonne.
digitalWrite(pinLedSilence, LOW); // et la led silence s'éteint
}
//**************************************************************
if (cfour >= seuil_fourhaut) { // si la dernière température du capteur four est supérieure à son seuil haut
static uint32_t chrono = 0; // Référence temporelle persistante utilisée pour cadencer le clignotement….(le compteur est relevé)
if (millis() - chrono >= 100) { // Inversion de l’état de la LED toutes les 100 ms, ce qui fixe la fréquence de clignotement.
digitalWrite(pinledfourH, digitalRead(pinledfourH) == HIGH ? LOW : HIGH); // la led HP clignote… l'écriture de cette fonction s'appelle l'opérateur ternaire elle Inverse l'état en sortie pinLedHP… si pinLedHP est HIGH alors retourne LOW sinon retourne HIGH …on pourrait l'écrire digitalWrite(pinLedHP, !(digitalRead(pinLedHP)));
chrono = millis(); // on se souvient du moment de la dernière inversion
}
alarmesEnCours |= ALARME_FOUR_H; // Activation du bit correspondant à l’alarme HP sans modifier les autres bits. |= est un OU bit à bit
} else { // sinon
digitalWrite(pinledfourH, LOW); // la led HP n'est pas alimentée
alarmesEnCours &= ~ALARME_FOUR_H; // Effacement du bit ALARME_HP par masquage binaire, les autres alarmes restent inchangées.
}
//**************************************************************
if (cfour <= seuil_fourbas) { // si la dernière température du capteur four est inférieure à son seuil bas
static uint32_t chrono = 0;
if (millis() - chrono >= 100) {
digitalWrite(pinledfourB, digitalRead(pinledfourB) == HIGH ? LOW : HIGH);
chrono = millis();
}
alarmesEnCours |= ALARME_FOUR_B;
} else {
digitalWrite(pinledfourB, LOW);
alarmesEnCours &= ~ ALARME_FOUR_B;
}
//**************************************************************
if (cfeu >= seuil_feu) { // si la dernière température du capteur feu est supérieure à son seuil
static uint32_t chrono = 0;
if (millis() - chrono >= 100) {
digitalWrite(pinledfeu, digitalRead(pinledfeu) == HIGH ? LOW : HIGH);
chrono = millis();
}
alarmesEnCours |= ALARME_FEU;
} else {
digitalWrite(pinledfeu, LOW);
alarmesEnCours &= ~ALARME_FEU;
}
//********************************************************************
if (not modeSilence && alarmesEnCours != AUCUNE_ALARME) {
// une alarme au moins est en cours et on n'est pas en mode silence
static uint32_t chrono = 0;
if (millis() - chrono >= 300) {
digitalWrite( pinbuzzer, digitalRead(pinbuzzer) == HIGH ? LOW : HIGH);
chrono = millis();
}
}
else
{
digitalWrite(pinbuzzer, LOW);
}
//*****************************************************************************************************************************///////////////////////////////////////////////////
//Configuration du LCD
/*
lcd.setCursor(0, 0); // sur la première colone de la première ligne
lcd.print("T"); // on imprime les caractères "T"
lcd.print((char)223); // symbole °
lcd.print("ambiante"); // on imprime les caractères "ambiante"
lcd.print(thermocouple1.readInternal()); // on imprime la température ambiante donnée par le capteur 1
/*
lcd.setCursor(0, 1); // sur la première colone de la deuxième lign
lcd.print("Int. Temp 2 = "); // on imprime les caractères "Int. Temp 2 = "
lcd.print(thermocouple2.readInternal()); // on imprime la température ambiante donnée par le capteur MAX
*/
lcd.setCursor(4, 0); // sur la première colone de la quatrième ligne
lcd.print("Seuil bas = ");
lcd.print (seuil_fourbas); // le LCD imprime la valeur du seuil bas que l'on peut incrémenter
lcd.print((char)223);
lcd.setCursor(0, 1); // sur la première colone de la deuxième ligne
lcd.print("T");
lcd.print((char)223);
lcd.print("FOUR ");
lcd.print(cfour); // on imprime la température captée par le thermocouple du four // on imprime la température captée par le thermocouple du conduit de cheminée
lcd.setCursor(4, 2); // sur la première colone de la cinquième ligne
lcd.print("Seuil haut = ");
lcd.print (seuil_fourhaut); // le LCD imprime la valeur du seuil haut que l'on peut incrémenter
lcd.print((char)223);
lcd.setCursor(0, 3); // sur la première colone de la troisième ligne
lcd.print("T");
lcd.print((char)223);
lcd.print("CONDUIT ");
lcd.print(cfeu);
Serial.print ("alarmesEnCours") ; Serial.println(alarmesEnCours) ;
Serial.print ("T° FOUR") ; Serial.println(cfour) ;
Serial.print ("T° CONDUIT") ; Serial.println(cfeu) ;
delay(10); // 10ms pour que l'incrémentation ne soit pas trop rapide
//animations();
}

