Bonjour, merci pour ces pistes .
Je vais donc commencer alimenter mon Uno par un bloc alim de 9v.
Je joins le code complet pour un contrôle d'une éventuelle erreur de code .
Je ne comprend la chose suivante: si le micro "plante" pendant le loop et reste bloqué complet , pourquoi le wachdog le "reveillerait" ?
Que veut dire "se pose la question de la protection de l'arduino" ?
La carte relais est cablée classiquement ; résistance + led de signalisation , transistor et diode de roue libre.
Je vais aussi changer la carte relais par une carte relais avec optocoupleur fab seeit vendu par conrad, Est ce que cela suffira ?
Merci et à bientôt
#include <avr/wdt.h>
#include <Wire.h>
#include "Timer.h"
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins(RS,E,DB4,DB5,DB6,DB7)
//LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // dans le cas du shield arduino
LiquidCrystal lcd(6, 7, 5, 4, 3, 8); // dans le cas du shield fabriqué PB( RS,E D4,D5,D6,D7) modifié
// initialisation des variables
// float temp = 0.0; // pas besoin de cette variable globale
byte adress = 0x48; // adresse de la sonde DS75 (les 4 bits)
int valeurP = 0; // initialise la variable qui lira la valeur analogique du potentiomètre
boolean present = 0;
boolean etat_led = 1;
byte TemperatureMSB = 0;
byte TemperatureLSB = 0;
byte index_affichage = 0;
byte pospotar = 0;
byte oldpospotar = 0;
float Tcapteur = 0.0;
float Tballon1 = 0.0;
float Tballon2 = 0.0;
float Tarrivee = 0.0;
float T_CE = 0.0;
//float Tretour = 0.0;
float Tresist = 0.0;
int duree = 1000; //utilisé pour le clignotement de la led
unsigned long frequence_affichage = 3500; //3000 utilisé pour la fréquence d'affichage toutes les 3 sec
unsigned long frequence_acquisition = 60000; //60000 utilisé pour la fréquence d'acquisition toutes les mn
unsigned long frequence_reset = 3600000; //3600000 utilisé pour la fréquence de reset toutes les heures
unsigned long last_led = millis(); //utilisé pour le clignotement
unsigned long last_acquisition = millis(); //utilisé pour la fréquence d'acquisition
unsigned long last_affichage = millis(); //utilisé pour l'affichage des valeurs
unsigned long last_reset = millis(); //utilisé pour la réinitialisaton
boolean gel;
// initialisation des constantes (n° sonde)
const byte Scapteur = 0;
const byte Sarrivee = 1;
const byte Sballon1 = 3;
const byte Sballon2 = 7;
const byte S_CE = 6;
//const byte Sretour= 4;
const byte Sresist= 2;
// initialisation des constantes pins
const byte vanne1 = 11;
const byte vanne2 = 10;
const byte resistance = 12;
const byte circ = 9; // ATTENTION 3 SI ESSAI AVEC SHIELD AARDUINO SInon AVEC LA PLATINE PB C'EST 9
const byte led = 13;
const byte capteurdebit = 2; // le capteur est raccordé sur la pin 2 pour utilisé l'interruption INT0
// declarations des variables liées au capteur de débit et à la fonction de l'interruption
unsigned long debut_sensor;
volatile int impulsion = 0 ;
volatile unsigned long precedentPulse = millis();
float debit = 0;
boolean marcheR = 0; // à 1 qd la résistance est sous tension
// declarations des variables liées à la communicarion avec le Pi
boolean auto_resistance = 0; //var boolean si autorisation de gestion de la résistance
String message; // message reçu de la liaison série avec le pi
///////////////////// SETUP ////////////////////////////////////
void setup() {
Serial.begin(9600); // initialisation du port série
lcd.begin(16, 2); // initialisation de l'afficheur LCD
// Print a message to the LCD.
lcd.print(" Progr solaire 5 ");
lcd.setCursor(0, 1) ; // positionne à 1ière colonne , 2 ième ligne
lcd.print(" du 19 sept 21");
delay(2000);
lcd.setCursor(0, 0) ; // positionne à 1ière colonne , 1 ième ligne
lcd.print("fichier");
lcd.setCursor(0, 1) ; // positionne à 1ière colonne , 1 ième ligne
lcd.print("solaire_5_com");
// configurer les 8 sondes possibles
for (byte i = 0; i < 8; i++) {
Wire.begin();
Wire.beginTransmission(adress + i); // début communication sur chaque sonde
Wire.write(0x01); // Accès au registre de configuration
Wire.write(0x20); // Ecriture dans le registre de configuration avec résolution 10 bits (pour 11 bits c'est 0x40) et pour 9 bits c'est 0x00
Wire.endTransmission();
}
// initialize digital pin as an output.
pinMode(led, OUTPUT);
pinMode(vanne2, OUTPUT);
pinMode(vanne1, OUTPUT);
pinMode(circ, OUTPUT);
pinMode(resistance, OUTPUT);
pinMode(capteurdebit, INPUT);
digitalWrite(led, HIGH) ; // allumage led témoin
delay(2000);
// initialisation de l'interruption pour la mesure de débit
attachInterrupt(0, pulsecounter, FALLING); // attache l'interruption n°0 (qui correspond à la pin 2) à la fonction pulsecounter
// Serial.printledln(last_affichage);
acquisitions(); // premières acquisitions
if (pospotar == 0) {
actions(); // et tout de suite action pour ne pas attendre le temps de la fréquence d'acquisitions
}
last_reset = millis(); // réinitialisaton du reset
debut_sensor = 0; //initialisation pour la pemiere periode de 1 sec pour définir un débit
wdt_enable(WDTO_8S); // initialisation du wachdog sur 8 s
}
//////////////////// FIN DE SETUP ////////////////////////////////
// fonction pour la lecture
float mesure(byte sonde) { // qui retourne une valeur
//float s = 1.0;
int MSB = 0;
int LSB = 0;
float temp_mesuree = 0.0;
present = 0;
Wire.beginTransmission(sonde); // début communication sur la sonde 0 en mode écriture
Wire.write(0x00); // Pointer sur le registre de temperature
Wire.endTransmission();
Wire.requestFrom(sonde, 2u);
if (2 <= Wire.available()) { // si deux octets disponibles
MSB = Wire.read(); // lire l'octet de poids fort
LSB = Wire.read(); // lire l'octet de poids faible
present = 1; // la sonde est présente car il y a les 2 octets
} else {
present = 0; // iil n'y a pas les 2 octets donc la sonde n'est pas présente
}
Wire.endTransmission();
//Serial.print(" MSB = ");
//Serial.print(MSB);
// Serial.print(" LSB = ");
//Serial.println(LSB);
if (present) {
if (MSB >= 128) { // si le bit 7 du MSB est à 1 c'est négatif
MSB = MSB - 256; // inverse les bits
temp_mesuree = (0.5 * ((LSB & 0x80) >> 7) + 0.25 * ((LSB & 0x40) >> 6)) - 1 + (float)MSB ;
// Serial.print(" nouveau MSB apres -255 = ");
// Serial.println(MSB);
}
else {
temp_mesuree = 0.5 * ((LSB & 0x80) >> 7) + 0.25 * ((LSB & 0x40) >> 6) + (float)MSB;
// 0x80 = 10000000 et le & signifie je selectionne uniquement le bit 7 et je le decale à droite de 7 http://www.locoduino.org/spip.php?article70
// 0x40 = 01000000 et le & signifie je selectionne uniquement le bit 6 et le le decale à droite de 6
// temp=0.5*((LSB&0x80)>>7) + 0.25*((LSB&0x40)>>6) + 0.125*((LSB&0x20)>>5) + 0.0625*((LSB&0x10)>>4) + (float)MSB; pour une résolution plus fine
}
}
return temp_mesuree;
}
// fonction d'acquiitions
void acquisitions() {
Tballon1 = 0.0;
Tballon2 = 0.0;
Tcapteur = 0.0;
Tarrivee = 0.0;
// T_CE = 0.0;
//T_resist= 0.0;
Tballon1 = mesure(adress + Sballon1);
affichage("Mesure ","Ballon 1",Tballon1);
delay(1000);
Tcapteur = mesure(adress + Scapteur);
affichage("Mesure ","Capteur",Tcapteur);
delay(1000);
Tballon2 = mesure(adress + Sballon2);
affichage("Mesure ","Ballon 2",Tballon2);
delay(1000);
Tarrivee = mesure(adress + Sarrivee);
affichage("Mesure ","Arrivée",Tarrivee);
//delay(1000);
//Tretour = mesure(adress + Sretour);
// affichage("Mesure ","Retour",Tretour);
//delay(1000);
T_CE = mesure(adress + S_CE);
affichage("Mesure ","C.E",T_CE);
Tresist = mesure(adress + Sresist);
affichage("Mesure ","Resistan",Tresist);
}
// fonction pour les actions
void actions() {
if (Tballon1 > Tballon2) {
if ((Tcapteur > Tballon2 + 4 ) || (Tarrivee > Tballon2 + 4 ))
{
digitalWrite(vanne2, HIGH);
digitalWrite(vanne1, LOW);
digitalWrite(circ, HIGH);
}
else {
digitalWrite(vanne2, LOW);
digitalWrite(vanne1, LOW);
digitalWrite(circ, LOW);
}
}
else if ((Tcapteur > Tballon1 + 4 ) || (Tarrivee > Tballon1 + 4))
{
digitalWrite(vanne1, HIGH);
digitalWrite(vanne2, LOW);
digitalWrite(circ, HIGH);
} else {
digitalWrite(vanne1, LOW);
digitalWrite(vanne2, LOW);
digitalWrite(circ, LOW);
}
// mise en circulation en cas de risque de gel
if (Tcapteur <= 2 ) {
gel = 1;
if (Tballon1 >= Tballon2) {
digitalWrite(vanne1, HIGH);
digitalWrite(circ, HIGH);
} else {
digitalWrite(vanne2, HIGH);
digitalWrite(circ, HIGH);
}
}
// le risque de gel disparait
if ((gel == 1) && (Tcapteur > 2 ) ) {
digitalWrite(vanne2, LOW);
digitalWrite(vanne1, LOW);
digitalWrite(circ, LOW);
gel = 0;
}
}
//fonction d'affichage
void affichage(String origine, String sonde, float temperature) { // origine c'est soit mesure à la suite de l'acquisitrion , soit temp pour les affichages permanents
lcd.clear();
lcd.setCursor(0, 0) ; // 1ème col - 1ème ligne - positionne le curseur à l'endroit voulu (colonne, ligne) (1ère=0 !)
lcd.print(origine) ;
lcd.print(sonde) ;
lcd.setCursor(0, 1) ; // 1ème col - 2ème ligne - positionne le curseur à l'endroit voulu (colonne, ligne) (1ère=0 !)
lcd.print(temperature) ;
lcd.print(" ") ;
lcd.print((char)223); // c'est °
lcd.print('C');
if (auto_resistance) {
lcd.setCursor(15,0); // 16ème col - 1ème ligne pour indiquer gestion resistance en auto
lcd.print('A');}
if (marcheR) {
lcd.setCursor(12,1); // 13ème col - 2ème ligne pour indiquer resistance sous tension
lcd.print('R');}
if (debit > 0) {
lcd.setCursor(9, 1) ; // 10ème col - 2ème ligne - positionne le curseur à l'endroit voulu (colonne, ligne) (1ère=0 !)
lcd.print(debit) ;
}
}
// fonction de l'interruption INT0 occasionnée par le pulse du flow sensor ************************
void pulsecounter(){
impulsion++;
precedentPulse = millis();
}
///////////////////////////////////////////////////////////////////////////////////
////// PROGRAMME PRINCIPAL /////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
void loop() {
// clignotement de la led *************************
if ((millis() - last_led ) >= duree) {
if (etat_led == 1) {digitalWrite(led, LOW); // c'était allumé donc on éteint la led
etat_led = LOW; // la led est éteinte
duree = 1000; } // pour une durée de 1 sec }
else { // c'était éteint donc on l'allume
digitalWrite(led, HIGH); // allumage de la led
etat_led = HIGH; // la led est allumée
if ( auto_resistance == 1) {
duree = 1000; // pour la durée d'allumage de 200ms ou de 1000ms si autorisation de lecture su capteur de débit
} else {
duree = 200;
}
}
last_led = millis();
}
delay(10);
// lire état du potentiometre *******************************************
valeurP = analogRead(A0); // test du potentiomètre
if (valeurP >= 900) {
pospotar = 3; // défini la position du potentiometre
} else if (valeurP > 500) {
pospotar = 2;
} else if (valeurP > 100) {
pospotar = 1;
} else {
pospotar = 0;
}
// gestion du potentiometre car sa position a changé *******************
if (pospotar != oldpospotar) {
if (pospotar > 2 ) { // c'est donc à 3
digitalWrite(vanne1, LOW); // forcage vanne 2 et circ
digitalWrite(vanne2, HIGH);
digitalWrite(circ, HIGH);
auto_resistance = 0;
}
else if (pospotar > 1) { // c'est donc à 2
digitalWrite(vanne1, HIGH); // forcage vanne 1 et circ
digitalWrite(vanne2, LOW);
digitalWrite(circ, HIGH);
auto_resistance = 0;
}
else { // c'est donc à 0 ou 1
digitalWrite(vanne2, LOW); // tout arrêt
digitalWrite(vanne1, LOW);
digitalWrite(circ, LOW);
if (pospotar == 1 ) { // c'est donc à 1 , on autorise l'interruption pour lire le débimetre
auto_resistance = 1; }
else {auto_resistance = 0;}
}
oldpospotar = pospotar;
}
// acquisitions suivant timer **********************************************
if ((millis() - last_acquisition ) >= frequence_acquisition ) {
acquisitions() ;
if (pospotar <= 1) {
actions();
}
last_acquisition = millis();
} else {
lcd.setCursor(12, 1) ;
lcd.print(" "); // efface les digits 13 et 14 de la seconde ligne pas les 15 ni 16
lcd.setCursor(14, 1) ; // 15ème col - 2ème ligne - positionne le curseur à l'endroit voulu (colonne, ligne) (1ère=0 !)
lcd.print((last_acquisition + frequence_acquisition - millis()) / 1000); // affiche les econdes restantes avant la nouvelle acquisitions
}
delay(10);
// affichages suivant timer ************************************************
if ((millis() - last_affichage ) >= frequence_affichage ) {
if (index_affichage > 4) {
affichage("Temp ","Arrivee", Tarrivee) ;
} else if (index_affichage > 3) {
affichage("Temp ","Ballon 2", Tballon2) ;
} else if (index_affichage > 2) {
affichage("Temp ","Capteur", Tcapteur) ;
} else if (index_affichage > 1){
affichage("Temp ","Ballon 1 ", Tballon1) ;
} else if (index_affichage > 0){
affichage("Temp ","CE ", T_CE) ;
} else { affichage("Temp ","Resistance",Tresist);}
index_affichage++;
if (index_affichage == 6) {
index_affichage = 0;
}
last_affichage = millis();
}
delay(20);
// pour faire un reset régulièrement ****************************************
if ((millis() - last_reset) >= frequence_reset) {
setup();
}
delay(20);
// définir le débit pour l'affichage basé sur le comtage des impulsions en 1 sec *************************
if ((millis()- debut_sensor )>= 1000) { // à chaque seconde écoulée
debit= impulsion/8.90; // déhit sur 1 sec
debut_sensor=millis(); // pour une nouvelle péridoe d'observation de 1 sec
impulsion = 0;}
// gestion de la résistance ***********************************************
// debuter le comptage de temps si un débit mini de 1 litre/mn s'écoule càd dès que 2 pulses sont vus qui permettent de définir un débit
if (auto_resistance){
if (marcheR) { // si resistance en marche
if ((millis() - precedentPulse) > 1000) { // 1 sec sans pulse du capteur donc plus de débit
marcheR = 0;
digitalWrite(resistance, LOW); } //arrête la resistance
}
else { // la résistance n'est pas en marche
if (((millis() - precedentPulse) < 100)&& (Tballon1 < 48)) { // il y a u n débit de au moins 1 litre /mn
marcheR = 1;
digitalWrite(resistance, HIGH); } //marche la resistance
}
}
// verifier si message reçu du pi et le traiter et renvoyer les données ***************************
message = "";
if (Serial.available() > 0) {
message = Serial.readString();
if (message == "R") {
auto_resistance = 1;
}
if (message == "S") {
auto_resistance = 0;
if (marcheR== 1){ // dans le cas où Resistance était en matche
digitalWrite(resistance, LOW); //arrête la resistance
marcheR = 0;}
}
// ensuite envoi les donnnées sur le pi
Serial.print(auto_resistance); // correspond à 0 ou 1
Serial.print(";");
Serial.print(Tcapteur);
Serial.print(";");
Serial.print(Tarrivee);
Serial.print(";");
Serial.print(Tballon2);
Serial.print(";");
Serial.print(Tballon1);
Serial.print(";");
Serial.print(T_CE);
Serial.print(";");
Serial.print(Tresist);
}
wdt_reset(); // reset du wachdog à chaque tour de loop
} // fin du loop