Récupérer une valeur avec un bouton poussoir

Bonjour la communauté,

Malgré mes recherches sur internet et mes livres arduino je ne trouve pas la réponse à cette question.

Est-il possible de récupérer une valeur (la stocker) avec un bouton poussoir?

Mon projet est très simple "pour vous" j'imagine.
Un capteur d'humidité pour le sol me donne une valeur ex: 55%, je souhaite garder cette valeur en appuyant sur un bouton. Je la garde pour l'utiliser plus tard comme référence à ne pas dépasser. Un autre jour une humidité de 75% me convient mieux, j'appuie et elle devient ma référence à ne pas dépasser.

J'ai fait mon schéma et le code de base pour utiliser mon capteur. Cela fonctionne très bien mais maintenant je voudrais y ajouter cette fonction et je galère.

Sauriez-vous m'aider ou m'orienter!?

Merci :wink:

Bonsoir viseo

Tu devrai poster ton code pour que l'on puisse voire comment y "caser" un bouton.

Cordialement
jpbbricole

Bonsoir jpbbricole,

// C++ code
//


int ref;
int capteur = A2;
int LED1 = 2;
int LED2 = 3;


void setup()
{
  	Serial.begin (9600);
	pinMode (LED1, OUTPUT);
  	pinMode (LED2, OUTPUT);
}
  
void loop()
{
  ref = analogRead(capteur);
  
  if (ref < 55) //Si humidité inférieur à 55% LED verte allumée
  {
    Serial.println (ref);
    digitalWrite (LED1, HIGH);
    digitalWrite (LED2, LOW);
  }
  else  // Autrement LED rouge allumée
  {    
    Serial.println (ref);
   	digitalWrite (LED2, HIGH); 
    digitalWrite (LED1, LOW); 
  }
  delay (100);
}

Actuellement je dois indiquer une valeur de référence (55 dans mon exemple) avec mon IF pour faire allumer la LED verte ou rouge.
Je voudrais utiliser un bouton pour stocker la valeur du analogRead et m'en servir pour indiquer que celle-ci +10% fait allumer la LED rouge.

Je suis sur un site qui explique comment stocker une valeur dans l'EEPROM. Dois-je m'orienter dans cette direction?

Oui c'est une très bonne idée. La valeur sera sauvegardée dans l'EEPROM comme ça même si l'alimentation de la carte est coupée, au démarrage le programme pourra retrouver la valeur.

Merci. Je focus sur cette méthode. J'ai bidouillé un truc :confused: mais ça ne fonctionne pas ... pour l'instant :slight_smile:

// C++ code
//

#include <EEPROM.h>

int capteur = A2;
int LED1 = 2;
int LED2 = 3;
int etatbouton = 0;
int bouton = A1;
int adresse = 100;
byte ref;
byte alert;

void setup()
{
  	Serial.begin (9600);
	pinMode (LED1, OUTPUT);
  	pinMode (LED2, OUTPUT);
  	pinMode (bouton, INPUT_PULLUP);
}
  
void loop()
{
  etatbouton = analogRead(bouton);
  	ref = analogRead(capteur);
  		alert = ref+10;


if (bouton = LOW)
{
  EEPROM.write(adresse, ref);
  	digitalWrite (LED1, HIGH);
  		digitalWrite (LED2, LOW);
}


  else  // Autrement LED rouge allumée
  {    
    	EEPROM.read(adresse);
    		ref>alert;    
   				digitalWrite (LED2, HIGH); 
    				digitalWrite (LED1, LOW); 
  }
  delay (100);
}

Bonsoir viseo

Il est préférable d'utiliser EEPROM.update pour écrire en EEPROM, ça économise cette mémoire.

Cordialement
jpbbricole

Tu ne trouves pas qu'il y a un truc bizarre ici?
Moi j'en vois trois:

  1. pour lire un bouton, on utilise digitalRead() ce qui donnerait

etatbouton = digitalRead(bouton);

  1. on fait le test sur la variable qui contient l'état du bouton
  2. dans un test d'égalité on utilise ==

if(etatbouton == LOW)

Bonsoir @viseo

Fil de discusion transféré dans la partie principale du forum francophone, emplacement indiqué dans les Bonnes Pratiques du Forum.

Page à consulter pour savoir où et comment poser les questions.

Mince désolé, je pensais avoir posté dans la section principale :confused:

Je pense avoir trouvé la solution à mon problème en utilisant l'EEPROM.

Effectivement! J'ai effectué les corrections. Merci.

Cela fonctionne parfaitement avec EEPROM.update :grinning::+1:

Voici le code

// C++ code
//

#include <EEPROM.h>

int capteur = A2;
int LED1 = 2;
int LED2 = 3;
int bouton = 5;
int etatbouton = 0;
int adresse = 5;
int ref;
int alert;

void setup()
{
  	Serial.begin (9600);
	pinMode (LED1, OUTPUT);
  	pinMode (LED2, OUTPUT);
  	pinMode (bouton, INPUT_PULLUP);    	
}
  
void loop()
{
	etatbouton = digitalRead(bouton);
  	ref = analogRead(capteur);
	alert = EEPROM.read(adresse)+50;	
 	
if (etatbouton == LOW)
{
 	EEPROM.update(adresse, ref);
  	digitalWrite (LED1, HIGH);
  	digitalWrite (LED2, LOW);
  	Serial.println (alert);
  	delay(100);
}
     	
if	(ref>alert)
{
  	digitalWrite (LED2, HIGH); 
   	digitalWrite (LED1, LOW); 
}
  
else 
{
    digitalWrite (LED2, LOW); 
   	digitalWrite (LED1, LOW); 
}
}

Vous serait-il possible de me dire si le code est correcte, je veux dire s'il est propre :confused:
Je rencontre quelques petites erreurs que je dois corriger, comme la LED rouge qui est allumé dés le début et un temps de latence entre l'appui du bouton et l’éclairage des LED.

Je ne pense pas qu'il soit nécessaire de lire à chaque itération de loop() la valeur en EEPROM. Il doit être suffisant de la lire une fois dans le setup().

Alors là pas bien.
Si tu tiens le bouton 5s tu vas demander 50 écritures en EEPROM. Heureusement avec EEPROM.update() cela ne fera pas de dégat dans l'EEPROM. Mais il faut prendre l'habitude de tester que le bouton est relâché avant de sortir du if pour éviter ce genre de problème.
Il faut aussi mettre à jour alert je suppose. Cela évitera de devoir relire inutilement l'EEPROM.
Au lieu de mettre un delay(500), il vaut mieux mettre

alert = ref; // met à jour la nouvelle valeur d'alerte
delay(50);
while(digitalRead(bouton) == LOW); // attend que le bouton soit relâché

bien sûr il faut alors modifier la variable (la tenir à jour) dans le if de détection d'appui du bouton.


  • les pins seraient mieux en const byte (et tant qu'on y est avec le mot pin pour dire ce que c'est)
const byte pinCapteur = A2;
const byte pinLED1 = 2;
const byte pinLED2 = 3;
const byte pinBouton = 5;
  • etatbouton n'as pas besoin d'être une variable globale. on peut d'ailleurs s'en passer et juste faire
  if (digitalRead(pinBouton) == LOW) {
    ...
  }
  • Pourquoi le +50 sur la référence ?

  • attention vous stockez un seul octet avec update() et vous lisez la valeur de référence avec un analogRead() qui peut monter à 1023. il vaudrait mieux utiliser put() et get().

J'ai testé et en mettant dans le IF du bouton cela fonctionne et évite d'avoir une vérification à chaque loop. C'est mieux ainsi, bien vu!

Il n'y a pas photo cela rend le code beaucoup plus propre.

Après lecture sur le site Arduino, c'est la bonne méthode pour un code correct!

Le +50 devient mon alerte à ne pas dépasser par la référence (référence est l'humidité du terreau qui va varier au cours des heures de travail).

Si je stock simplement la valeur de l'humidité du capteur je dois est être en dessous des 512 bytes.
Je pense :confused:

Voici le nouveau code avec vos remarques et suggestions

// C++ code
//

#include <EEPROM.h>

const byte pinCapteur = A0; // capteur branché sur A2
const byte pinLED1 = 2; // LED verte branchée sur D2
const byte pinLED2 = 3; // LED rouge branchée sur D3
const byte pinBouton = 5; // bouton brnaché sur D5
int etatbouton = 0; // état du bouton
int adresse = 5; // enregistrement du capteur à l'adresse 5 de l'EEPROM
byte ref = 0; // valeur du capteur
byte alert = 0; // valeur de l'alerte


void setup()
{
  	Serial.begin (9600);
	pinMode (pinLED1, OUTPUT); // LED1 sortie
  	pinMode (pinLED2, OUTPUT); // LED2 sortie
  	pinMode (pinBouton, INPUT_PULLUP); // bouton poussoir
}
  
void loop()
{
  	ref = analogRead(pinCapteur); // valeur de ref est celle du capteur	
 	
if 	(digitalRead(pinBouton) == LOW) // si le bouton est appuyé
{
 	
  	EEPROM.update(adresse, ref); // enregistre la valeur du capteur sur l'EEPROM
 	alert = EEPROM.read(adresse)+50; // bouton poussoir activé la valeur de alert est celle du capteur +50
  	digitalWrite (pinLED1, HIGH); // LED verte s'allume
  	digitalWrite (pinLED2, LOW); // LED rouge éteinte
  	Serial.println (alert);
  	
 	delay(50); // attende de 50ms
	while(digitalRead(pinBouton) == LOW); // attend que le bouton soit relâché
}
     	
if	(ref>alert) // si la valeur du capteur est plus grande que celle-ci +50
{
  	digitalWrite (pinLED2, HIGH); // LED rouge allumée
   	digitalWrite (pinLED1, LOW); // LED  verte éteinte
}
  
else 
{
    digitalWrite (pinLED2, LOW); // LED rouge éteinte
   	digitalWrite (pinLED1, LOW); // LED verte éteinte
}
}

ce que je veux dire c'est que si vous essayez de mettre 300 dans la case mémoire de l'EEPROM, ça ne va pas marcher. Un octet c'est au max 255


sinon faire

 	delay(50); // attente de 50ms
	while(digitalRead(pinBouton) == LOW); // attend que le bouton soit relâché
 	delay(50); // attente de 50ms

pour éviter les rebonds du bouton lors du relâchement


il faudrait initialiser ref dans le set up, par contre pas la peine d'aller relire l'EEPROM lors de l'appui bouton...

  	EEPROM.update(adresse, ref); // enregistre la valeur du capteur sur l'EEPROM
 	alert = ref+50; // bouton poussoir activé la valeur de alert est celle du capteur +50

mais attention si vous dépassez 255

Merci à tous!

Le projet fonctionne et le code est plus clair :wink: Je vais maintenant le monter et créer un boitier 3D.
Une fois de plus la communauté a été bienveillante et efficace.
J'indique comme résolu.

:raised_hand: :smiley: :+1:

attendez vous donc à un soucis si vous poussez un peu trop le potentiomètre qui sert de référence... à 256 vous mettez un seuil à 0 en mémoire...