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
Pages vues depuis 15/01/2020 : 341 462