website logo

Motorisation des barrières d'un passage à niveau Jouef

lundi 03 mai 2021 @ 19:45:01

Sujet : Les servomoteurs commandés par Arduino







Prototype à refaire proprement avec des barrières plus jolies et détaillées. Peut-être  diminuer la vitesse de mouvement mais surtout ajouter le fonctionnement d'une led clignotante et, pourquoi pas de la sonnerie adéquate.

J'ai reçu les PCB

149505909_1568873219978585_7571848644473367403_o.jpg

 

Code provisoire :

voici la dernière mouture du programme



//*************************************************************************
// GESTION D'UN PASSAGE A NIVEAU PAR SERVOMOTEUR
//*************************************************************************
// le 01/02/2021 à 17:00
// testé le 01/02/2021 à 17H00 
// led avec millis() => OK
// testé le 04/02/2021 => OK
// à ajouter la gestion du son : 
//    - démarrage en même temps que la led.
//    - arrêt avec la fin d'ouverture de la barrière.
// testé avec le son le 05/03/2021 15H30 => rallonger la durée de l'enregistrement audio car loop s'entend à chaque reprise du morceau
//=========================================================================
// I) Détection de la présence d'un convoi : 
//           * soit par un jeu de 2 détecteurs IR
//           * soit par une platine de détection de présence
// pour la mise au point on va utilier un BP momentané pour simuler les 
// contacts du relais de détection.
// 
// II) Une led clignotante doit s'allumer quelques secondes avant l'abaissement
// de la barrière et s'arrêter quelques secondes après qu'elle soit relevée.
// Dans un premier temps le codage utilisera une diode clignotante mais on 
// pourra tester une diode et un système de tâche de fond.
//
// On va essayer d'utiliser les astuces pour effectuer plusieurs tâches en 
// même temps
//
// III) La dernière position sera enregistrée dans l'eeprom (bof ... à quoi ca sert .... )
//=========================================================================

#i n c l u d e "EEPROM.h"
#i n c l u d e "Servo.h"                                            
#i n c  l u d e "LiquidCrystal_PCF8574.h"
#i n c l u d e "Arduino.h"
#i n c l u d e "SoftwareSerial.h"
#i n c l u d e "DFRobotDFPlayerMini.h"

SoftwareSerial mySoftwareSerial(10, 11);                        // RX, TX sur les pin 10 et 11 avec une résistance de 1 Ko en série
DFRobotDFPlayerMini myDFPlayer;

Servo servoPassageNiveau;

const int PointMilieuT = 1500;
int angleMin = 1350;                                            // à déterminer. PaN fermé
int angleMax = 1820;                                            // à déterminer. PaN ouvert 
int angleIntermediaire;                                         // valeur de l'angle intermédiaire pendant le mouvement
int DernierePositionServo   ;                                   // PointMilieuT = milieu, angleMin = bas, angleMax = haut
bool sensMouvement = 1;                                         
const byte Temporisation = 10;                                  // Règle la vitesse de rotation du servo en introduisant une pause
                                                                // entre chaque rotation.

const byte pinBPMilieu = A0;                                    // BP de mise au point milieu connecté sur A0
const byte pinDetecteur1 = A1;                                  // BP / Relais détection connecté à A1
const byte pinLed = 2;                                          // led connectée sur D2 
const byte pinServo = 3;                                        // Les servos sont connectés sur D3

int detectionPresence = 0;                                      // convoi présent = 1 - pas de convoi = 0
bool etatBarriere = 1;                                          // barriere levée = 1 - barriere baissée = 0

bool departTempoTache1 = 0;
unsigned long departTache1 = 0;
         
bool departTempoLed = 0;
const long tempoLed = 400;                                      // durée du clignotement de la led

// les drapeaux pour l'affichage
bool X = 0;                                                     // drapeau affichage présence train et état barrières
bool Y = 0; 
bool Z = 0;                                                     // drapeau lancement du son                           

void setup() {
  
  Serial.begin(9600); 
  pinMode(pinLed, OUTPUT);
  pinMode(13, OUTPUT);                                          // utilisation de la led interne en rappel témoin.
  
  mySoftwareSerial.begin(9600);
  
  /* reprise du code de gestion de la carte Dfplayer */
  Serial.println();
  Serial.println(F("DFRobot DFPlayer Mini Demo"));
  Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));
  
  if (!myDFPlayer.begin(mySoftwareSerial)) {  //Use softwareSerial to communicate with mp3.
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while(true){
      delay(0); // Code to compatible with ESP8266 watch dog.
    }
  }
  Serial.println(F("DFPlayer Mini online.")); 
  /* fin de la reprise de code */
 
  myDFPlayer.volume(20);                                        // ajustement du volume sonore
  
  /* lecture de la dernière position dans l'eeprom */
  DernierePositionServo = EEPROM.read(10) | ((int)EEPROM.read(11)) << 8;  // lecture des 2 bytes pour int angleMin[]
  // int positionActuelle = servoPassageNiveau.read();          // test de la fonction read, inutile ici
  
  if (DernierePositionServo > angleMax || DernierePositionServo < angleMin){ // si incohérence de valeur ou initialisation (=255)       
      DernierePositionServo = angleMax;                         // on défint le PaN comme étant ouvert
      etatBarriere = 1;
      EEPROM.update(10,DernierePositionServo & 0xFF);           // écrit le premier byte de la valeur int
      EEPROM.update(10 + 1, DernierePositionServo >> 8);        // écrit le second byte de la valeur int
  } else if (DernierePositionServo < PointMilieuT){
      DernierePositionServo = angleMin;
      etatBarriere = 0;
  } else {
      DernierePositionServo = angleMax;
      etatBarriere = 1; 
  } //  if (DernierePositionServo > limitAngleMax || DernierePositionServo < limitAngleMin)
  
  /* positionnement à la derniere position */ 
  angleIntermediaire = DernierePositionServo;                   // on met le servo à sa dernière position => à reprendre  éventuellement pour une boucle
  servoPassageNiveau.attach(pinServo);
  servoPassageNiveau.writeMicroseconds(angleIntermediaire);

  departTache1 = millis(); 
  do { 
      if (millis() - departTache1 >= 150ul){
          servoPassageNiveau.detach();
          Serial.println("Setup - Servo détaché");
          departTache1 = 0;
          break;  
      }
  }
  while(1);
   
} // fin de setup

int tacheLed(int actionLed) {
// fonction de gestion de la led
  static byte etatLed = LOW;
  static unsigned long precedentLed = 0;
  unsigned long actuelLed =0;

  if (actionLed == 1){   
  // on lance l'allumage de la led   
      actuelLed = millis();      
      if (actuelLed - precedentLed >= tempoLed) {       
        precedentLed = actuelLed;
        if (etatLed == LOW) {         
          etatLed = HIGH;        
        }else{         
          etatLed = LOW;       
        } // fin de if (etatLed == LOW) 
              
        digitalWrite(pinLed, etatLed);     
        digitalWrite(13, etatLed);  
      } // fin de if (actuelLed - precedentLed >= tempoLed)     
  } else {
  // on arrête le clignotement de la led en position éteinte
      etatLed = LOW;
      digitalWrite(pinLed, etatLed); 
      digitalWrite(13, etatLed); 
  // et on arrête le son
      myDFPlayer.pause();Z = 0;         
  } // fin de if (actionLed == 1)
  
} // fin de fonction

void loop() {
  if (analogRead(pinBPMilieu) <= 512){
      /* REGLAGE DU POINT MILIEU */
      pointMilieu();
      
  } else {
      detectionPresence = analogRead(pinDetecteur1);   
      if(departTempoLed == 1) tacheLed(1);
      if (detectionPresence <= 512){                             // convoi détecté    
        if (Z == 0)  myDFPlayer.loop(2); Z += 1;                 // on joue le 2ème mp3 (sonnerie PaN) de la carte micro SD
          if (etatBarriere == 1){                                // état barrière levée    
             departTempoLed = 1;                                 // on lance le clignotement de la led
             if (departTache1 == 0) {
                departTache1 = millis();
             } else if (millis() - departTache1 >= 1500) {       // on abaisse la barrière après 1.5 secondes
                fermetureBarriere();     
                departTache1 = 0;
             } // fin de if ( millis() - departTache1 >= 1500)                                   
          } // fin de if (etatBarriere == 1)
  
      } else if (detectionPresence > 512){                      // pas de convoi
          if (etatBarriere == 0){                               // état barrière baissée  => on doit la lever
             ouvertureBarriere();                               // on relève la barrière
          } else {  
             if (departTache1 == 0) {
                departTache1 = millis();
             } else if (millis() - departTache1 >= 1500) {                                        
                tacheLed(0); departTempoLed = 0;                // on arrête le clignotement de la led     
                departTache1 = 0;                     
             } // fin de if ( millis() - departTache1 >= 1500)                          
          } // fin de if (etatBarriere == 0)
          
      } // fin de if (detectionPresence <= 512)
      
  } // fin de if (analogRead(pinBPMilieu)) < 512
} // fin de loop

void pointMilieu(void){
        servoPassageNiveau.attach(pinServo);
        // int positionServo = servoPassageNiveau.readMicroseconds(); // test de la fonction => inutile ici
          servoPassageNiveau.writeMicroseconds(PointMilieuT);    //  à reprendre pour une boucle
          angleIntermediaire = PointMilieuT;
          delay(150);
          servoPassageNiveau.detach();
        if (X == 0) {  
          Serial.println("Servo au point milieu ... détaché!");
          X += 1;
          Y = 0;
        }
} // fin de fonction

void fermetureBarriere(void) {
      if (X == 0) {  
        Serial.println("Barrière fermante ...");
        X += 1;
        Y = 0; 
      }
      
      servoPassageNiveau.attach(pinServo);
      while (angleIntermediaire > angleMin) {        
          angleIntermediaire = angleIntermediaire - sensMouvement;
          servoPassageNiveau.writeMicroseconds(angleIntermediaire); 
          tacheLed(1);    
          delay(Temporisation);       
      } // fin de while 

      delay(150);
      etatBarriere = 0;
      servoPassageNiveau.detach(); 
      Serial.println("Barrière fermée. Servo détaché!");
      /* Enregistrement de la dernière position */                
      EEPROM.update(10, angleIntermediaire & 0xFF);                   // écrit le premier byte de la valeur int
      EEPROM.update(11, angleIntermediaire >> 8);                     // écrit le premier byte de la valeur int 
} // fin de fonction

void ouvertureBarriere(void){
      if (Y == 0) {
        Serial.println("Barrière ouvrante ...");
        Y += 1;     
        X = 0; 
      }
      
      servoPassageNiveau.attach(pinServo);
      while (angleIntermediaire < angleMax) { 
          angleIntermediaire = angleIntermediaire + sensMouvement;
          servoPassageNiveau.writeMicroseconds(angleIntermediaire);     
          tacheLed(1);
          delay(Temporisation);       
      } // fin de while   
      delay(150);
      etatBarriere = 1;
      servoPassageNiveau.detach(); 
      Serial.println("Barrière ouverte. Servo détaché!");
      /* Enregistrement de la dernière position */                
      EEPROM.update(10, angleIntermediaire & 0xFF);             // écrit le premier byte de la valeur int
      EEPROM.update(11, angleIntermediaire >> 8);               // écrit le premier byte de la valeur int
} // fin de fonction	

 

Test avec le son

Nouvelle vidéo avec la led et la platine

Test de montage mécanique

et avec la platine définitive incluant le lecteur de carte SD




Cet article provient de Le réseau du Mesnil-sur-Jorg
L'url pour cet article est : http://wgnt-train.fr/article.php?sid=188