Le réseau : Motorisation des barrières d'un passage à niveau Jouef
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
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