Bonjour, Voici mon projet :
Je voudrais avec un arduino nano 33 IOT, avoir un relever de température, contrôler la pression hydraulique à la sortie d'une pompe et pouvoir contrôler deux relais avec deux boutons poussoirs.
toute ces info seront consultable avec l'application blynk.
Je rencontre un problème pour programmer mes bouton poussoirs et me relais. Apres plusieur essaie et recherche j'ai vue que je dois utilisé la technique de "automate fini" / "state machine fonction"
Pour moi c'est un peu compliquer cette technique. J'ai besoin de votre aide.
Vous trouverer ci-dessou mon code. Je me suis inspierer de cette vidéo : vidéo Youtube
Quand j'appuie sur mon bouton poussoir, le relais ce met a clignoter très rapidement. Des que je le relâche il ne reste pas dans une position. Ce que je voudrais c'est que si j'appuie une fois et que je relâche le relais se ferme et si je rappuie et relâche une second fois le relais s'ouvre. Un système de marche arrêt.
Avez vous une solution ?
int state_s1 = 0;
int state_prev_s1 = 0;
int pin_s1 = 2;
int val_s1=0;
unsigned long t_s1 = 0;
unsigned long t_0_s1 = 0;
unsigned long bounce_delay_s1=5;
const int RELAIS1=4;
boolean etatRelais1=1;
void setup() {
// put your setup code here, to run once:
pinMode(pin_s1,INPUT_PULLUP);
pinMode(RELAIS1, OUTPUT);
Serial.begin(115200);
}
void loop() {
// put your main code here, to run repeatedly:
SM_relaiA();
if(state_s1 == 4){
Serial.println("triggered!!!");
etatRelais1=!etatRelais1; // inverse l'état du relais
digitalWrite(RELAIS1,etatRelais1);
}
if (state_s1 != state_prev_s1){
Serial.print("state= ");
Serial.println(state_s1);
}
}
void SM_relaiA (){
state_prev_s1 = state_s1;
switch(state_s1){
case 0 :
state_s1 = 1;
break;
case 1 :
val_s1 = digitalRead(pin_s1);
if ( val_s1 == LOW) {state_s1 = 2;}
break;
case 2 :
t_0_s1 = millis();
state_s1 = 3;
break;
case 3 :
val_s1 = digitalRead(pin_s1);
t_s1 = millis();
if (val_s1 == HIGH) {state_s1;}
if (t_s1 - t_0_s1 > bounce_delay_s1){
state_s1 = 4;
}
break;
case 4 :
state_s1 = 0;
break;
case 5 :
val_s1 = digitalRead(pin_s1);
if(val_s1 == HIGH)(state_s1 = 4);
break;
}
}
hello
j'ai essayé te t'expliquer par écrit, mais c'est vite devenu imbitab.e
alors j'ai fais au plus simple.
nota: je n'ai vu qu'un relais
a tester
pour le relais, j'ai déclaré sur 13 pour avoir la led
pour le serial print, il est en 1000000 de bauds
int etat_S1 = 0;
int etat_precedent_S1 = 0; //pour autoriser affichage sur moniteur
int BP_S1 = 2;
int Val_BP_S1 = 0;
unsigned long t_s1 = 0;
unsigned long t_0_s1 = 0;
unsigned long bounce_delay_s1 = 30;
const int RELAIS1 = 13;
//const int RELAIS1 = 4;
boolean etatRelais1 = 1;
void setup()
{
// put your setup code here, to run once:
pinMode(BP_S1, INPUT_PULLUP);
pinMode(RELAIS1, OUTPUT);
Serial.begin(1000000);
}
void loop()
{
// put your main code here, to run repeatedly:
SM_relaiA();
if (etat_S1 == 5) {
Serial.println("triggered!!!");
etatRelais1 = !etatRelais1; // inverse l'état du relais
digitalWrite(RELAIS1, etatRelais1);
}
if (etat_S1 != etat_precedent_S1)//affichage sur moniteur autorisé
{
Serial.print("state= ");
Serial.println(etat_S1);
}
}
void SM_relaiA () {
etat_precedent_S1 = etat_S1; //memorise etat_S1
switch (etat_S1)
{
case 0 : //sans appui sur BP=> etat_S1++ ???
etat_S1 = 1;Serial.println("case 0 =>1");
break;
case 1 : //boucle suivante
Val_BP_S1 = digitalRead(BP_S1); //on guette le 1er appui sur BP
if ( Val_BP_S1 == LOW) {Serial.println("case 1 =>2");
etat_S1 = 2; //et si BP enfoncé, etat_S1++
}
break;
case 2 : //boucle suivante
t_0_s1 = millis(); //relevé de l'heure
etat_S1 = 3; // et etat_S1++
Serial.println("case 2 =>3");
break;
case 3 : //boucle suivante
Val_BP_S1 = digitalRead(BP_S1); //lecture entree BP
if (Val_BP_S1 == HIGH)
{
t_s1 = millis(); //si BP relaché relevé de l'heure
etat_S1 = 4;Serial.println("case 3 =>4");
}
break;
case 4 : //5eme appui sur BP
if ((millis() - t_0_s1) > bounce_delay_s1)
{
etat_S1 = 5;Serial.println("case 4 =>5 car anti-rebonds terminé");
}
break;
case 5 :
etat_S1 = 0;Serial.println("case 5 =>0");
break;
}
}
Juste une dernière question, pour mon deuxième relais, est ce que je dois creer un "void SM_relaiB ()"
ou rajouter des ligne dans le "void SM_relaiA ()" ?
J'ai réussi a mettre les deux relais et il marche bien avec les boutons poussoir.
Je vais encore avoir besoin de ton aide.
je voudrais savoir a quel endroit je dois rajouter les ligne de code pour un capteur de température, et un capteur de pression sans que ça change le fonctionnement de mes relais et des boutons.
hello
ton code
il fonctionne
il y avait des "delay"qui ne favorisaient pas la prise en compte des appuis sur le BP
j'ai ajouter une fréquence de lecture des températures à 1Hz
mais est ce nécessaire de les lire si souvent?
comme je n'ai que deux DS1821, j'ai neutralisé les lignes pour la troisième sonde
#include <OneWire.h>
unsigned long periode_lecture_temp =0;
//relais 1 et bouton poussoir
int etat_S1 = 0;
int etat_precedent_S1 = 0; //pour autoriser affichage sur moniteur
int BP_1 = 2; //bouton poussoir en d2
int Val_BP_S1 = 0;
unsigned long t_s1 = 0;
unsigned long t_0_s1 = 0;
unsigned long bounce_delay_s1 = 30;
const int RELAIS1 = 7;//relais en d7
//const int RELAIS1 = 4;
boolean etatRelais1 = 1;
//relais 2 et bouton poussoir
int etat_S2 = 0;
int etat_precedent_S2 = 0; //pour autoriser affichage sur moniteur
int BP_2 = 3; //boutton poussoir en d3
int Val_BP_S2 = 0;
unsigned long t_s2 = 0;
unsigned long t_0_s2 = 0;
unsigned long bounce_delay_s2 = 30;
const int RELAIS2 = 6; //relais en d6
//const int RELAIS1 = 4;
boolean etatRelais2 = 1;
// temperature
const byte BROCHE_ONEWIRE = 8;//Broche du bus 1-Wire
/* Code de retour de la fonction getTemperature() */
enum DS18B20_RCODES
{
READ_OK,
NO_SENSOR_FOUND,
INVALID_ADDRESS,
INVALID_SENSOR
};
/* Création de l'objet OneWire pour manipuler le bus 1-Wire */
OneWire ds(BROCHE_ONEWIRE);
byte getTemperature(float *temperature, byte reset_search)
{
byte data[9], addr[8];
// data[] : Données lues depuis le scratchpad
// addr[] : Adresse du module 1-Wire détecté
/* Reset le bus 1-Wire ci nécessaire (requis pour la lecture du premier capteur) */
if (reset_search) {//Serial.println("1_ds.reset_search() ");
ds.reset_search();
}
/* Recherche le prochain capteur 1-Wire disponible */
if (!ds.search(addr)) {//Serial.println("0_ds.reset_search() ");
// Pas de capteur
return NO_SENSOR_FOUND;
}
/* Vérifie que l'adresse a été correctement reçue */
if (OneWire::crc8(addr, 7) != addr[7]) {Serial.println("mauvaise adresse ");
// Adresse invalide
return INVALID_ADDRESS;
}
/* Vérifie qu'il s'agit bien d'un DS18B20 */
if (addr[0] != 0x28) {//Serial.println("mauvais capteur ");
// Mauvais type de capteur
return INVALID_SENSOR;
}
/* Reset le bus 1-Wire et sélectionne le capteur */
ds.reset();//Serial.println("ds.reset(); ");
ds.select(addr);//Serial.println("ds.select(addr); ");
/* Lance une prise de mesure de température et attend la fin de la mesure */
ds.write(0x44, 1);//Serial.println("ds.write(0x44, 1); ");
//delay(800);
/* Reset le bus 1-Wire, sélectionne le capteur et envoie une demande de lecture du scratchpad */
ds.reset();//Serial.println("ds.reset(); ");
ds.select(addr);//Serial.println("ds.select(addr); ");
ds.write(0xBE);//Serial.println("ds.write(0xBE, 1); ");
/* Lecture du scratchpad */
for (byte i = 0; i < 9; i++) {
data[i] = ds.read();//Serial.println("ds.read(); 8fois ");
}
/* Calcul de la température en degré Celsius */
*temperature = (int16_t) ((data[1] << 8) | data[0]) * 0.0625;//Serial.println("température en degré Celsius ");
// Pas d'erreur
return READ_OK;
}
void setup()
{
pinMode(BP_1, INPUT_PULLUP);
pinMode(RELAIS1, OUTPUT);
pinMode(BP_2, INPUT_PULLUP);
pinMode(RELAIS2, OUTPUT);
Serial.begin(1000000);
periode_lecture_temp = millis();
}
void loop()
{
SM_relaiA();
SM_relaiB();
if ((millis()-periode_lecture_temp)>1000)//lecture toutes les secondes
{
periode_lecture_temp=millis();
SM_temperature ();
}
}
void SM_relaiA () {
etat_precedent_S1 = etat_S1; //memorise etat_S1
switch (etat_S1)
{
case 0 : //sans appui sur BP=> etat_S1++ ???
etat_S1 = 1; Serial.println("case 0 =>1");
break;
case 1 : //boucle suivante
Val_BP_S1 = digitalRead(BP_1); //on guette le 1er appui sur BP
if ( Val_BP_S1 == LOW) {
Serial.println("case 1 =>2");
etat_S1 = 2; //et si BP enfoncé, etat_S1++
}
break;
case 2 : //boucle suivante
t_0_s1 = millis(); //relevé de l'heure
etat_S1 = 3; // et etat_S1++
Serial.println("case 2 =>3");
break;
case 3 : //boucle suivante
Val_BP_S1 = digitalRead(BP_1); //lecture entree BP
if (Val_BP_S1 == HIGH)
{
t_s1 = millis(); //si BP relaché relevé de l'heure
etat_S1 = 4; Serial.println("case 3 =>4");
}
break;
case 4 : //5eme appui sur BP
if ((millis() - t_0_s1) > bounce_delay_s1)
{
etat_S1 = 5; Serial.println("case 4 =>5 car anti-rebonds terminé");
}
break;
case 5 :
Serial.println("triggered!_____11111111111111111111111111111111111_!");
//delay(2000);
etatRelais1 = !etatRelais1; // inverse l'état du relais
digitalWrite(RELAIS1, etatRelais1);
etat_S1 = 0; Serial.println("case 5 =>0");
break;
}
if (etat_S1 != etat_precedent_S1)//affichage sur moniteur autorisé
{
Serial.print("state= ");
Serial.println(etat_S1);
}
}
void SM_relaiB () {
etat_precedent_S2 = etat_S2; //memorise etat_S1
switch (etat_S2)
{
case 0 : //sans appui sur BP=> etat_S1++ ???
etat_S2 = 1; Serial.println("case 0 =>1");
break;
case 1 : //boucle suivante
Val_BP_S2 = digitalRead(BP_2); //on guette le 1er appui sur BP
if ( Val_BP_S2 == LOW) {
Serial.println("case 1 =>2");
etat_S2 = 2; //et si BP enfoncé, etat_S1++
}
break;
case 2 : //boucle suivante
t_0_s2 = millis(); //relevé de l'heure
etat_S2 = 3; // et etat_S1++
Serial.println("case 2 =>3");
break;
case 3 : //boucle suivante
Val_BP_S2 = digitalRead(BP_2); //lecture entree BP
if (Val_BP_S2 == HIGH)
{
t_s2 = millis(); //si BP relaché relevé de l'heure
etat_S2 = 4; Serial.println("case 3 =>4");
}
break;
case 4 : //5eme appui sur BP
if ((millis() - t_0_s2) > bounce_delay_s2)
{
etat_S2 = 5; Serial.println("case 4 =>5 car anti-rebonds terminé");
}
break;
case 5 :
Serial.println("triggered!_____222222222222222222222222222222222_!");
//delay(2000);
etatRelais2 = !etatRelais2; // inverse l'état du relais
digitalWrite(RELAIS2, etatRelais2);
etat_S2 = 0; Serial.println("case 5 =>0");
break;
}
if (etat_S2 != etat_precedent_S2)//affichage sur moniteur autorisé
{
Serial.print("state= ");
Serial.println(etat_S2);
}
}
void SM_temperature ()
{
float temperature[3];
if (getTemperature(&temperature[0], true) != READ_OK)
{
Serial.println(F("Erreur de lecture du capteur 1"));
return;
}
if (getTemperature(&temperature[1], false) != READ_OK)
{
Serial.println(F("Erreur de lecture du capteur 2"));
return;
}
/*
if (getTemperature(&temperature[2], false) != READ_OK)
{
Serial.println(F("Erreur de lecture du capteur 3"));
return;
}
*/
/* Affiche les températures */
Serial.print(F("Temperatures : "));
Serial.print(temperature[0], 2);
Serial.print("°"); //Serial.write(176); // Caractère degré
Serial.print(F("C, "));
Serial.print(temperature[1], 2);
Serial.print("°"); // Caractère degré
Serial.println(F("C, "));
/*
Serial.print(temperature[2], 2);
Serial.write(176); // Caractère degré
Serial.println('C');
*/
}
merci énormément, je voudrais rajouter, sur un des deux relais une led rouge quand le relais est ouvert et une led verte quand le relais est fermer. pourais-tu me dire ou je dois rajouter le code, et accorder la couleur des led en fonction de la position du relais.
Ce que je voudrai, c'est que lorsque je clique sur le bouton dans application le relais s'actionne, et si je clique sur le bouton poussoir (physique), dans application il est écrit on / off en fonction de la position du relais.
faire comme dans cette video : lien vidéo youtube
est ce que tu crois que c'est possible avec mon code ??