stopper une fonction

bonjour,

je suis super novice et je suis même pas sur de bien formuler ma question mais je tente quand même de vous la poser .

j ai déjà réalisé un petit programme simulant un cadenas à 3 chiffres avec un affichage LCD et je dois dire que ça fonctionne très bien. Du coup , croyant savoir plein de trucs, je me suis lancé dans un projet qui me paraissait plus simple et je dois dire que je suis complètement largué.

voilà je m explique.

je cherche simplement à exécuter une action 2 fois( faire basculer un relais) d’affilé après qu un bouton poussoir soit appuyé et reste appuyé pendant un temps indéfini.
quand ce bouton poussoir change d’état donc plus appuyé, j aimerais que la carte arduino NANO redémarre et soit de nouveau en attente d une nouvelle pression sur le bouton poussoir pour que l action se fasse à nouveau etc…ainsi de suite.

voila c 'est pas grand chose à mes yeux mais je sais pas du tout comment m y prendre. donc je vous présente un truc qui marche pas comme je veux.
je fait donc appelle a vous pour éclairer ma lanterne
merci d avance…

relais.ino (657 Bytes)

Il faut faire une machine à états (cf mon petit tuto sur ce sujet éventuellement)

merci pour la réponse rapide je vais essayer de faire ça.
je vous tien au courant,je ne connaissais pas cette fonction "enum" ni même tout le reste d ailleurs

merci encore.

Bonjour,

Au lieu de mettre ton code en fichier attaché mets ton code entre balises

Dans ton code enlève le exit(0). En C c'est supposé sortir du programme et retourner au système d'exploitation, et sous le framework arduino je ne sais pas ce que ça fait

Elève aussi le cas ' if (valeur == LOW) {', je ne sais pas ce qu'est supposé faire 'return loop();' mais ça m'étonnerait que ça fasse quelque chose de bien.

Après je n'ai pas compris ce que tu veux faire

  • tu veux que le relais commute 2 fois dès que tu appuies sur le bouton ?
  • tu veux que le relais commute 2 fois si tu appuies sur le bouton un certain temps ?
  • tu veux que le relais commute 2 fois tant que le bouton est appuyé ?

bonjour, kamill

en effet je cherche à faire commuter mon relais que 2 fois après l appuie du bouton poussoir. sauf que ce bouton reste appuyé un temps indéfini.

dés que ce bouton n est plus appuyé on revient au début du cycle en attente d un nouvel appuie à durée indéfinie.

en gros pour mieux m expliquer je veux que l on pose un objet sur le bouton et qu une cloche sonne juste 2 fois sauf que cet objet peut rester posé sur ce bouton un moment dont on ne connaît pas la durée.( donc l état du bouton ne change pas et reste HIGH).

dés que l on enlève cet objet du bouton (l’état du bouton change et passe à LOW) on revient au début du programme, donc en attente d une nouvelle pose de cet objet sur ce bouton. d’où mon" if (valeur == LOW) "pour retourner au début de ma boucle ( mais ça marche pas lol).

le “exit(0)” arrête tout le programme ce qui fait que ma cloche sonne deux fois mais quand j enlève l objet il ne se passe plus rien et je suis obligé d éteindre la carte arduino pour pouvoir recommencer mon action.

j espère avoir été plus clair dans mes explications et surtout trouvé une solution, je suis entrain d étudier les machines à états mais c est pas gagné lol.

j avoue ne connaître que les fonctions “if” car j ai bien compris comment ça fonctionne c est pour ça que j en mets partout. :confused:

merci d avance

Bonjour,

Il suffit de déclencher le relais quand le bouton change d'état et qu'il est enfoncé.
Ce qui donne

const int bouton = 3;     
const int relais =  2;      

void setup() {
/* Serial.begin(9600);
 Serial.println(); */
 pinMode(relais, OUTPUT);      
 
 pinMode(bouton, INPUT);     
}

void loop(){
 static int etatBoutonPrec=LOW;
 int etatBouton = digitalRead(bouton);
 
 if (etatBouton == HIGH && etatBoutonPrec == LOW)
 {     
   digitalWrite(relais, LOW);
   delay(500);
   digitalWrite(relais, HIGH);
   delay(500);  
   digitalWrite(relais, LOW);
   delay(500);
   digitalWrite(relais, HIGH);
   delay(500); 
   digitalWrite(relais, LOW);
 }
 etatBoutonPrec=etatBouton;
 delay(10);
}

merci beaucoup du coup de main c 'est génial !!!!!!

je vais bien étudier ça pour bien le comprendre.

merci encore!
:smiley:

On peut utiliser le type byte pour mémoriser HIGH ou LOW, on gagne de la mémoire

Appeler exit(0); dans un programme fonctionne mais comme il n'y a pas d'OS où retourner en gros ça arrête tout code et votre arduino reste dans l'état où il était juste avant l'appel au niveau des valeurs de pins en OUTPUT; ensuite faut appuyer sur reset pour relancer le programme

J-M-L:
On peut utiliser le type byte pour mémoriser HIGH ou LOW, on gagne de la mémoire

Bonjour J-M-L,

Je suis d'accord avec toi, mais je suis tes principes d'orthodoxie: digitalRead() retourne un int, donc je le mémorise dans un int :).
Rien ne dit que dans une prochaine révision de l'IDE et du framework, HIGH ne va pas être égal à 3224 (bon, ça m'étonnerait un peu quand même, mais on ne sait jamais :grinning: )

Oui c'est vrai mais ils ne peuvent pas parce que la signature de digitalWrite utilise un uint8_t pour HIGH ou LOW...

--> void digitalWrite(uint8_t pin, [color=red]uint8_t[/color] val)

Je pense qu'à l'origine ils voulaient se réserver le droit de retourner -1 si l'appel à digitalRead plante (comme la méthode read des Streams) mais si vous regardez le code ils ne le font pas, ils retournent LOW en cas de mauvaise pin

int digitalRead(uint8_t pin)
{
	uint8_t timer = digitalPinToTimer(pin);
	uint8_t bit = digitalPinToBitMask(pin);
	uint8_t port = digitalPinToPort(pin);
	if (port == NOT_A_PIN) return LOW;
	// If the pin that support PWM output, we need to turn it off
	// before getting a digital reading.
	if (timer != NOT_ON_TIMER) turnOffPWM(timer);
	if (*portInputRegister(port) & bit) return HIGH;
	return LOW;
}

Pour mémoire HIGH et LOW ne sont pas définis comme des const int mais dans wiring.h comme

#define HIGH 0x1
#define LOW  0x0

Donc c'est remplacé brut dans votre code par une valeur littérale et donc le compilateur fait automatiquement une promotion vers le type de votre variable de réception (et par défaut est effectivement vu comme un int)

Contre argument implacable!
De toute façon, j'ai toujours pensé qu'ils auraient du utiliser des booléens pour ces fonctions.

Non ce n'est pas une valeur de vérité c'est un etat électrique donc HIGH ou LOW ça fait du sens

Vous pourriez écrire une fonction isPinHigh() et là Le nom indique que c'est une question donc une valeur de vérité

Oui, ça se défend, mais je crois qu'on est en train de polluer le fil

:slight_smile: oui

re,

je vous remercie de votre aide a tout les deux.

j étudie les machines à état maintenant grâce a vous J.M.L merci de ma voir mis sur cette voie et le code de kamill répond tout a fait à ma question et mon besoin, je suis juste un peu déçu de ne pas l avoir trouvé tout seul LOL.
mais comme dit dans un poste précédant je suis ultra novice et tout les autres post que vous avez ecrit j ai rien compris LOL.
merci encore je pense revenir vers vous pour d autre questions si je comprend rien. :smiley: