J'ai une programme simulant le fonctionnement d'un passage à niveau.
Il fonctionne de la manière suivante :
détection du train par les capteurs IR A ou B
les led clignotent
Abaissement des barrières après 7 secondes
Les led continuent de clignoter tant que le train n'est pas passé
détection du train en sortie B ou A
Arret des led
Lever les barrières
Je n'arrive pas à faire un clignoter les LED pendant 7 secondes avant l'abaissement des barrières
c'est au niveau de l'appel de la fonction Signal()...
// Détection du passage d'un train par capteur infra-rouge
// Baisser 2 barrières et allumer 2 diodes en clignotement
#include <VarSpeedServo.h> // Inclure dans le programme les fonctions de gestion des servo-moteurs avec gestion de la vitesse
// Attribution des emplacements ou sont reliés les fils sur les broches de la carte Arduino
// Ces emplacements déclarés en constante (const) ne changeront pas durant tout le programme
const int capteurA = 0; // Le signal du capteur A est brancé sur l'entée analogique A0 de la carte Arduino
const int capteurB = 2; // Le signal du capteur B est brancé sur l'entée analogique A2 de la carte Arduino
const int diodeA = 10; // la diode A est reliée à l'entrée/sortie numérique 10 de la carte Arduino
const int diodeB = 12; // la diode B est reliée à l'entrée/sortie numérique 11 de la carte Arduino
const int barriereA = 2; // le servoA est reliée à l'entrée/sortie numérique 2 de la carte Arduino
const int barriereB = 4; // le servoB est reliée à l'entrée/sortie numérique 4 de la carte Arduino
VarSpeedServo servoA;
VarSpeedServo servoB;
unsigned long compteur_temps; // Une varible qui va permettre de compter le temps pour faire clignoter à intervale fixe les leds
unsigned long compteur_delais; // Une varible qui va permettre de compter le délais pour faire abaisser les barrieres
// Déclaration des variables, les variables stockent des informations qui peuvent varier durant le fonctionnement du programme
int angle_barriere_fermee = 110; // angle du servo pour mettre la barriere en position basse
int angle_barriere_ouverte = 40; // angle du servo pour mettre la barriere en position haute
int valeur_capteurA = 1023; // Cette variable recevra l'information du capteurA (plus de 512 si pas de détection et moins de 512 si il y a une détection de passage
int valeur_capteurB = 1023; // Cette variable recevra l'information du capteurA (plus de 512 si pas de détection et moins de 512 si il y a une détection de passage
int premier_capteur = 0; // Cette variable contiendra 1 si c'est le capteurA qui a détecté en premier le train, 2 si c'est le capteur B et 0 autrement
boolean train_engage = false; // variable que l'on met à 0 si il n'y a pas de détection de train et à 1 si un train est détecté
boolean barriere_ouverte; // variable à 1 si les barrières sont ouvertes et à 0 si elles sont fermées
int memo_timer; // une variable qui va permettre de compter le temps pour faire clignoter les leds
boolean etat_signal = false; // une variable contenat 0 si les leds sont eteintes et 1 si elles sont allumlées
// Au lancement du programme on initialise les broches de la carte et les objets de notre programmation
void setup() {
// On declare que les broches ou sont reliées les diodes sont des sorties pour la carte Arduino
pinMode(diodeA,OUTPUT);
pinMode(diodeB,OUTPUT);
// On relie caque objet servo à la broche qui lui a été désignée
servoA.attach(barriereA);
servoB.attach(barriereB);
// On place les barrières en position ouverte
servoA.write(angle_barriere_ouverte);
servoB.write(angle_barriere_ouverte);
barriere_ouverte = true;
}
// On fait une boucle que le programme va executer indéfiniment
void loop() {
valeur_capteurA = analogRead(capteurA);
valeur_capteurB = analogRead(capteurB);
if (train_engage == 1 && premier_capteur == 0) {
if (valeur_capteurA > 512 && valeur_capteurB > 512) {
servoA.slowmove(angle_barriere_ouverte,30);
servoB.slowmove(angle_barriere_ouverte,30);
barriere_ouverte = true;
digitalWrite(diodeA,LOW);
digitalWrite(diodeB,LOW);
train_engage = 0;
}
}
// Si il n'y a pas de train entre les 2 capteurs
if (train_engage == false) {
// On regarde si un capteur détecte une présence
if (valeur_capteurA < 512 || valeur_capteurB < 512) {
train_engage = true;
// On met en mémoire quel capteur à détecté l'arrivée du train
if (valeur_capteurA < 512) {
premier_capteur = 1;
} else {
premier_capteur = 2;
}
}
// Si un train est engagé entre les 2 capteurs
} else {
Signal(); // On met le signal en route
if (barriere_ouverte == true) { // Un train viens de s'engager et les barrières sont ouvertes donc on ferme
// On place les barrières en position fermée
// servo.slowmove(angle,speed) | Speed 0 or 255: maximum, 1-254 from lower to higher speed
servoA.slowmove(angle_barriere_fermee,30);
servoB.slowmove(angle_barriere_fermee,30);
// On met à 0 la variable d'information sur la position desbarrières
barriere_ouverte = false;
}
// On teste si le 2eme capteur detecte le passage du train pour ouvrir les barrières
// On regarde si c'est le capteurA qui a détecté l'arrivée du train
if (premier_capteur == 1) {
if (valeur_capteurB < 512) {
premier_capteur = 0;;
}
}
if (premier_capteur == 2) { // Si non c'est que c'est le 2eme capteur
if (valeur_capteurA < 512) {
premier_capteur = 0;
}
}
}
delay(10);
}
//**************************************************************************
// Fonction pour faire clignoter les leds
void Signal() {
if (millis() > compteur_temps + 800) { //Vitesse clignottement 250
compteur_temps = millis();
if (etat_signal == false) {
etat_signal = true;
digitalWrite(diodeA,HIGH);
digitalWrite(diodeB,HIGH);
} else {
etat_signal = false;
digitalWrite(diodeA,LOW);
digitalWrite(diodeB,LOW);
}
}
}
Pour éviter des soucis dans une cinquantaine de jour quand milllis() va revenir à 0 il vaut mieux écrire if (millis() - compteur_temps > 800) { //Vitesse clignotement 250(et le commentaire n'est pas adapté)
j'ai pas lu tout le code, mais appelez vous la fonction Signal() à chaque tour de loop() quand il faut que le signal soit actif ?
il faudrait une variable qui mémorise l'état du signal - attente_ clignotement, clignotement actif, clignotement_terminé. par défaut vous êtes en attente clignotement. au moment du déclenchement du signal vous notez l'heure de départ (pour compter vos 7 secondes) et passez au mode clignotement _actif. tant que vous êtes dans ce mode vous clignotez à la fréquence souhaitée, puis quand vous avez eu les 7 secondes alors vous passez au rouge et au mode clignotement_terminé. La fonction signal saura alors qu'il ne faut plus clignoter. jusqu'à la prochaine initialisation
Je n'ai pas trop de soucis sur les 50 jours, l'arduino ne reste guère plus longtemps que 24h en tension.
Mais merci de la remarque (c'est 800ms de clignotement).
Effectivement la fonction Signal() est appellée à tour de loop() quand le signal est actif (quand indifféremment capteur A ou capteur B passe actif).
Pour cela j'aurais mis une fonction loop() dans la première avec une autre fonction millis()
const long tempo_led = 7000;
void loop() {
blablabla
void loop() {
unsigned long x = millis();
while(millis() - x < tempo_led){
Signal();
}
Signal();
et la suite ....
68tjs:
"Signal" (avec ou sans majuscule je ne sais plus) est une macro Atmel "deprecated" remplacée par ISR.
N'y a-t-il pas de risque à utiliser ce nom ?
c'était une macro, tout en majuscule, donc pas de soucis - mais bon réflexe!
Ça fonctionne !
J'ai bien les 7 secondes de délais. Merci !
Mais je ne sais pas pourquoi ça me sort la partie détection de sortie.
Si le capteur A ou B enclenche la fonction clignotement et servos, puis clignotement, normalement il faut que B ou A déclenche l'arrêt de "Signal()" et le mouvement des servos.
Or là ça fonctionne que quand le capteur B est actifs assez longtemps et avec un délais de 7 secondes...
Sans l'ajout du bloc while l'arrêt de Signal() se faisait correctement à l'instant où le capteur opposé était actif.
// Détection du passage d'un train par capteur infra-rouge
// Baisser 2 barrières et allumer 2 diodes en clignotement
#include <VarSpeedServo.h> // Inclure dans le programme les fonctions de gestion des servo-moteurs avec gestion de la vitesse
// Attribution des emplacements ou sont reliés les fils sur les broches de la carte Arduino
// Ces emplacements déclarés en constante (const) ne changeront pas durant tout le programme
const int capteurA = 0; // Le signal du capteur A est brancé sur l'entée analogique A0 de la carte Arduino
const int capteurB = 2; // Le signal du capteur B est brancé sur l'entée analogique A2 de la carte Arduino
const int diodeA = 10; // la diode A est reliée à l'entrée/sortie numérique 10 de la carte Arduino
const int diodeB = 12; // la diode B est reliée à l'entrée/sortie numérique 11 de la carte Arduino
const int barriereA = 2; // le servoA est reliée à l'entrée/sortie numérique 2 de la carte Arduino
const int barriereB = 4; // le servoB est reliée à l'entrée/sortie numérique 4 de la carte Arduino
VarSpeedServo servoA;
VarSpeedServo servoB;
unsigned long compteur_temps; // Une varible qui va permettre de compter le temps pour faire clignoter à intervale fixe les leds
const long tempo_led = 7000; // Une varible qui va permettre de compter le délais pour faire abaisser les barrieres
// Déclaration des variables, les variables stockent des informations qui peuvent varier durant le fonctionnement du programme
int angle_barriere_fermee = 110; // angle du servo pour mettre la barriere en position basse
int angle_barriere_ouverte = 40; // angle du servo pour mettre la barriere en position haute
int valeur_capteurA = 1023; // Cette variable recevra l'information du capteurA (plus de 512 si pas de détection et moins de 512 si il y a une détection de passage
int valeur_capteurB = 1023; // Cette variable recevra l'information du capteurA (plus de 512 si pas de détection et moins de 512 si il y a une détection de passage
int premier_capteur = 0; // Cette variable contiendra 1 si c'est le capteurA qui a détecté en premier le train, 2 si c'est le capteur B et 0 autrement
boolean train_engage = false; // variable que l'on met à 0 si il n'y a pas de détection de train et à 1 si un train est détecté
boolean barriere_ouverte; // variable à 1 si les barrières sont ouvertes et à 0 si elles sont fermées
int memo_timer; // une variable qui va permettre de compter le temps pour faire clignoter les leds
boolean etat_signal = false; // une variable contenat 0 si les leds sont eteintes et 1 si elles sont allumlées
// Au lancement du programme on initialise les broches de la carte et les objets de notre programmation
void setup() {
// On declare que les broches ou sont reliées les diodes sont des sorties pour la carte Arduino
pinMode(diodeA,OUTPUT);
pinMode(diodeB,OUTPUT);
// On relie caque objet servo à la broche qui lui a été désignée
servoA.attach(barriereA);
servoB.attach(barriereB);
// On place les barrières en position ouverte
servoA.write(angle_barriere_ouverte);
servoB.write(angle_barriere_ouverte);
barriere_ouverte = true;
}
// On fait une boucle que le programme va executer indéfiniment
void loop() {
valeur_capteurA = analogRead(capteurA);
valeur_capteurB = analogRead(capteurB);
if (train_engage == 1 && premier_capteur == 0) {
if (valeur_capteurA > 512 && valeur_capteurB > 512) {
servoA.slowmove(angle_barriere_ouverte,30);
servoB.slowmove(angle_barriere_ouverte,30);
barriere_ouverte = true;
digitalWrite(diodeA,LOW);
digitalWrite(diodeB,LOW);
train_engage = 0;
}
}
// Si il n'y a pas de train entre les 2 capteurs
if (train_engage == false) {
// On regarde si un capteur détecte une présence
if (valeur_capteurA < 512 || valeur_capteurB < 512) {
train_engage = true;
// On met en mémoire quel capteur à détecté l'arrivée du train
if (valeur_capteurA < 512) {
premier_capteur = 1;
} else {
premier_capteur = 2;
}
}
// Si un train est engagé entre les 2 capteurs
} else {
{ // début du bloc
unsigned long x = millis();
while(millis() - x < tempo_led) Signal();
} // fin du bloc
Signal(); // On met le signal en route
if (barriere_ouverte == true) { // Un train viens de s'engager et les barrières sont ouvertes donc on ferme
// On place les barrières en position fermée
// servo.slowmove(angle,speed) | Speed 0 or 255: maximum, 1-254 from lower to higher speed
servoA.slowmove(angle_barriere_fermee,30);
servoB.slowmove(angle_barriere_fermee,30);
// On met à 0 la variable d'information sur la position desbarrières
barriere_ouverte = false;
}
// On teste si le 2eme capteur detecte le passage du train pour ouvrir les barrières
// On regarde si c'est le capteurA qui a détecté l'arrivée du train
if (premier_capteur == 1) {
if (valeur_capteurB < 512) {
premier_capteur = 0;;
}
}
if (premier_capteur == 2) { // Si non c'est que c'est le 2eme capteur
if (valeur_capteurA < 512) {
premier_capteur = 0;
}
}
}
delay(10);
}
//**************************************************************************
// Fonction pour faire clignoter les leds
void Signal() {
if (millis() > compteur_temps + 800) { //Vitesse clignottement 800ms H/L
compteur_temps = millis();
if (etat_signal == false) {
etat_signal = true;
digitalWrite(diodeA,HIGH);
digitalWrite(diodeB,HIGH);
} else {
etat_signal = false;
digitalWrite(diodeA,LOW);
digitalWrite(diodeB,LOW);
}
}
}