/*
**************************************************************************************
** **
** Mesure et calcule de la vitesse des trains dans leur sens de marche sur 1 voie. **
** **
** Mentionner la distance entre les 2 capteur infrarouge (variable "Distance"), **
** puis sélectionner l'échelle "N" ou "HO" (variable "Echelle") et si besoin **
** changer le temps maximum avant la detection de Fin (variable "Delais"). **
** **
** - créé le 19 décembre 2024 - **
** - modifié le 21 juin 2025 - **
** **
**************************************************************************************
*/
// Import de la librairie pour l'afficheur LCD
#include <LiquidCrystal.h>
// Initialise la librairie avec les pins à connecter
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
// Initialisation des variables
int Voie; // Voie de mesure
int VoieDebut = 2; // Barrière optique Début
int VoieFin = 0; // Barrière optique Fin
int lectdeb; // Valeur lue sur les barrières optiques
int lectfin; // Valeur lue sur les barrières optiques
int Tdebut; // Temps sur la barrière début
int debut; // Détection début
int Tfin; // Temps sur la barrière fin
int fin; // Détection fin
int Temps; // Temps de passage ( = Tfin - Tdebut )
float Vitesse; // Vitesse calculée
double Coef; // Coefficient d'échelle
unsigned long timer; // Base du compteur
byte Compteur = 0; // Compteur après détection capteur début
// - Variable à personnaliser - //
const int Echelle = "N"; // Défini l'échelle employée (N ou HO)
long Distance = 100; // Distance entre les barrières infrarouge en mm
byte Delais = 30; // Délais avant raz détection
// Initialisation du caractères personnalisés (e en exposant)
byte expo[8] = {
B01110,
B10001,
B11110,
B10000,
B01110,
B00000,
B00000,
B00000,
};
// Initialisation du caractères personnalisés (é)
byte eaigu[8] = {
B00010,
B00100,
B01110,
B10001,
B11110,
B10000,
B01110,
B00000,
};
// Initialisation Arduino
void setup() {
// Défini les colonnes et lignes, affiche la première ligne et la fin de la seconde
lcd.createChar(0, expo); // Mémorise le caractère spécial
lcd.begin(16, 2); // Déclaraton du type d'afficheur 16 cracteres sur 2 lignes
lcd.clear();
lcd.setCursor (0, 0); // Positionne le curseur ligne 1 colonne 2
lcd.print("Vitesse"); // Ecrit "Vitesse"
lcd.setCursor(8, 0); // Positionne le curseur ligne 1 colonne 10
if ( Echelle == "N" ) { // Echelle "N"
Coef = 576,00;
lcd.print ("au 160"); // Ecrit "au 160" à la suite de "vitesse"
lcd.setCursor(14, 0); //Positionne le curseur ligne 1 colonne 16
lcd.write(byte(0)); // Ecrit le caractère spécial
}
if ( Echelle == "HO" ) { // Echelle "HO"
Coef = 313,20;
lcd.print ("au 87"); // Ecrit "au 87" à la suite de "vitesse"
lcd.setCursor(14, 0); //Positionne le curseur ligne 1 colonne 15
lcd.write(byte(0)); // Ecrit le caractère spécial
}
lcd.setCursor(0, 1); // Positionne le curseur ligne 2 colonne 1
lcd.print(" < En attente > "); // Efface la deuxième ligne
}
// Programmation Arduino
void loop() {
debut = 0;
fin = 0;
Compteur = 0;
// Détection sur capteur de Début
while (debut == 0 ) {
// Détection d'un train en sens inverse
lectfin = analogRead (VoieFin); // Lis la tension de la broche fin
if ( lectfin < 200 ) { // Si déctection retour au début de la boucle
lcd.setCursor(0, 1); // Positionne le curseur ligne 2 colonne 1
lcd.print("Train contresens"); // Efface la deuxième ligne
while (true) {
if (millis() - timer > 995) {// si 995 ms se sont écoulées - ajouter une seconde à la variable Compteur
timer = millis();
Compteur++;
}
if (Compteur >= Delais) { // attente xx secondes selon délais paramètré
goto Abandon;
}
lectdeb = analogRead (VoieDebut); // Lis la tension de la broche début
if ( lectdeb < 200 ) {
delay (500);
goto Abandon;
}
}
}
// Détection début d'un train
lectdeb = analogRead (VoieDebut); // Lis la tension de la broche début
if ( lectdeb < 200 ) { // Si la tension est inférieur à 1 Volt
Tdebut = millis ();
debut = 1;
lcd.createChar(1, eaigu); // Mémorise le caractère spécial
lcd.setCursor(0, 1); // Positionne le curseur ligne 2 colonne 1
lcd.print("D"); // Efface la deuxième ligne
lcd.setCursor(1, 1); // Positionne le curseur ligne 2 colonne 2
lcd.write(byte(1)); // Ecrit le caractère spécial
lcd.setCursor(2, 1); // Positionne le curseur ligne 2 colonne 3
lcd.print("tection train");
Compteur = 0;
}
}
// Détection sur capteur de Fin
while (fin == 0 ) {
if (millis() - timer > 995) {// si 995 ms se sont écoulées - ajouter une seconde à la variable Compteur
timer = millis();
Compteur++;
}
if (Compteur >= Delais) { // attente xx secondes selon délais paramètré
goto Abandon;
}
lectfin = analogRead (VoieFin); // Lis la tension de la broche fin
if ( lectfin < 200 ) { // Si la tension est inférieur à 1 Volt
Tfin = millis ();
fin = 1;
}
}
Temps = Tfin - Tdebut; // Calcule le temps entre Fin et Début
Vitesse = Coef * Distance / Temps;
lcd.setCursor(0, 1); // Positionne le curseur ligne 2 colonne 1
lcd.print(" "); // Efface la 2ème ligne (16 espaces)
lcd.setCursor(1, 1); // Repositionne le curseur ligne 2 colonne 2
lcd.print(Vitesse); // Ecrit la vitesse calculée
lcd.setCursor(8, 1); // Repositionne le curseur ligne 2 colonne 9
lcd.print("Km/h"); // Ecrit
delay (5000); // Affichage pendant 5 secondes
Abandon:
lcd.setCursor(0, 1); // Positionne le curseur ligne 2 colonne 1
lcd.print(" < En attente > "); // Efface la deuxième ligne
}Capteur début
Capteur fin