fbpixel
Étiquettes :
3.6
(5)

Pour ce projet, nous allons réaliser un feu tricolore et reproduire son fonctionnement. Nous allons voir étape par étape comment tester chacun des composants et comment développer le programme final.

C’est un projet simple pour bien commencer l’apprentissage de l’électronique et de la programmation avec Arduino.

Matériel

  • Ordinateur
  • Arduino UNO
  • Câble USB A mâle vers USB B mâle
  • Module feu tricolore (ou LEDs x3 + Résistances x3)
  • Bouton poussoir (ou module bouton poussoir)
  • Breadboard
  • Câbles Dupont M/F
  • Bouton poussoir x1

Objectif

Nous allons reproduire le fonctionnement d’un feu rouge. D’abord avec un mode automatique dans lequel les LEDs s’allume l’une après l’autre. Puis nous allons rajouter un bouton d’appel piéton pour forcer le passage au rouge.

Préparation et code de test de l’Arduino

Sans brancher les LEDs, nous pouvons déjà commencer à travailler sur l’algorithme de base pour tester la communication série et la programmation de l’Arduino. Vous pouvez suivre ce tutoriel pour configurer et programmer la carte Arduino.

int verte = 0;
int orange = 1;
int rouge = 2;


void setup() {
  Serial.begin(9600);
  Serial.println("Feux rouge initialisé");
}

void loop() {
  Serial.println("loop running");
  delay(500);
  allumer(verte);
  delay(1000);
  eteindre(verte);
  allumer(orange);
  delay(1000);
  eteindre(orange);
  allumer(rouge);
  delay(1000);
}


void allumer(int color) {
  Serial.print("allumer led ");
  switch (color) {
    case 0:
      Serial.println("verte");
      break;
    case 1:
      Serial.println("orange");
      break;
    case 2:
      Serial.println("rouge");
      break;
  }
}

void eteindre(int color) {
  Serial.print("eteindre led :");
  switch (color) {
    case 0:
      Serial.println("verte");
      break;
    case 1:
      Serial.println("orange");
      break;
    case 2:
      Serial.println("rouge");
      break;
  }
}

Schéma de câblage

Le bouton est branché sur la pin 2, la LED1 sur la pin 9, lED2 sur la pin 10 et LED3 sur la pin 11. Notez bien la présence des résistances pour éviter d’endommager les composants. Avec le module feu tricolore, ces résistances ne sont pas nécessaires.

Code de gestion des LEDs

Une fois les LEDs branchées à l’Arduino, nous pouvons essayer de les allumer. La fonction utilisée pour contrôler une diode est digitalWrite() avec comme paramètre HIGH pour l’allumer, LOW pour l’éteindre. Il suffit de rajouter la fonction digitalWrite() à l’endroit désiré dans les fonctions allumer et éteindre.

L’objectif est de faire s’allumer la LED verte puis la orange puis la rouge après des intervalles de temps donnés.

Pour plus de lisibilité, nous plaçons les variables verte, orange, rouge dans un enum.

const int pinVerte = 9;
const int pinOrange = 10;
const int pinRouge = 11;

enum couleur {
  VERTE,
  ORANGE,
  ROUGE
};
int etatFeu = VERTE;

void setup() {
  Serial.begin(9600);
  pinMode(pinVerte, OUTPUT);
  pinMode(pinRouge, OUTPUT);
  pinMode(pinOrange, OUTPUT);

  Serial.println("Feu tricolore initialisé");
}

void loop() {
  Serial.println(F("Mode auto running"));
  eteindre (ROUGE);
  allumer (VERTE);
  delay (5000);
  eteindre (VERTE);
  allumer (ORANGE);
  delay (1000);
  eteindre (ORANGE);
  allumer (ROUGE);
  delay (3000);
}


void allumer(int color) {
  Serial.print("allumer led ");
  switch (color) {
    case VERTE:
      Serial.println("verte");
      digitalWrite(pinVerte, HIGH); //analogWrite(pinVerte, 250);
      break;
    case ORANGE:
      Serial.println("orange");
      digitalWrite(pinOrange, HIGH); //analogWrite(pinOrange, 250);
      break;
    case ROUGE:
      Serial.println("rouge");
      digitalWrite(pinRouge, HIGH); //analogWrite(pinRouge, 250);
      break;
    default:
      digitalWrite(pinOrange, HIGH); //analogWrite(pinOrange, 250);
      break;
  }
  etatFeu = color;
}

void eteindre(int color) {
  Serial.print("eteindre led :");
  switch (color) {
    case VERTE:
      Serial.println("verte");
      digitalWrite(pinVerte, LOW); //analogWrite(pinVerte, 0);
      break;
    case ORANGE:
      Serial.println("orange");
      digitalWrite(pinOrange, LOW); //analogWrite(pinOrange, 0);
      break;
    case ROUGE:
      Serial.println("rouge");
      digitalWrite(pinRouge, LOW); //analogWrite(pinRouge, 0);
      break;
    default:
      digitalWrite(pinVerte, LOW); //analogWrite(pinVerte, 0);
      digitalWrite(pinOrange, LOW); //analogWrite(pinOrange, 0); //
      digitalWrite(pinRouge, LOW); //analogWrite(pinRouge, 0); //
      break;
  }
}

Il est possible de moduler la luminosité de la LED en utilisant la fonction analogWrite() et une sortie PWM du microcontrôleur.

Code de gestion du bouton

Nous allons à présent tester le fonctionnement du bouton poussoir. L’objectif est que le feu tricolore change de couleur lorsqu’on appuie sur le bouton. Pour cela, il nous faut “écouter” l’état du bouton constamment. Une technique intéressante pour surveiller l’état d’un capteur est d’utiliser une interruption. Nous reprenons donc le code de ce tutoriel complet sur la gestion d’un bouton avec interruption.

const byte ledPin = 10;
const byte interruptPin = 2;
volatile byte state = LOW;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), onEvent, FALLING);
  Serial.println(F("Système intialisé"));
}

void loop() {
  digitalWrite(ledPin, state);
}

void onEvent() {
  state = !state;
  Serial.print(F("Switch LED : "));
  if (state) {
    Serial.println(F("ON"));
  } else {
    Serial.println(F("OFF"));
  }
}

Pour d’autres façons de gérer le bouton poussoir, vous pouvez lire ce tutoriel.

Changement de la couleur du feu à l’aide du bouton

Nous allons combiner les deux codes précédents afin de modifier la couleur du feu tricolore lorsqu’on appuie sur le bouton.

const int pinVerte = 9;
const int pinOrange = 10;
const int pinRouge = 11;

enum couleur {
  VERTE,
  ORANGE,
  ROUGE
};
int etatFeu = VERTE;

const byte btnPin = 2;
int state = 0;

void setup() {
  Serial.begin(9600);
  pinMode(pinVerte, OUTPUT);
  pinMode(pinRouge, OUTPUT);
  pinMode(pinOrange, OUTPUT);
  
  pinMode(btnPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(btnPin), onEvent, FALLING);
  Serial.println("Feu tricolore initialisé");
}

void loop() {
  switch (state) {
    case 0://mode automatique
      Serial.println(F("Mode auto"));
      eteindre (ROUGE);
      allumer (VERTE);
      delay (5000);
      eteindre (VERTE);
      allumer (ORANGE);
      delay (1000);
      eteindre (ORANGE);
      allumer (ROUGE);
      delay (3000);
      break;
      
    case 1:// mode manuel
      Serial.println(("Mode manuel"));
      delay (5000);
      eteindre (ROUGE);
      
      state = 0;
      break;
  }
}

void onEvent() {
  Serial.println("---> Bouton pressé");
  eteindre(3);//eteindre tout
  allumer (ROUGE);
  state=1;
}


void allumer(int color) {
  Serial.print("allumer led ");
  switch (color) {
    case VERTE:
      Serial.println("verte");
      digitalWrite(pinVerte, HIGH); //analogWrite(pinVerte, 250);
      break;
    case ORANGE:
      Serial.println("orange");
      digitalWrite(pinOrange, HIGH); //analogWrite(pinOrange, 250);
      break;
    case ROUGE:
      Serial.println("rouge");
      digitalWrite(pinRouge, HIGH); //analogWrite(pinRouge, 250);
      break;
    default:
      digitalWrite(pinOrange, HIGH); //analogWrite(pinOrange, 250);
      break;
  }
}

void eteindre(int color) {
  Serial.print("eteindre led : ");
  switch (color) {
    case VERTE:
      Serial.println("verte");
      digitalWrite(pinVerte, LOW); //analogWrite(pinVerte, 0);
      break;
    case ORANGE:
      Serial.println("orange");
      digitalWrite(pinOrange, LOW); //analogWrite(pinOrange, 0);
      break;
    case ROUGE:
      Serial.println("rouge");
      digitalWrite(pinRouge, LOW); //analogWrite(pinRouge, 0);
      break;
    default:
      Serial.println(" tout");
      digitalWrite(pinVerte, LOW); //analogWrite(pinVerte, 0);
      digitalWrite(pinOrange, LOW); //analogWrite(pinOrange, 0); //
      digitalWrite(pinRouge, LOW); //analogWrite(pinRouge, 0); //
      break;
  }
}

Si vous testez ce code, vous allez vous rendre compte que le feu ne se comporte pas tout à fait comme prévu. Nous arrivons à forcer la couleur au rouge mais le fonctionnement automatique ne reprend pas son cours correctement. Cela est dû à la fonction delay() qui bloque le code. Pour pouvoir prendre en compte le bouton au moment où on appuie dessus, il va falloir modifier le code afin de se débarrasser de la fonction delay().

Modification du code

Pour supprimer la fonction delay(), nous pouvons utiliser un algorithme à l’aide de la fonction millis(). Nous allons reproduire la fonction delay à l’aide de la fonction millis sans bloquer le déroulement du code.

  if((millis()-previousTime)>200){
    previousTime=currentTime;
    Serial.println(F("action"));
  }

Pour cela, il faut aussi décomposer le fonctionnement du feu rouge en différents états et les intégrés dans les cas du switch. Un état pour le changement de couleur et un état pour le délai.

  switch (state) {
    case 0:
      eteindre (ROUGE);
      allumer (VERTE);
      state++;
      previousMillis = millis();
      break;
    case 1:
      if (millis() - previousMillis > 5000) { //delay (5000);
        state++;
      }
      break;
    case 2:
      eteindre (VERTE);
      allumer (ORANGE);
      state++;
      previousMillis = millis();
      break;
    case 3:
      if (millis() - previousMillis > 1000) { //delay (1000);
        state++;
      }
      break;
    case 4:
      eteindre (ORANGE);
      allumer (ROUGE);
      state++;
      previousMillis = millis();
      break;
    case 5:
      if (millis() - previousMillis > 3000) { //delay (3000);
        state = 0;
      }
      break;
  }

Code final complet

Une fois ces modifications faites, l’appui du bouton est pris en compte directement et le feu rouge peut reprendre son cours correctement.

const int pinVerte = 9;
const int pinOrange = 10;
const int pinRouge = 11;

enum couleur {
  VERTE,
  ORANGE,
  ROUGE
};
int etatFeu = VERTE;
int state = 0;

const byte btnPin = 2;
int mode = 0;

unsigned long previousMillis = 0;

void setup() {
  Serial.begin(9600);
  pinMode(pinVerte, OUTPUT);
  pinMode(pinRouge, OUTPUT);
  pinMode(pinOrange, OUTPUT);

  pinMode(btnPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(btnPin), onEvent, RISING);
  Serial.println("Feu tricolore initialisé");
}

void loop() {
  switch (state) {
    case 0:
      eteindre (ROUGE);
      allumer (VERTE);
      state++;
      previousMillis = millis();
      break;
    case 1:
      if (millis() - previousMillis > 5000) { //delay (5000);
        state++;
      }
      break;
    case 2:
      eteindre (VERTE);
      allumer (ORANGE);
      state++;
      previousMillis = millis();
      break;
    case 3:
      if (millis() - previousMillis > 1000) { //delay (1000);
        state++;
      }
      break;
    case 4:
      eteindre (ORANGE);
      allumer (ROUGE);
      state++;
      previousMillis = millis();
      break;
    case 5:
      if (millis() - previousMillis > 3000) { //delay (3000);
        state = 0;
      }
      break;
  }
}

void onEvent() {
  Serial.println("---> Bouton pressé");
  if (etatFeu == VERTE) {
    Serial.println("Changement d'etat");
    state = 2;
  }
}


void allumer(int color) {
  Serial.print("allumer led ");
  switch (color) {
    case VERTE:
      Serial.println("verte");
      digitalWrite(pinVerte, HIGH); //analogWrite(pinVerte, 250);
      break;
    case ORANGE:
      Serial.println("orange");
      digitalWrite(pinOrange, HIGH); //analogWrite(pinOrange, 250);
      break;
    case ROUGE:
      Serial.println("rouge");
      digitalWrite(pinRouge, HIGH); //analogWrite(pinRouge, 250);
      break;
    default:
      digitalWrite(pinOrange, HIGH); //analogWrite(pinOrange, 250);
      break;
  }
  etatFeu = color;
}

void eteindre(int color) {
  Serial.print("eteindre led :");
  switch (color) {
    case VERTE:
      Serial.println("verte");
      digitalWrite(pinVerte, LOW); //analogWrite(pinVerte, 0);
      break;
    case ORANGE:
      Serial.println("orange");
      digitalWrite(pinOrange, LOW); //analogWrite(pinOrange, 0);
      break;
    case ROUGE:
      Serial.println("rouge");
      digitalWrite(pinRouge, LOW); //analogWrite(pinRouge, 0);
      break;
    default:
      digitalWrite(pinVerte, LOW); //analogWrite(pinVerte, 0);
      digitalWrite(pinOrange, LOW); //analogWrite(pinOrange, 0); //
      digitalWrite(pinRouge, LOW); //analogWrite(pinRouge, 0); //
      break;
  }
}

N’hésitez pas à laisser un commentaire pour partager vos réalisations ou nous faire part de vos remarques. Vous pouvez aussi nous contacter pour toutes questions.

Application

  • Reproduire un croisement de route avec 4 feux tricolores synchronisés

Source

Retrouvez nos tutoriels et d’autres exemples dans notre générateur automatique de code
La Programmerie

How useful was this post?

Click on a star to rate it!

Average rating 3.6 / 5. Vote count: 5

No votes so far! Be the first to rate this post.

As you found this post useful...

Follow us on social media!

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?