Utiliser un bouton pour appeler une fonction ?

Bonjour à tous.

Je fais encore appel à votre savoir pour que vous veniez à mon aide.

J'ai écrit un code qui si il fonctionnait devrait allumer allumer mes leds et ensuite les remettre dans leur état initial via une fonction. Voici le code :

const int LEDFONCTION = 2;
const int LEDCHAUFFAGEON = 3;
const int LEDVENTILATIONON = 4;

const int BOUTONTEST = 53;

int ETATLEDCHAUFFAGEON;
int ETATLEDVENTILATIONON;
int ETATBOUTONTEST;

void setup() {
pinMode(LEDFONCTION, OUTPUT);
pinMode(LEDCHAUFFAGEON, OUTPUT);
pinMode(LEDVENTILATIONON, OUTPUT);
pinMode(BOUTONTEST, INPUT);

digitalWrite(LEDFONCTION, HIGH);
digitalWrite(LEDCHAUFFAGEON, LOW);
digitalWrite(LEDVENTILATIONON, LOW);
digitalWrite(BOUTONTEST, HIGH);
}

void loop() {
    if(BOUTONTEST == LOW){ // Si le bouton TEST est pressé
        test_led(); // On exécute la fonction test_led.
    }

}

void test_led() {
  ETATLEDCHAUFFAGEON = digitalRead(LEDCHAUFFAGEON); // Récupération de l'Etat de la LED CHAUFFAGE (HIGH ou LOW)
  ETATLEDVENTILATIONON = digitalRead(LEDVENTILATIONON); // Récupération de l'Etat de la LED VENTILATION
  while(BOUTONTEST == LOW){ // Tant que le Bouton test est appuyé, on boucle
  digitalWrite(LEDCHAUFFAGEON, HIGH); // Allumer LED CHAUFFAGE
  digitalWrite(LEDVENTILATIONON, HIGH); // Allumer LED VENTILATION
  }
  digitalWrite(LEDCHAUFFAGEON, ETATLEDCHAUFFAGEON); // Remise au dernier état de la LED CHAUFFAGE d'après la variable
  digitalWrite(LEDVENTILATIONON, ETATLEDVENTILATIONON); // Remise au dernier état de la LED VENTILATION d'après la variable
}

Mon problème est que ce code, qui me paraît pourtant simple par rapport à ce que j'ai pu voir, ne fonctionne pas et je ne comprends pas pourquoi.

Pourriez-vous me dire ce que je ne fais pas correctement pour me permettre d'évoluer ?

Merci d'avance.

Explication sur la fonction :

On récupère l'état initial des leds dans des variables.

On allume les leds tant que le bouton est appuyé.

Une fois que le bouton est relâché, on remet les leds à leur état initial.

On allume les leds tant que le bouton est appuyé.

Une fois que le bouton est relâché, on remet les leds à leur état initial.

bonjour,
boucle while
pas besoin de récupérer l'état de quoi que ce soit

while( bouton==HIGH){
digitalWrite(led, HIGH);
}
digitalWrite(led, LOW);

Il ne se passe rien est c'est normal.

    if(BOUTONTEST == LOW){ // Si le bouton TEST est pressé
.....
while(BOUTONTEST == LOW)

BOUTONTEST ne change jamais de valeur donc tu restes en permanence dans loop

Peut-être qu'avec un digitalRead() cela fonctionnerait mieux.

attention
on n'allume pas une led avec un HIGHT mais avec un LOW
on branche l'anode au +Volts via une résistance de limitation et la cathode à la sortie du micro.

Si j'ai bien compris, l'idée est de lire l'état de la led et de la stocker dans une variable, sans pour autant connaitre initialement son état.

Puis l'allumer pour le test et ensuite la remettre dans son état initial.

ETATLEDCHAUFFAGEON = digitalRead(LEDCHAUFFAGEON); ça fonctionne

exemple que j'ai fait :

bitstate=digitalRead(ledPin);
Serial.print(bitstate); sur le moniteur ça me met bien 0 ou 1 en fonction de l'état de la led.

Petite correction à apporter aussi c'est : pinMode(BOUTONTEST, INPUT_PULLUP); pour utiliser la resistance Pullup interne si ton bouton est connecté entre pin 53 et la masse.

ça compile bien pour moi.
A+

Yan_duino

dfgh:
attention
on n'allume pas une led avec un HIGHT mais avec un LOW
on branche l'anode au +Volts via une résistance de limitation et la cathode à la sortie du micro.

On ne peut rien affirmer sans savoir comment il a le câblé la LED.

Bonjour,
une question : peut-on vraiment utiliser digitalRead() sur une pin définie en OUTPUT ?
dans le "reste" de votre code, l'état des led est forcément déjà connus !?

Bonjour,

fablath:
une question : peut-on vraiment utiliser digitalRead() sur une pin définie en OUTPUT ?

Oui

Voici mon schema de montage. J'ai modifié mon code au niveau des PINS de la carte mais le principe est toujours le même.

Yan_duino:
Si j'ai bien compris, l'idée est de lire l'état de la led et de la stocker dans une variable, sans pour autant connaitre initialement son état.

Puis l'allumer pour le test et ensuite la remettre dans son état initial.

Oui, c'est tout à fait ça.

Mon projet est en fait un contrôleur de couveuse. J'ai simplifié le code pour la lecture et n'en suit qu'à mes débuts.

Du coup, les leds peuvent être allumés ou éteintes en fonction de la température, de l'hygrométrie...

J'ai réécris mon code ainsi avec un test au démarrage.

const int LEDFONCTION = 21;
const int LEDCHAUFFAGEON = 22;
const int LEDVENTILATIONON = 23;
const int BUZZER = 3;

const int BOUTONTEST = 53;

int ETATLEDCHAUFFAGEON;
int ETATLEDVENTILATIONON;
int ETATBOUTONTEST;

void setup() {
pinMode(LEDFONCTION, OUTPUT);
pinMode(LEDCHAUFFAGEON, OUTPUT);
pinMode(LEDVENTILATIONON, OUTPUT);
pinMode(BOUTONTEST, INPUT);
pinMode(BUZZER, OUTPUT);

// DEBUT TEST DE DEMARRAGE
  digitalWrite(LEDFONCTION, HIGH);
  digitalWrite(LEDCHAUFFAGEON, HIGH);
  digitalWrite(LEDVENTILATIONON, HIGH);
  delay(5000);
  // FIN DU TEST DES LEDS REMISE AU NIVEAU D'ORIGINE
  digitalWrite(LEDFONCTION, HIGH);
  digitalWrite(LEDCHAUFFAGEON, LOW);
  digitalWrite(LEDVENTILATIONON, LOW);
// FIN TEST DE DEMARRAGE

  digitalWrite(BOUTONTEST, HIGH);
}

void loop() 
  {
    while(BOUTONTEST == LOW) // Si on appuie sur BOUTON TEST
      {
        test_led(); // Exécution de la fonction TEST_LED.
      }
  }

void test_led()
  {
  ETATLEDCHAUFFAGEON = digitalRead(LEDCHAUFFAGEON); // Récupération de l'Etat de la LED CHAUFFAGE (HIGH ou LOW)
  ETATLEDVENTILATIONON = digitalRead(LEDVENTILATIONON); // Récupération de l'Etat de la LED VENTILATION
  while(BOUTONTEST == LOW)
    { // Tant que le Bouton test est appuyé, on boucle
      digitalWrite(LEDCHAUFFAGEON, HIGH); // Allumer LED CHAUFFAGE
      digitalWrite(LEDVENTILATIONON, HIGH); // Allumer LED VENTILATION
    }
  digitalWrite(LEDCHAUFFAGEON, ETATLEDCHAUFFAGEON); // Remise au dernier état de la LED CHAUFFAGE d'après la variable
  digitalWrite(LEDVENTILATIONON, ETATLEDVENTILATIONON); // Remise au dernier état de la LED VENTILATION d'après la variable
}

Résultat :

La fonction TEST marche.

Ensuite, l'appuie sur le bouton n'allume pas les 2 leds.

Je suis en train de prendre en compte au fur et à mesure les autres posts.

J'ai réussi !!! Merci pour votre aide.

Je n'avais pas intégré la nécessité d'utiliser "digitalRead" pour lire l'état du bouton. Je débute et il y a quelques subtilités qui m'échappe encore (comme la résistance pull_up... Je n'ai pas tout compris mais ça fonctionne...)

Pour ceux que ça pourrait aider voici le code fonctionnant :

const int LEDFONCTION = 21;
const int LEDCHAUFFAGEON = 22;
const int LEDVENTILATIONON = 23;
const int BUZZER = 3;

const int BOUTONTEST = 30;

int ETATLEDCHAUFFAGEON;
int ETATLEDVENTILATIONON;
int ETATBOUTONTEST;

void setup() {
pinMode(LEDFONCTION, OUTPUT);
pinMode(LEDCHAUFFAGEON, OUTPUT);
pinMode(LEDVENTILATIONON, OUTPUT);
pinMode(BOUTONTEST, INPUT_PULLUP);
pinMode(BUZZER, OUTPUT);

// DEBUT TEST DE DEMARRAGE
  digitalWrite(LEDFONCTION, HIGH);
  digitalWrite(LEDCHAUFFAGEON, HIGH);
  digitalWrite(LEDVENTILATIONON, HIGH);
  delay(5000);
  // FIN DU TEST DES LEDS REMISE AU NIVEAU D'ORIGINE
  digitalWrite(LEDFONCTION, HIGH);
  digitalWrite(LEDCHAUFFAGEON, LOW);
  digitalWrite(LEDVENTILATIONON, LOW);
// FIN TEST DE DEMARRAGE

  digitalWrite(BOUTONTEST, HIGH);
}

void loop() 
  {
    while(digitalRead(BOUTONTEST) == LOW) // Si on appuie sur BOUTON TEST
      {
        test_led(); // Exécution de la fonction TEST_LED.
      }
  }

void test_led()
  {
  ETATLEDCHAUFFAGEON = digitalRead(LEDCHAUFFAGEON); // Récupération de l'Etat de la LED CHAUFFAGE (HIGH ou LOW)
  ETATLEDVENTILATIONON = digitalRead(LEDVENTILATIONON); // Récupération de l'Etat de la LED VENTILATION
  while(digitalRead(BOUTONTEST) == LOW)
    { // Tant que le Bouton test est appuyé, on boucle
      digitalWrite(LEDCHAUFFAGEON, HIGH); // Allumer LED CHAUFFAGE
      digitalWrite(LEDVENTILATIONON, HIGH); // Allumer LED VENTILATION
    }
  digitalWrite(LEDCHAUFFAGEON, ETATLEDCHAUFFAGEON); // Remise au dernier état de la LED CHAUFFAGE d'après la variable
  digitalWrite(LEDVENTILATIONON, ETATLEDVENTILATIONON); // Remise au dernier état de la LED VENTILATION d'après la variable
}

Edit : Je me posais la question sur la commande "while". Cette boucle ne va t'elle pas bloquer le reste de l'exécution de mon programme ?

Je vais ajouter la lecture régulière de la température et de l'hygrométrie du coup, si je reste appuyé 20 minutes sur le bouton, le reste du code va t'il s'exécuter (lecture température, hygro, mise en route du chauffage, retournement...)

fdufnews:
On ne peut rien affirmer sans savoir comment il a le câblé la LED.

je ne demandais pas comment il a cablé ses LEDs. je lui disais comment il faut les cabler pour ménager le micro.

mais je ne veux pas polémiquer.

dfgh:
je ne demandais pas comment il a cablé ses LEDs. je lui disais comment il faut les cabler pour ménager le micro.

mais je ne veux pas polémiquer.

Ça m'intéresse !!! J'ai mal câblé mes leds ? Le schéma ci-dessus correspond à mon câblage. J'ai fait ce qu'on trouve sur les différents tutos. Si je peux économiser mon micro, ça m'intéresse.

Je ne suis pas la pour polémiquer mais pour apprendre et faire les choses correctement si possible :wink:

un microcontrôleur n'est pas défini pour être une source de courant.
un microcontrôleur préfère "recevoir" du courant plutôt que d'en donner

En fait pour les avr c'est plutôt l'inverse.
Ils acceptent plus volontier de fournir du courant ("source") --> 150 mA par PORT
que d'en recevoir ("sink") --> 100 mA par PORT.

cf page 314 de la datasheet ATMEGA 328p édition 10_2014

J'ai modifié mon schema, c'est correct ?

he non désolé . toutes mes excuses.
voir la réponse de 68tjs ci dessus
il a raison
voici la doc en question
3. Although each I/O port can source more than the test conditions (20mA at VCC = 5V, 10mA at VCC = 3V) under steady state conditions (non-transient), the
following must be observed:
ATmega48A/PA/88A/PA/168A/PA/328/P:
1] The sum of all IOH, for ports C0 - C5, D0- D4, ADC7, RESET should not exceed 150mA.
2] The sum of all IOH, for ports B0 - B5, D5 - D7, ADC6, XTAL1, XTAL2 should not exceed 150mA.
If IIOH exceeds the test condition, VOH may exceed the related specification. Pins are not guaranteed to source current greater than the listed test condition.
4. Although each I/O port can sink more than the test conditions (20mA at VCC = 5V, 10mA at VCC = 3V) under steady state conditions (non-transient), the
following must be observed:
ATmega48A/PA/88A/PA/168A/PA/328/P:
1] The sum of all IOL, for ports C0 - C5, ADC7, ADC6 should not exceed 100mA.
2] The sum of all IOL, for ports B0 - B5, D5 - D7, XTAL1, XTAL2 should not exceed 100mA.
3] The sum of all IOL, for ports D0 - D4, RESET should not exceed 100mA.
If IOL exceeds the test condition, VOL may exceed the related specification. Pins are not guaranteed to sink current greater than the listed test conditio

Ce n'est pas un schéma électrique!
C'est un dessin de câblage, c'est totalement différent.

Pour te répondre il faudrait reconstituer le schéma électrique à partir du dessin de câblage et je n'ai pas envie de le faire.

Regarde dans Fritzing il y a une possibilité de créer un schéma électrique à partir du dessin de câblage.

Note importante : sans valeur pour les résistances et références exactes des composants on ne peut rien dire.

C'était surtout pour le principe.

A l'origine, j'ai branché mes cathodes sur le pin GND de l'arduino et les anodes sur les pins correspondants.

Suite à la remarque de dfgh, j'ai alimenté les anodes en 5V en plaçant une resistance de 220 Ohms. Puis j'ai relié les cathodes sur les pins correspondant.

Quel est le bon branchement ? Anode sur les pins ou Cathode sur les pins ?

Merci pour votre aide.