Probleme de pilotage relais pompe

Bonjour très chers bidouilleurs et autres experts de ce fabuleux outil,

Mon expertise limité m'impose aujourd'hui de poster une question et d'appeler à l'aide :face_with_peeking_eye:
Je souhaite réaliser un projet de pilotage d'une pompe selon un delta de capteur de température (S1 Vs S2) pour une installation de chauffage.
Je planche et stagne depuis de nombreuses heures sur le fait que mon relais reste après de bref switch d'initialisations (que je ne comprends d'ailleurs pas) définitivement allumé le code conditionnel (if / else if) fonctionne seulement sur le principe et le textuel mais pas le relais.
Si quelqu'un arrive à m'expliquer le problème ou a une solution je suis tout oui

merci d'avance

voici le code complet :

// include libraries
#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into pin 13 on the Arduino
#define ONE_WIRE_BUS 13 // Arduino pin connected to DS18B20 sensor's DQ pin
#define precision 12 //onewire precision dallas sensor
//const int digPin = 12;

int sen_number = 0; //counter of Dallas sensors
int S1TempC, S2TempC, S3TempC, S4TempC;
int Ch_Pump = 6;   //Relay pump pin

// flow measurement definition
int flowPin = 2;  //This is the input pin on the Arduino
double flowRate;  //This is the value we intend to calculate.
volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.


OneWire oneWire(ONE_WIRE_BUS);  // Setup a oneWire instance to communicate with devices
DallasTemperature sensors(&oneWire); // pass oneWire to DallasTemperature library
DeviceAddress T1, T2, T3, T4;// arrays to hold device adresses
//float tempCelsius;    // temperature in Celsius
//float tempFahrenheit; // temperature in Fahrenheit

void setup()
{
  Serial.begin(9600); // initialize serial



  // put your setup code here, to run once:
  pinMode(flowPin, INPUT);           //Sets the pin as an input
  attachInterrupt(0, Flow, RISING);  //Configures interrupt 0 (pin 2 on the Arduino Uno) to run the function "Flow"
pinMode(Ch_Pump, OUTPUT);
digitalWrite(Ch_Pump, LOW);
    sensors.begin();    // initialize the sensor
  
Serial.print("*Temp Sensor:* ");
Serial.print("Found: ");


Serial.print(sensors.getDeviceCount(), DEC);
Serial.println(" Devices.");


// report parasite power requirements
Serial.print("Parasite power is: ");
if (sensors.isParasitePowerMode()) Serial.println("ON");
else Serial.println("OFF");
        
// Search for devices on the bus and assign based on an index.
if (!sensors.getAddress(T1, 0)) Serial.println("Not Found Sensor 1");
if (!sensors.getAddress(T2, 1)) Serial.println("Not Found Sensor 2");
if (!sensors.getAddress(T3, 2)) Serial.println("Not Found Sensor 3");
if (!sensors.getAddress(T4, 3)) Serial.println("Not Found Sensor 4");

//show the addresses we found on the bus
for (int k =0; k < sensors.getDeviceCount(); k++) {
Serial.print("Sensor "); Serial.print(k+1);
Serial.print(" Address: ");
if (k == 0) { printAddress(T1); Serial.println();}
 else if (k == 1) { printAddress(T2); Serial.println();}
 else if (k == 2) { printAddress(T3); Serial.println();}
 else if (k == 3) { printAddress(T4); Serial.println();}
}

// set the resolution to 12 bit per device
sensors.setResolution(T1, precision);
sensors.setResolution(T2, precision);
sensors.setResolution(T3, precision);
sensors.setResolution(T4, precision);

for (int k =0; k < sensors.getDeviceCount(); k++) {
Serial.print("Sensor "); Serial.print(k+1);
Serial.print(" Resolution(best=12 bit): ");
if (k == 0) { Serial.print(sensors.getResolution(T1), DEC); Serial.println();
} else if (k == 1) { Serial.print(sensors.getResolution(T2), DEC); Serial.println();
} else if (k == 2) { Serial.print(sensors.getResolution(T3), DEC); Serial.println();
} else if (k == 3) { Serial.print(sensors.getResolution(T4), DEC); Serial.println();
}
}
Serial.println("Flow sensor in use YF-S201 (1-30l/min)"); 
}


// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
for (uint8_t i = 0; i < 8; i++)
{
//zero pad the address if necessary
if (deviceAddress[i] < 16) Serial.print("0");
Serial.print(deviceAddress[i], HEX);
}
}
// function to print the temperature for a device
void printTemperature(DeviceAddress deviceAddress)
{
float tempC = sensors.getTempC(deviceAddress);
Serial.print(",Temp.[°C]|[°F]:, ");
Serial.print(tempC);
//Serial.print("  °C  ");
Serial.print(" , ");        // separator between Celsius and Fahrenheit
Serial.print(DallasTemperature::toFahrenheit(tempC));
Serial.print(" , ");
//Serial.print("  °F  ");
}


// function to print a device's resolution
//void printResolution(DeviceAddress deviceAddress)
//{}


void printData(DeviceAddress deviceAddress)
{
Serial.print(" Address: ");
printAddress(deviceAddress);
Serial.print(" ");
printTemperature(deviceAddress);
//Serial.println();
}
 



void loop()
{
float S1TempC = sensors.getTempC(T1);
float S2TempC = sensors.getTempC(T2);
float S3TempC = sensors.getTempC(T3);
float S4TempC = sensors.getTempC(T4);
 digitalWrite(Ch_Pump, LOW);

  count = 0;      // Reset the counter so we start counting from 0 again
  interrupts();   //Enables interrupts on the Arduino
  
// call sensors.requestTemperatures() to issue a global temperature request to all devices on the bus
//Serial.print("Reading DATA..."); 
sensors.requestTemperatures(); 
//Serial.println("DONE");
// print the device information
for (int k =0; k < sensors.getDeviceCount(); k++) {
Serial.print("Sensor "); Serial.print(k+1); Serial.print(",");
if (k == 0) { printData(T1);}
 else if (k == 1) { printData(T2);}
 else if (k == 2) { printData(T3);}
 else if (k == 3) { printData(T4);}
}
if (sen_number == sensors.getDeviceCount()) {
sen_number = 0; // reset counter
}


// ***Pump Managment***

//Serial.print("S1TempC: ");Serial.print(S1TempC);Serial.print(" ");
//Serial.print("S2TempC: ");Serial.print(S2TempC);Serial.print(" ");
//Serial.print("S3TempC: ");Serial.print(S3TempC);Serial.print(" "); // verif. fonc. variables SxTempC
//Serial.print("S4TempC: ");Serial.print(S4TempC);Serial.print(" ");


if ((S1TempC > S2TempC)) // if temp S1 (Bath sensor) superior than S2 (Prim.heat echangeur entry) then Turn pump ON
{
 **digitalWrite(Ch_Pump, LOW);**
 Serial.print("chaleur : S1-secondire> Entrée.ECH PUMP ON --> ");
}
else if(S1TempC > S2TempC) 
{
**digitalWrite(Ch_Pump, HIGH);**
 Serial.print("chaleur : S1-secondaire> Entrée.ECH PUMP ON --> ");
 }
}



//Serial.print("Sensor Number="); Serial.println(sen_number);
delay(30000); // give the time between each temp measure and used for rotation calculation --> 10.000 = 10sec
noInterrupts(); //Disable the interrupts on the Arduino

  //Start the math of Flow measurement
  flowRate = (count * 2.236);        //rotation determination : Take counted pulses(rotation) in the last "delay" period and multiply by 2.236mL (mean of info found over internet 2,22 2,5ml/rotation)
  flowRate = flowRate * 2;         //time conversion : Convert "delay period" to minutes, giving you mL / Minute
  flowRate = flowRate / 1000;       //Convert mL to Liters, giving you Liters / Minute


 //Flow measurement indication
Serial.print("Flow YF-S201 [l/min]:, ");  
Serial.println(flowRate);         //Print the variable flowRate to Serial in l/min
//Serial.print("  l/min");  
//Serial.println("  - normal pump flow 13,3l/min");  
//sen_number++ ;
}

void Flow()
{
   count++; //Every time this function is called, increment "count" by 1
}

:warning:
Post mis dans la mauvaise section, on parle anglais dans les forums généraux. déplacé vers le forum francophone.

Merci de prendre en compte les recommandations listées dans Les bonnes pratiques du Forum Francophone

Première étape: Est-ce que le problème est logiciel ou matériel ?
Est-ce que la sortie logique de l'Arduino fonctionne conformément au attentes ?
Si non: problème logiciel -> revoir le code
Si oui: problème matériel -> voir la suite.

Deuxième étape: si problème matériel est-ce que le problème viens de la commande ou de la puissance ?
Là, il faudrait un schéma électrique.

Côté câblage, j'ai pu revérifié tout est ok, 5VDC GND + signal sur la bonne entrée.
J'ai tenté changé d'entrée pour voir, même résultat.
La pompe fonctionne également, l'ensemble a été vérifié au voltmètre-
Le code semble il correct ? je pencherais plutôt la dessus

au passage pour la modération du forum : désolé pour mon erreur d'adressage.

J'ai pu trouver mon soucis via un second post du côté anglophone (plus actif) :
pour les éventuelles personnes ayant un soucis de relais, attention il faut prendre en compte qu'un contact NO ou NC peut être /x (inversé) avec la notion HIGH / LOW.
dans mon exemple :
contact voulu et connecté sur la platine = NO
Utilisation "pensée" du HIGH pour avoir un front montant = 1 -> fermeture de la passerelle du relais.
Cependant par je ne sais quelle raison technique le HIGH me connectait la sortie NC à l'inverse de ce que je pensais logique.
soit pour le debug. : en cas de soucis penser à tester l'inverse des états ex. HIGH au lieux de LOW pour l'ensemble du code.

Bonjour fredz6732

Dans ton cas, il fallait d'abord regarder le schéma de ton relais, il y en a 2 sortes, avec optocoupleur et sans optocoupleur.

Avec, c'est actif à LOW
image
Sans optocoupleur, c'est actif à HIGH
image
On reconnais les versions à optocoupleur au petit circuit à 4 patte (opto)s:
image

Cordialement
jpbbricole

Il faudrait aussi jeter un œil là-dessus. Parce qu'avec ces tests, tu n'es pas prêt de couper le relais.

Normalement Ouvert et normalement Fermé n'a rien à voir avec l'état à l'entrée de la carte. Cela concerne l'état du relais lorsqu'il n'est pas excité (comprendre hors tension).
Il y a effectivement plusieurs types de cartes dans le commerce qui se ressemblent plus ou moins. Et les vendeurs ne sont pas toujours très bavards dans la description des produits qu'ils vendent.
Le plus simple est de faire un essai avec un programme simple pour déterminer comment sont pilotés les relais.

en effet, je n'ai pas donnée la version la plus juste autant pour moi. j'ai depuis corrigé l'erreur. :slight_smile:
Cette histoire d'optocoupleur reste encore un mystère pour moi, de quoi s'agit il? un relais haute fréquence ?

Bonjour fredz6732

Non, c'est simplement une transmission de signal, HIGH/LOW dans ton cas, avec des signaux lumineux. De cette façon, il n'y a pas de liaison électrique entre l'Arduino et la partie relais (isolation galvanique).
Il faut, bien sûre, ne pas connecter le GND de l'Arduino avec le GND de la carte relais. Uniquement connecter le signal de l'Arduino (Ch_Pump dans ton cas) et le +5V de l'Arduino avec le VCC de la carte relais.
Ceci évite l'influence, parfois néfaste, entre les 2 parties.
Un peu de lecture

Cordialement
jpbbricole

Sur un module relais, une première isolation galvanique est assurée par le relais lui même.
Il n'y a aucune liaison électrique entre la bobine et les contacts du relais, et l'isolation galvanique est d'au moins 1000V, pour les plus courants.
Un module relais avec opto-coupleur n'apporte rien de plus, sinon une isolation galvanique supérieure (5000V), mais pour assurer 5000V d'isolation la carte devrait être étudiée pour (une fente entre émetteur et récepteur), ce qui est rarement le cas.
Ici à droite, un opto avec ce que l'on appelle un "air gap" :

Donc, la présence d'un opto est loin d'être essentielle.

Que ce soit avec ou sans opto-coupleur, il existe des modules relais actifs au niveau bas (les plus courants) ou au niveau haut. D'autre sont personnalisables à l'aide d'un cavalier.

Celui-ci est activable sur niveau bas, sans opto :


Par contre pour piloter une pompe ou un moteur 230V, un snubber s'avère souvent nécessaire :
https://forum.arduino.cc/t/charge-inductive-et-parasites/596348
Si lors des ouvertures de contacts tu constates des dysfonctionnements (plantage, reboot), mets en place un snubber.

Je pensais que la liaison des GND était un impératif pour le bon fonctionnement entre les divers modules (RTC, écran etc) et la carte Arduino.
Ce n.est pas le cas pour les cartes relais ?

Bonsoir EGT59

Pour ces exemples, c'est indispensable.

Ce n'est pas le cas pour les cartes relais à optocoupleur, si tu mets le GND, ça veut dire que le GND de l'Arduino et le GND de l'alimentation des relais sont communs, l'isolation galvanique n'est plus assurée et, de par là, l'optocoupleur ne "sert plus".
Regardes le schéma du post #6 (celui du haut), tu verras que le GND n'est pas utile.

Cordialement
jpbbricole

On va essayer de clarifier.

A aucun moment fredz6732 n'a donné la moindre indication à propos du module relais utilisé (avec opto ou sans), ni à propos de l'alimentation, ni fourni de schéma.

S'il s'agit d'un module avec opto, et si l'on veut obtenir une isolation galvanique entre l'ARDUINO et la partie commande de la bobine, il faudrait disposer de deux alimentations totalement séparées, la première reliée à l'ARDUINO, la deuxième reliée au module relais entre GND et JD-VCC, et il faudrait ne pas utiliser GND côté ARDUINO.

Dans le cas présent, il y a de fortes chances pour que l'alimentation soit commune, et en 5V.
Donc je ne vois pas par quel miracle ou tour de magie il pourrait exister une isolation galvanique entre un ARDUINO et un module relais se partageant la même alimentation.

Et quand bien même il y aurait deux alimentations séparées, on voit mal l'intérêt de vouloir obtenir une isolation galvanique entre une alimentation 5V et une autre alimentation 5V. Mais pourquoi pas ? rien ne l'interdit. Peut-être qu'avec un ou plusieurs module à 16 relais cela apporterait une meilleure immunité aux perturbations sur l'alimentation.

S'il s'agissait d'un module relais à bobine 230V, commandé par un opto-triac, je comprendrais l'utilité de l'isolation galvanique. Personne n'a envie de se prendre une châtaigne 230V en touchant un ARDUINO relié à la phase.

En conclusion, si fredz6732 possède un module relais 5V à opto (ce qui est probable), il peut parfaitement le relier à l'ARDUINO à l'aide du connecteur d'entrée : GND, VCC, IN1 IN2, etc.

Le connecteur JD-VCC, VCC, GND a une seule utilité : pouvoir alimenter un module relais pourvu de relais à bobine 12V ou 24V.
Mais même dans ce cas, deux alimentations séparées ne sont pas obligatoires. On peut tout à fait alimenter un ARDUINO sous 12V, en respectant le courant maximal sur ses sorties, ou sous 24V à travers un régulateur. Et dans ce cas, la masse est commune, donc aucune isolation galvanique n'est possible.

Donc, dire que grâce à l'optocoupleur, il n'y a pas de liaison électrique entre l'ARDUINO et la partie commande de bobine est faux. Ce n'est pratiquement jamais le cas, sauf si l'on dispose de deux alimentations totalement séparées.

Ou des modules de relais pourvus de relais à bobine 5V si l'on veut séparer les alimentions.

[quote="hbachetti, post:14, topic:968716"]
Donc, dire que grâce à l'optocoupleur, il n'y a pas de liaison électrique entre l'ARDUINO et la partie commande de bobine est faux.[/quote]
Alord, à quoi sert cet optocoupleur?

!!! Dans tout les cas où c'est des relais autres que des 5V et ou que l'on ne veut pas alimenter des relais à bobine 5V. depuis l'alimentation de l'Arduino.

Tout ça pour dire que mon explication du post #13 tendait à répondre à la question:

Dans le cas de modules relais avec optocoupleurs la liaison GND ne sert à rien dans le bon fonctionnement de la commande des relais,
image
contrairement à la majorité des autres cartes interface où cette liauioson est indispensable.

Cordialement
jpbbricole

A rien, sauf si l'on dispose de deux alimentations totalement séparées, sans masse commune, et surtout si l'on croit que l'isolation galvanique est nécessaire.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.