Mes bricolages électroniques

Mes bricolages électroniques

Feu tricolore évolué

Ahhhh! Mon deuxième programme avec Arduino (le premier était de faire clignoter une led)!

Gerer deux feux tricolores (d'un carrefour donc) pour la version de base. Après je l'ai fait évoluer en y intégrant un mode orange clignotant (en mettant la pin 8 à la masse). Puis en gérant les entrées/sorties en mode analogique, dont lire un potentiomètre, interpréter la valeur et l'envoyer en sortie en PWM, et ce pour chaque couleur. Et encore après, en y intégrant un mode Série. L' Arduino envoi des messages à l'ordination via le biais de la connection USB en mode Série (message d'accueil, panne feu, durée panne, fin de panne).

L' Arduino est également capable de recevoir des messages série, par exemple XON (mode normal), XOFF (mode orange cligno).

 Pour activer les messages série, la pin 2 doit être mise à GND.

 

Vous trouvez le code complet ci-dessous.

 

 

Vidéo:

 

Code source:

 

//Gestion d'un feu tricolore avec modification de la luminosité de chaque couleur,
//et envoi de données par le port série (message d'accueil, panne feu, durée panne, fin de panne).
//Par activer le mode serie, la pin digitale 2 doit être à LOW donc à la GND. Un RESET est requis
//pour prendre les nouveaux paramètres en compte.
//Developpé en natif sur Arduino Duemilanove et compatible Uno R3.
//Fait par Landrain Arnaud le 08/07/2013.
//Version 2.20 Dernière modification le 11/07/13.
//Remarque: -Potentiomètre général non géré.
//          -Commande pouvant être envoyée vers l'Arduino depuis le PC: XON (normal) ou XOFF (panne).
//             Configurer l'envoi sur "Retour chariot" (Carriage Return).

//Définition I/O
const byte ledr1 = 3;
const byte ledj1 = 5;
const byte ledv1 = 6;
const byte ledr2 = 9;
const byte ledj2 = 10;
const byte ledv2 = 11;
const byte led13 = 13;
const byte bouton = 8;
const byte btn_serie = 2;    //si à LOW, msg séries actif
const int potarg = A0;
const int potarr = A1;
const int potarj = A2;
const int potarv = A3;
byte etatbouton;
unsigned long temps;              //variable qui stocke la mesure du temps
int tempr = 20;        //Temps du rouge *100
int tempj = 12;        //Temps du jaune (sauf panne) *100
int tempv = 35;        //Temps du vert *100
int cligno = 10;        //Temps du cligno *100
boolean panne = LOW;      //Si feu en panne = HIGH
boolean panneserie = LOW;  //panne activée par le port serie
int dureepanne = 0;       //Durée de la panne (en sec)
int val_potarg;    //potar général
int val_potarr;    //potar rouge
int val_potarj;    //potar jaune
int val_potarv;    //potar vert
boolean serie;        //variable de stockage si serie = on ==>LOW
int i;
//Variable pour traitement reception série;
char SerialInByte;      //stocke valeur du port serie (RX)
String cmd = String("");
String machaine;      //on stocke le découpage


void setup() {      // put your setup code here, to run once:
  pinMode(ledr1, OUTPUT);
  pinMode(ledj1, OUTPUT);
  pinMode(ledv1, OUTPUT);
  pinMode(ledr2, OUTPUT);
  pinMode(ledj2, OUTPUT);
  pinMode(ledv2, OUTPUT);
  pinMode(led13, OUTPUT);
  pinMode(bouton, INPUT);
  pinMode(btn_serie, INPUT);
  pinMode(potarg, INPUT);
  pinMode(potarr, INPUT);
  pinMode(potarj, INPUT);
  pinMode(potarv, INPUT);
 
  digitalWrite(bouton, HIGH);            //Pull-up activée
  digitalWrite(btn_serie, HIGH);            //Pull-up activée

  lirean();        //On lit les entrées car on a besoin de l'état de la PIN 2
 
 if(serie == LOW){
  Serial.begin(9600);                    //Activation du port serie
  Serial.println("== Feux Tricolores avec communication serie et gestion PWM by Nono ==");
  Serial.println("V2.20");
  Serial.println(" ");                  //Message d'accueil
  Serial.print("Rouge: ");      
  Serial.print(tempr);                  //On affiche les tempos enregistrées par couleurs
  Serial.print(" Orange: ");
  Serial.print(tempj);
  Serial.print(" Vert: ");
  Serial.print(tempv);
  Serial.println(" (/10 = secondes)");
  Serial.println(" ");
 }
 
 analogWrite(ledr2, 255);              //On allume les deux leds rouges à fond
 analogWrite(ledr1, 255);
 digitalWrite(13, LOW);                //on éteint led13 (requis pour Uno R3)

}


void loop()  {// put your main code here, to run repeatedly:
//Rouge 2  
    for(i=0; i<tempr; i++)   
    {
      lirean();
      jaunecli();
      analogWrite(ledr1, val_potarr);
      analogWrite(ledr2, val_potarr);      
      analogWrite(ledj1, 0);
      analogWrite(ledj2, 0);
      analogWrite(ledv1, 0);
      analogWrite(ledv2, 0);      
      delay(100);
    }
//Vert 1   
    for(i=0; i<tempv; i++)   
    {
      lirean();
      jaunecli();
      analogWrite(ledr1, 0);
      analogWrite(ledr2, val_potarr);      
      analogWrite(ledj1, 0);
      analogWrite(ledj2, 0);
      analogWrite(ledv1, val_potarv);
      analogWrite(ledv2, 0);      
      delay(100);
    }    
//Jaune 1   
    for(i=0; i<tempj; i++)   
    {
      lirean();
      jaunecli();
      analogWrite(ledr1, 0);
      analogWrite(ledr2, val_potarr);      
      analogWrite(ledj1, val_potarj);
      analogWrite(ledj2, 0);
      analogWrite(ledv1, 0);
      analogWrite(ledv2, 0);      
      delay(100);
    }  
//Rouge 1   
    for(i=0; i<tempr; i++)   
    {
      lirean();
      jaunecli();
      analogWrite(ledr1, val_potarr);
      analogWrite(ledr2, val_potarr);      
      analogWrite(ledj1, 0);
      analogWrite(ledj2, 0);
      analogWrite(ledv1, 0);
      analogWrite(ledv2, 0);      
      delay(100);
    }
//Vert 2   
    for(i=0; i<tempv; i++)   
    {
      lirean();
      jaunecli();
      analogWrite(ledr1, val_potarr);
      analogWrite(ledr2, 0);      
      analogWrite(ledj1, 0);
      analogWrite(ledj2, 0);
      analogWrite(ledv1, 0);
      analogWrite(ledv2, val_potarv);      
      delay(100);
    }  
//Jaune 2   
    for(i=0; i<tempj; i++)   
    {
      lirean();
      jaunecli();
      analogWrite(ledr1, val_potarr);
      analogWrite(ledr2, 0);      
      analogWrite(ledj1, 0);
      analogWrite(ledj2, val_potarj);
      analogWrite(ledv1, 0);
      analogWrite(ledv2, 0);      
      delay(100);
    }
}

//================== SOUS-ROUTINE =============================
void lirean()        //Lecture des entrées AN1-2-3, convertion 10 vers 8 bits
                     //   et lecture des entrées digitales
{
      val_potarr = analogRead(potarr);
      val_potarr = val_potarr / 4;      //on divise la valeur du potar par 4 (entrées AN=10240 valeurs)
      if(val_potarr < 5)                //et sorties PWM = 255 valeurs max
      {val_potarr = 5;}
      val_potarj = analogRead(potarj);
      val_potarj = val_potarj / 4;
      if(val_potarj < 10)              //on bloque chaque led à un minimum même si le potar est à Zero
      {val_potarj = 10;}    
      val_potarv = analogRead(potarv);
      val_potarv = val_potarv / 4;
      if(val_potarv < 10)
      {val_potarv = 10;}
      etatbouton = digitalRead(bouton);    //on lit bouton panne
      serie = digitalRead(btn_serie);      //on lit mode serie off/on
      if(serie == LOW){
      lireserie();                         //on teste le port serie
      }
 }  


void jaunecli()        //Mode orange clignotant
{
  while(etatbouton == LOW || panneserie == HIGH )
  {
    if(panne == LOW)        //Envoie msg si permière boucle
    {  
      lirean();
      if(serie == LOW){               //On envoie le message à l'ordinateur si pin2=GND
      Serial.println("Panne feu");    //sans effet si pin2=HIGH au démarrage
     temps = millis();                  //On démarrage un compteur pour la durée de la panne
    }
    }
   panne = HIGH;
   for(i=0; i<cligno; i++)   
   {
   lirean();
   analogWrite(ledr1, 0);
   analogWrite(ledr2, 0);      
   analogWrite(ledj1, val_potarj);
   analogWrite(ledj2, val_potarj);
   analogWrite(ledv1, 0);
   analogWrite(ledv2, 0);      
   delay(100);
   }
    for(i=0; i<cligno; i++)   
   {
   lirean();
   analogWrite(ledr1, 0);
   analogWrite(ledr2, 0);      
   analogWrite(ledj1, 0);
   analogWrite(ledj2, 0);
   analogWrite(ledv1, 0);
   analogWrite(ledv2, 0);      
   delay(100);
   }
  }
  lirean();
  if(panne && etatbouton)
  {  if(serie == LOW){             //On envoie le msg à l'ordi si PIN2= LOW
  Serial.print("Duree panne: ");        //sans effet si pin2=HIGH au démarrage
  dureepanne = (millis()-temps);        
  Serial.print(dureepanne);
  Serial.println("ms");
  Serial.println("Fin de panne");
  Serial.println(" ");
  }
  panne = LOW;
  i = 0;  
  }  
}


void lireserie (){
      // Vérifier si des caractères sont reçu sur le port série
    if (Serial.available() > 0) {
      
       // Variable temporaire pour copier le caractère lu
//       char SerialInByte;
       // Lire un caractère (un Byte)
       SerialInByte = Serial.read();
      
       // Si c'est <CR> --> traiter la commande
       if(SerialInByte==13){
          ProcessCmd();
       }else{
          // sinon, ajouter le caractère à la mémoire tampon (cmd)
          cmd += String(SerialInByte);
       }
    }
  }
 
    
void clearCmd(){      // Réinitialiser le buffer (et vider le port série)
  cmd="";
  Serial.flush();
}

 
void ProcessCmd() {  // Interpréter la commande reçue
      
    machaine=cmd.substring(0,3);
 //   Serial.println(machaine);
 //############################   MODE NORMAL   #################################
    if(machaine.equals("XON")) {
      if(panneserie == LOW){
      Serial.println("Le feu est deja en mode normal!");  
      goto fin;
      }
      Serial.println("Mode manuel: normal");
      panneserie = LOW;
      clearCmd();
      goto fin;
          }
    if(machaine.equals("XOF")){
      if(panneserie == HIGH){
      Serial.println("Le feu est deja en mode panne!");  
      goto fin;
      }
      Serial.println("Mode manuel: panne");
      panneserie = HIGH;
      clearCmd();
      goto fin;      
    }
 
    Serial.println("Cette commande est incorrecte. Veuillez essayer XON ou XOFF.");   
    fin:

   clearCmd();                //Si donnée incorrecte
   
 
}



10/07/2013
0 Poster un commentaire

A découvrir aussi


Inscrivez-vous au blog

Soyez prévenu par email des prochaines mises à jour

Rejoignez les 2 autres membres