Nouveau: débutant demande un peu d'aide - merci

Bonjour à tous,

Je suis modéliste naval depuis plusieurs années et j’ai comme projet de réaliser un éclairage simulant l’allumage des néons sur mon nouveau bateau.
Le matériel dont je dispose est une carte Arduino uno R3, et je compte par la suite tansférer le programme dans un microcontrôleur Attiny 85 ou 84.
J’ai commencé à réaliser un début de programme en glanant ici et là des exemples de programme.
Mais comme je vous l’ai signaler dans le titre je suis plus que novice dans la conception de programme.
Actuellement le programme développé ne permet que de réaliser une partie du déroulement de ce que je voudrais.
Le dit déroulement serait d’appuyer sur un poussoir, en le gardant maintenu de faire clignoter plusieurs foix des leds, puis de les allumer en fixe jusqu’au moment où l’on relacherait le poussoir.
Pour l’instant, j’arrive bien à faire clignoter les leds mais elles ne font que de clignoter jusqu’à ce que je relâche le bouton.

Dans la pièce jointe vous trouverez le tableau du déroulement du programme aisin que le schéma de raccordement du poussoir.
Je joins aussi le code que j’ai réalisé pour le moment.

const int L1 = 11; // broche 11 du micro-contrôleur se nomme maintenant : L1
const int L2 = 12; // broche 12 du micro-contrôleur se nomme maintenant : L2
const int L3 = 13; // broche 13 du micro-contrôleur se nomme maintenant : L3
const int BP = 2;  // broche2 du micro-contrôleur se nomme maintenant : BP

void setup() //fonction d'initialisation de la carte
{
//contenu de l'initialisation
pinMode(L1, OUTPUT); // L1 est une broche de sortie
pinMode(L2, OUTPUT); // L2 est une broche de sortie
pinMode(L3, OUTPUT); // L3 est une broche de sortie
pinMode(BP, INPUT);  // BP est une broche d'entree
}
void loop() //fonction principale, elle se répète (s’exécute) à l'infini
{
//contenu du programme
int test = digitalRead(BP); // Lecture de l'entree BP et sockage du résultats dans test

if(test==LOW) // Si test est à l'état bas
{
digitalWrite(L1, HIGH);   // Allumer L1
digitalWrite(L2, HIGH);   // Allumer L2
digitalWrite(L3, HIGH);   // Allumer L3
delay(500);              // ne fait rien pendant 1/2 seconde
digitalWrite(L1, LOW);    // éteint L1
digitalWrite(L2, LOW);    // éteint L2
digitalWrite(L3, LOW);    // éteint L3
delay(250);              // ne fait rien pendant 1/4 seconde
digitalWrite(L1, HIGH);   // Allumer L1
digitalWrite(L2, HIGH);   // Allumer L2
digitalWrite(L3, HIGH);   // Allumer L3
delay(500);              // ne fait rien pendant 1/2 seconde
digitalWrite(L1, LOW);    // éteint L1
digitalWrite(L2, LOW);    // éteint L2
digitalWrite(L3, LOW);    // éteint L3
delay(500);              // ne fait rien pendant 1/2 seconde
digitalWrite(L1, HIGH);   // Allumer L1
digitalWrite(L2, HIGH);   // Allumer L2
digitalWrite(L3, HIGH);   // Allumer L3
}
else{                     // Allumer L1,L2,L3 // Sinon
digitalWrite(L1, LOW);    // Eteindre L1
digitalWrite(L2, LOW);    // Eteindre L2
digitalWrite(L3, LOW);    // Eteindre L3
}
}

Si pouviez m’aider à finir mon projet, ça serait génial.

Schéma du programme Néons.pdf (32.9 KB)

Le problème avec votre approche c’est que vous bouclez sans fin tant que le bouton est appuyé sur la demande de faire clignoter puisque tout ce que vous testez c’est si le bouton est enfoncé ou pas.

Essayez avec cela. je n’ai pas testé mais l’idée c’est d’avoir ce que l’on appelle en programmation une machine à état: on se souvient dans quel mode on est et à chaque fois que l’on revient dans la boucle on test pour savoir si on doit changer d’état. ça permet de ne pas avoir une section critique ou le code est bloqué en attendant son exécution et si vous relâchez le bouton alors rien ne se passe tant que l’action demandée n’a pas été finie (cf votre approche, dès que vous touchez le bouton vous partez pour 3 secondes de clignotement même si vous lâchez le bouton instantanément)

ici mes 3 états sont définis par ce que font les LEDs: ETEINTES, CLIGNOTENT, FIXES et l’appui sur le bouton (et le temps d’appui) me fait passer entre les états.

j’ai aussi scindé le code en plusieurs fonctions pour assurer la lisibilité. ce n’est jamais bon de tout coller dans la boucle.

enfin notez que j’ai mis pinMode(BP, INPUT_PULLUP);. Votre arduino a une résistance intégrée que vous pouvez activer en PULLUP → comme cela vous pouvez vous passer de la résistance externe R1 que vous avez dans votre schéma du bouton poussoir. c’est câblé “conceptuellement” comme cela

const int L1 = 11; // broche 11 du micro-contrôleur se nomme maintenant : L1
const int L2 = 12; // broche 12 du micro-contrôleur se nomme maintenant : L2
const int L3 = 13; // broche 13 du micro-contrôleur se nomme maintenant : L3
const int BP = 2;  // broche2 du micro-contrôleur se nomme maintenant : BP

enum {ETEINTES, CLIGNOTENT, FIXES}; // on définit 3 mots clés qui sont l'état des LEDs
byte etatDesLEDs;
byte nbClignottement;

// --------------------------------------------
// fonction allumer(): allume toutes les LEDs
// --------------------------------------------
void allumer()
{
  digitalWrite(L1, HIGH);   // Allumer L1
  digitalWrite(L2, HIGH);   // Allumer L2
  digitalWrite(L3, HIGH);   // Allumer L3
}

// --------------------------------------------
// fonction eteindre(): éteint toutes les LEDs
// --------------------------------------------
void eteindre()
{
  digitalWrite(L1, LOW);    // éteint L1
  digitalWrite(L2, LOW);    // éteint L2
  digitalWrite(L3, LOW);    // éteint L3
}

// --------------------------------------------
// fonction faireClignotter()
//    inverese l'état des LEDs toutes les 500ms
//    à noter l'usage de variable static
//    pour mémoriser l'état entre deux appels de
//    la fonction ainsi que la gestion du temps
// --------------------------------------------
void faireClignotter()
{
  static unsigned long dernierChangement = 0;
  static boolean LEDeteintes = false;

  if (millis() - dernierChangement >= 500) {
    // on a attendu assez longtemps dans cet état, on inverse
    if (LEDeteintes) {
      allumer();
      LEDeteintes = false;
    } else {
      eteindre();
      LEDeteintes = true;
    }
    dernierChangement = millis();
    nbClignottement++; // augmente de 2 pour 1 clignottement car on compte les ON et OFF
  }
}

// --------------------------------------------
// fonction d'initialisation de la carte
// --------------------------------------------
void setup()
{
  //contenu de l'initialisation
  pinMode(L1, OUTPUT); // L1 est une broche de sortie
  pinMode(L2, OUTPUT); // L2 est une broche de sortie
  pinMode(L3, OUTPUT); // L3 est une broche de sortie

  // le bouton est connecté à une résistance, devient LOW quand appuyé
  pinMode(BP, INPUT_PULLUP);  // BP est une broche d'entree

  // on s'assure que tout est éteint
  eteindre();
  etatDesLEDs = ETEINTES;
  nbClignottement = 0;
}

// --------------------------------------------
//fonction principale, elle se répète (s'exécute) à l'infini
// --------------------------------------------
void loop()
{
  //contenu du programme
  int test = digitalRead(BP); // Lecture de l'entree BP et sockage du résultats dans test

  if (test == LOW) {
    if (etatDesLEDs == ETEINTES) {
      // premier appui sur le bouton, on passe en mode clignotage
      allumer();
      etatDesLEDs = CLIGNOTENT;
    } else if (etatDesLEDs == CLIGNOTENT) {
      if (nbClignottement < 6) { // 3 clignottements = 6 changements d'état des LEDs
        faireClignotter();
      } else {
        etatDesLEDs = FIXES;
        nbClignottement = 0; // pour la prochaine fois
        allumer();
      }
    }
  } else { // le bouton est relaché
    if ((etatDesLEDs == CLIGNOTENT) || (etatDesLEDs == FIXES)) {
      etatDesLEDs = ETEINTES;
      nbClignottement = 0; // pour la prochaine fois
      eteindre();
    }
  }
}

une façon moins propre de le faire avec votre code serait après le clignotement d’allumer les LEDs et de faire une boucle à cet endroit en attendant le relâchement du bouton… mais c’est pas super propre et si le bouton “rebondit” (quand on appuie sur un bouton pendant quelques millisecond es il oscille enter appuyé et éteint) alors ça va faire des trucs bizarres

Un grand merci pour votre réponse très rapide et très complète, J-M-L. Je viens de tester et cela fonctionne parfaitement.

Je me pose une autre question, est-il possible de gérer indépendamment chaque led, ainsi que le nombre de clignotements pour chaque led avec des temps différents ?

Merci par avance de votre aide.

Oui tout est possible. Dans ce cas il faut gérer les LEDs séparément.

  • j’ai créé un tableau avec la listes des broches des LEDs
const byte mesLEDS[NBLEDS] = {L1, L2, L3}; // tableau des LEDs, il doit y en avoir NBLEDS
  • j’ai créé un tableau avec les demi periode de clignotement
const unsigned long periodeLED[NBLEDS] = {[color=blue]500[/color], [color=blue]100[/color], [color=blue]50[/color]};  // initialiser avec les durées de clignottement voulues

ici la LED1 va changer d’état toute les 500ms, la seconde toutes les 100 et la troisième toutes les 50ms

j’ai modifié la fonction de clignotement pour qu’elle prenne en paramètre un Numéro de LED (0,1,2) à faire clignoter s’il est temps pour cette LED.

Cela change bien sûr le comportement de la variable qui compte le nombre de clignotements, certaines LEDs vont clignoter plus vite que d’autres donc vous gérez le nombre total de clignotements souhaités, ici j’ai mis 60 en tout.

if (nbClignottement < [b][color=blue]60[/color][/b]) { // Nombre total de changements d'états cumulés des LEDs

enfin au lieu d’appeler une seule fois la fonctionne faireClignotter() comme dans le code précédent, je le fais dans une boucle pour demander à chaque LED si c’est le bon moment de clignoter.

j’ai pas testé - donc je vous laisse explorer…

const byte BP = 2;  // broche2 du micro-contrôleur se nomme maintenant : BP


#define NBLEDS 3  // définir ici le nombre de LEDs

const byte L1 = 11; // broche 11 du micro-contrôleur se nomme maintenant : L1
const byte L2 = 12; // broche 12 du micro-contrôleur se nomme maintenant : L2
const byte L3 = 13; // broche 13 du micro-contrôleur se nomme maintenant : L3

const byte mesLEDS[NBLEDS] = {L1, L2, L3}; // tableau des LEDs, il doit y en avoir NBLEDS
const unsigned long periodeLED[NBLEDS] = {500, 100, 50};  // initialiser avec les durées de clignottement voulues


enum {ETEINTES, CLIGNOTENT, FIXES}; // on définit 3 mots clés qui sont l'état des LEDs
byte etatDesLEDs;
byte nbClignottement;

// --------------------------------------------
// fonction allumer(): allume toutes les LEDs
// --------------------------------------------
void allumer()
{
  for (byte i = 0; i < NBLEDS; i++) digitalWrite(mesLEDS[i], HIGH); // Allumer
}

// --------------------------------------------
// fonction eteindre(): éteint toutes les LEDs
// --------------------------------------------
void eteindre()
{
  for (byte i = 0; i < NBLEDS; i++) digitalWrite(mesLEDS[i], LOW); // Eteindre
}

// --------------------------------------------
// fonction faireClignotterLED une LED (0,1,2 pour L1, L2, L3)
// ------------------------------------------
void faireClignotterLED(byte ledNumber)
{
  static unsigned long dernierChangement[NBLEDS] = {0, 0, 0}; // autant de 0 que de LEDs
  static boolean LEDeteinte[NBLEDS] = {false, false, false}; // autant de false que de LEDs

  if (millis() - dernierChangement[ledNumber] >= periodeLED[ledNumber]) {
    // on a attendu assez longtemps dans cet état, on inverse
    if (LEDeteinte[ledNumber]) {
      digitalWrite(mesLEDS[ledNumber], HIGH);   // Allumer ledNumber
      LEDeteinte[ledNumber] = false;
    } else {
      digitalWrite(mesLEDS[ledNumber], LOW);   // Eteindre ledNumber
      LEDeteinte[ledNumber] = true;
    }
    dernierChangement[ledNumber] = millis();
    nbClignottement++; // augmente de 2 pour 1 clignottement car on compte les ON et OFF
  }
}


// --------------------------------------------
// fonction d'initialisation de la carte
// --------------------------------------------
void setup()
{
  //contenu de l'initialisation
  for (byte i = 0; i < NBLEDS; i++) pinMode(mesLEDS[i], OUTPUT); // broche de sortie

  // le bouton est connecté à une résistance, devient LOW quand appuyé
  pinMode(BP, INPUT_PULLUP);  // BP est une broche d'entree

  // on s'assure que tout est éteint
  eteindre();
  etatDesLEDs = ETEINTES;
  nbClignottement = 0;
}

// --------------------------------------------
//fonction principale, elle se répète (s'exécute) à l'infini
// --------------------------------------------
void loop()
{
  if (digitalRead(BP) == LOW) {
    if (etatDesLEDs == ETEINTES) {
      // premier appui sur le bouton, on passe en mode clignotage
      allumer();
      etatDesLEDs = CLIGNOTENT;
    } else if (etatDesLEDs == CLIGNOTENT) {
      if (nbClignottement < 60) { // Nombre total de changements d'états cumulés des LEDs
        for (byte i = 0; i < NBLEDS; i++) faireClignotterLED(i);
      } else {
        etatDesLEDs = FIXES;
        nbClignottement = 0; // pour la prochaine fois
        allumer();
      }
    }
  } else { // le bouton est relaché
    if ((etatDesLEDs == CLIGNOTENT) || (etatDesLEDs == FIXES)) {
      etatDesLEDs = ETEINTES;
      nbClignottement = 0; // pour la prochaine fois
      eteindre();
    }
  }
}

PS: on veut bien voir une photo de la maquette :)

Merci encore une fois, cela fonctionne exatement comme je le souhaitais

Les photos du bateau

super ! (bon manque la photo tu bateau :) )

Ah ? Je vais ressayer de le passer en word

non non pas en word!

utilisez http://www.hostingpics.net (c'est gratuit, sans inscription) pour charger votre photo sur internet et postez le lien ici

Donc voilà le Tom pousse ! En espérant que cette fois ça fonctionne

http://hpics.li/edfa7a8 http://hpics.li/aac43c5

Bonne soirée

Superbe! Je mets directement les photos pour que tout le monde en profite!

|333x500|500x333