Electrovanne bi-stable et contrôle du bon fonctionnement
Publié : 02 mai 2021, 11:54
Bonjour,
Je vais encore avoir besoin de vos lumières;
J'ai quelques questions, mais avant tout je vous situe le sujet:
Je souhaite piloter une (pour commencer) électrovanne bistable et contrôler son bon fonctionnement.
J'utilise MySensors + Arduino pro-mini; J'y ajoute un Hbridge commandé par 2 sortie binaires (D4 et D5) et un débimètre low-cost connecté a la 2emme interruption (D3);
Dans l'attente du Hbridge, je connecte des leds sur D4 D5 et j'envoie des niveaux plutôt que des impulsions pour monitorer les états.
J'ai ecrit un petit bout de code pour vérifier le bon fonctionnement du débimètre (mesure débit et totalisateur de volume)
Et comme ca marche bien je l'intègre dans mon node.
Le node est commandé depuis Domoticz par un petit script en Blocky qui commande ouverture/fermeture en fonction de température (a terme, ce sera plutot en fonction de l'heure et/ou de l'humidité de la terre)
Le retour vers la GateWay se fait sous forme d'info binaire de bon ou de mauvais fonctionnement selon la logique suivante: si la vanne doit etre ouverte alors le débimètre doit tourner et dans ce cas, pas d'erreur (un zéro est renvoyé a la centrale) et inversement (après trois tentatives infructueuses).
Vu que je teste sur table, si je commande la vanne a la fermeture, il n'y a pas de débit et donc tout est OK
Mais si je demande une ouverture, alors un erreur doit etre renvoyée puisque le débimètre ne tourne pas....
Premier problème: En cas d'erreur, l'alarme n'est pas activée dans Domoticz
J'instancie les classes Mymessage de la façon suivante
Je présente mon node ainsi
Et la partie du code qui ne déclenche rien est le suivant:
La ligne send(errorEVMsg.set(1)); // Panne electrovanne est supposée déclancher le baculement du switch associé dans Domoticz mais ca ne marche pas alors que le moniteur série affiche:
Qu'est ce que je n'ai pas compris ?
(d'autres questions a venir car ceci est déjà bien assez long a lire)
PS: Le sketch mis a jour au fur et a mesure de son avancement comme conseillé plus bas dans ce fil de discussion:
Je vais encore avoir besoin de vos lumières;
J'ai quelques questions, mais avant tout je vous situe le sujet:
Je souhaite piloter une (pour commencer) électrovanne bistable et contrôler son bon fonctionnement.
J'utilise MySensors + Arduino pro-mini; J'y ajoute un Hbridge commandé par 2 sortie binaires (D4 et D5) et un débimètre low-cost connecté a la 2emme interruption (D3);
Dans l'attente du Hbridge, je connecte des leds sur D4 D5 et j'envoie des niveaux plutôt que des impulsions pour monitorer les états.
J'ai ecrit un petit bout de code pour vérifier le bon fonctionnement du débimètre (mesure débit et totalisateur de volume)
Et comme ca marche bien je l'intègre dans mon node.
Le node est commandé depuis Domoticz par un petit script en Blocky qui commande ouverture/fermeture en fonction de température (a terme, ce sera plutot en fonction de l'heure et/ou de l'humidité de la terre)
Le retour vers la GateWay se fait sous forme d'info binaire de bon ou de mauvais fonctionnement selon la logique suivante: si la vanne doit etre ouverte alors le débimètre doit tourner et dans ce cas, pas d'erreur (un zéro est renvoyé a la centrale) et inversement (après trois tentatives infructueuses).
Vu que je teste sur table, si je commande la vanne a la fermeture, il n'y a pas de débit et donc tout est OK
Mais si je demande une ouverture, alors un erreur doit etre renvoyée puisque le débimètre ne tourne pas....
Premier problème: En cas d'erreur, l'alarme n'est pas activée dans Domoticz
J'instancie les classes Mymessage de la façon suivante
Code : Tout sélectionner
MyMessage flowMsg(CHILD_ID_FLOW, V_FLOW);
MyMessage volMsg(CHILD_ID_VOLUME, V_VOLUME);
MyMessage errorEVMsg(CHILD_ID_EV_Status, V_STATUS);
Code : Tout sélectionner
void presentation()
{
sendSketchInfo("Arrosage", "1.0");// Send the sketch version information to the gateway and Controller
present(CHILD_ID_EV_Status, S_BINARY);
present (CHILD_ID_FLOW, S_WATER);
present(CHILD_ID_VOLUME,S_WATER);
present (CHILD_ID_STATUS,S_BINARY);
}Code : Tout sélectionner
void receive(const MyMessage &message)
{
if (message.getType()==V_STATUS) { // vérification de l'ordre
if (message.getBool()== true) { // Ordre d'ouverture
for (int i=1; i <= nbTentatives; i++) { // tentatives
myElectrovanne.off(); // TODO LIGNE TEST A SUPPRIMER
myElectrovanne.open(); // envoi d'un pulse de 50ms
Serial.println ("ouverture EV ");
// wait (dureePulseEV); // TODO OTER LE REM DE CES 2 LIGNES
// myElectrovanne.off();
wait (delayFlowMetre); // attente pleine ouverture
if (myDebimetre.actif == false){ // si pas bien ouverte
send(errorEVMsg.set(1)); // Panne electrovanne
Serial.println ("La vanne ne s'est pas ouverte ");
}
else{ .....et le log du GW dit:ouverture EV
La vanne ne s'est pas ouverte
ouverture EV
La vanne ne s'est pas ouverte
ouverture EV
La vanne ne s'est pas ouverte
Code : Tout sélectionner
2021-05-02 12:27:58.047 GiBi-Home: Temp (Temp N°2 (Serre tunnel))
2021-05-02 12:27:58.051 EventSystem: Event triggered: Script #1_2
2021-05-02 12:27:59.061 GiBi-Home: Light/Switch (Electrovanne (Serre tunnel))
2021-05-02 12:28:00.037 GiBi-Home: Light/Switch (Electrovanne (Serre tunnel))(d'autres questions a venir car ceci est déjà bien assez long a lire)
PS: Le sketch mis a jour au fur et a mesure de son avancement comme conseillé plus bas dans ce fil de discussion:
Code : Tout sélectionner
/*
Sketch MySensor pour activer et monitorer une électrovanne (d'arrosage)suivie d'un débimètre numérique.
Pour etre bien certain qu'une électtrovanne bistable se trouve dans la position voulue, il faut une information en retour
Un ordre donné par la centrale peut très bien etre arrivé a destination sans que l'électrovanne n'ait suivi;
Une solution consiste a monitorer le passage de l'eau au moyen d'un débimètre low-cost pour boucler le système.
BOM:
Electrovanne bistable (récup Gardena ou low-cost chinois)
Débimetre chinois a 450 impulsions par litre (https://fr.aliexpress.com/item/32873453373.html?spm=a2g0s.9042311.0.0.4f676c377Zowm9)
30 l.mn Max soit 225 Hz max (4.44ms de prériode mini entre 2 impulsions)
Pour les tests sur table, cabler led verte en pin 4 et led rouge en pin 5
En réel, cabler un pont en H (H-bridge) a la place des leds
Version 1.0 Initiale
Version 1.1
Version 1.2
*/
#define MY_RADIO_RF24 // Enable and select radio type attached
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#define MY_REPEATER_FEATURE // Repeater functionality valid (for far watering points)
#define CHILD_ID_EV_Cmd 0 // Commande de l'élecrovanne
#define CHILD_ID_EV_Status 1 // Status de l'Electro-Vanne
#define CHILD_ID_FLOW 2 // débit (non utilisé pour l'instant)
#define CHILD_ID_VOLUME 3 // volume
#include <MySensors.h>
#define DIGITAL_INPUT_SENSOR 3 // Entrée interruption du débimètre
#define Open_PIN 4 // Sortie H bridge vers électrovanne
#define Close_PIN 5 // Sortie H bridge vers électrovanne
//*******Options utilisateur**********
double ppl = 450; // ppl (Pulses per liter) comme défini pas la notice du capteur
double miniFlow = 0; // seuil de détection de débit (en tics par seconde)
byte nbTentatives = 3; // nombre de tentative pour ouvrir la vanne avant renvoi d'une erreur
byte dureePulseEV = 50; // (ms) durée de l'impulsion pour activer l'EV (CF notice fabriquant)
short delayFlowMetre = 1000; // (ms) tempo de mise en route du flot et donc du débimètre
//************************************
volatile unsigned int ticsCount = 0;
short pulseCount = 0;
uint32_t oldPulseCount = 0;
double flow = 0;
double vol=0;
double oldflow = 0;
double oldvolume =0;
MyMessage cmdMsg(CHILD_ID_EV_Cmd, V_STATUS);
MyMessage flowMsg(CHILD_ID_FLOW, V_FLOW);
MyMessage volMsg(CHILD_ID_VOLUME, V_VOLUME);
MyMessage errorEVMsg(CHILD_ID_EV_Status, V_TRIPPED);
class electrovanne {
private:
byte Open_Pin;
byte Close_Pin;
public:
bool position;
electrovanne (byte O_pin, byte C_pin){ // constructeur
Open_Pin = O_pin;
Close_Pin = C_pin;
init();
}
void init() {
pinMode(Open_Pin, OUTPUT);
pinMode(Close_Pin, OUTPUT);
off ();
}
void open(){
digitalWrite(Close_Pin, LOW);
digitalWrite(Open_Pin, HIGH);
}
void close() {
digitalWrite(Open_Pin, LOW);
digitalWrite(Close_Pin, HIGH);
}
void off() {
digitalWrite(Close_Pin, LOW);
digitalWrite(Open_Pin, LOW);
}
};
class debimetre {
private:
byte inputPin;
public:
bool actif = false;
double volume = 0;
double flow = 0;
debimetre(byte I_pin) { // constructeur
inputPin = I_pin;
init();
}
void init () {
pinMode (inputPin, INPUT);
}
};
debimetre myDebimetre(DIGITAL_INPUT_SENSOR); // Instanciation du débimètre
electrovanne myElectrovanne(Open_PIN,Close_PIN); // Instanciation de l'electrovanne
void setup(){
pinMode(DIGITAL_INPUT_SENSOR, INPUT_PULLUP); // pour etre certain de détecter un front descendant
pulseCount = oldPulseCount = 0;
attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), isr, FALLING);
Serial.begin(115200);
}
void presentation(){
sendSketchInfo("Arrosage", "1.0");// Send the sketch version information to the gateway and Controller
present(CHILD_ID_EV_Cmd, S_BINARY);
present(CHILD_ID_EV_Status, S_DOOR);
present (CHILD_ID_FLOW, S_WATER);
present(CHILD_ID_VOLUME,S_WATER);
}
//*************************************
void loop()
{
pulseCount = ticsCount; // sauvegarde et raz du compteur d'impulsions
ticsCount = 0;
vol = pulseCount/ppl; // débit par seconde
flow = vol*60; // débit en litres.minute
if (flow != oldflow) oldflow = flow; // calcul du débit instantané (en cas de besoin ultérieur)
if (pulseCount != 0) { // En cas de mesure...
oldPulseCount = oldPulseCount + pulseCount;
myDebimetre.volume = ((double)oldPulseCount/((double)ppl));
pulseCount=0;
myDebimetre.actif = true;
// Serial.println ("OUVERT");
}
else {
myDebimetre.actif = false;
// Serial.println ("FERME");
}
delay(1000); // une mesure par seconde
}
//*************************************
//*************************************
void isr()
{
ticsCount++;
}
//*************************************
//*************************************
void receive(const MyMessage &message)
{
if (message.getType()==V_STATUS) { // vérification du type de msg
if (message.getBool()== true) { // Ordre d'ouverture
for (int i=1; i <= nbTentatives; i++) { // tentatives...
myElectrovanne.off(); // TODO (ligne pour test sur table à supprimer)
myElectrovanne.open(); // envoi d'un pulse de 50ms
// Serial.println ("ouverture EV ");
// wait (dureePulseEV); // TODO(mis en rem pour test sur table)
// myElectrovanne.off();
wait (delayFlowMetre); // attente pleine ouverture
if (myDebimetre.actif == false){ // si pas bien ouverte...
send(errorEVMsg.set(1)); // Panne electrovanne
// Serial.println ("La vanne ne s'est pas ouverte ");
}
else{
send(errorEVMsg.set(0)); // Electrovanne OK
// Serial.println ("La vanne s'est bien ouverte ");
break;
}
}
}
else { // Orde de fermeture
for (int i=1; i <= nbTentatives; i++) { // tentatives
myElectrovanne.off(); // TODO LIGNE TEST A SUPPRIMER (ou mettre en rem)
myElectrovanne.close(); // envoi d'un pulse de 50ms
// Serial.println ("fermeture EV ");
// wait (dureePulseEV); // TODO
// myElectrovanne.off();
wait (delayFlowMetre); // attente pleine ouverture
if (myDebimetre.actif == true) { // si pas bien fermée
send(errorEVMsg.set(1)); // En voie d'une alerte Panne electrovanne
Serial.println ("La vanne ne s'est pas fermée ");
}
else{
// Serial.println (myDebimetre.volume);
send(volMsg.set(myDebimetre.volume,1));
send(errorEVMsg.set(0)); // Electrovanne OK
// Serial.println ("La vanne s'est bien fermée ");
myDebimetre.volume=0; // RAZ du volumed'eau qui est passé durant la période ouverte
myDebimetre.flow=0; // RAZ du débit
break;
}
}
// TODO sleep(.....) // faire dormir le node et envoyer un hartbeat au réveil...
}
}
}