Je reprends mon travail sur la gestion des aiguillages par Arduino.
Après avoir testé plusieurs solutions plus ou moins sophistiquées sur des Arduino Nano ou Mini Pro, je pars sur un travail totalement basique avec un "gros" Mega 2560 pour 16 servos-moteurs.
Le système comprend 4 éléments.
Comme d'habitude, j'ai dessiné les PCB et il ont été fabriqués par JLCPCB.
La carte principale dessinée sous forme d'un shield qui vient s'enfficher sur les plots de l'arduino Mega 2560.
On trouve 2 régulateurs 5 volts. Le premier pour alimenter l'arduino seul, le second pour alimenter les 16 servos, les 32 leds de direction et l'écran LCD. A droite 16 sorties pour connecter les servomoteurs, en dessous une entrée DCC pour de futurs développements et en bas 4 74HC595 pour gérer les 32 leds bicolores du TCO. On voit également un connecteur (4 fils) pour l'écran, un connecteur (10 fils) d'entrée/sortie pour le clavier (modes de fonctionnement et réglages) et 2 connecteurs (9 et 10 fils) d'entrée toujours pour le clavier afin de recevoir les instructions des boutons poussoirs.
Un clavier "numérique" (par opposition aux claviers analogiques branchés sur un seul pin analogique) qui sera plutôt réservé aux tests et règlages. Il comprend 16 boutons poussoirs pour commander chacun des servmoteurs. Ces boutons poussoirs sont doublés de 16 pastilles de contact qui permettent de vérifier le bon fonctionnement du système de stylet qui sera employé sur le TCO. Le clavier numérique sera donc également connecté au PCB du TCO.
Un écran LCD pour lire les informations et directives.
Et enfin la platine du TCO un grand PCB au format A3 qui reprendra le tracé de mon réseau et incorporera les leds de direction des aiguillages ainsi que des points de touches permettant de commander les aiguillages plus "visuellement" par un simple "touché" d'un stylet sur un plot conducteur.
CE PCB est en cours d'étude et de dessin mais en voici l'ébauche. Il sera relié aux connecteurs des 4 74HC595 pour les leds de direction et au clavier pour la sélection des aiguillages à manoeuvrer.
Il y aura donc deux exemplaires de ce système pour gérer l'ensemble du réseau.
voici la dernière mouture du programme
/* Gestion de 16 aiguillages sur une carte arduino Mega 2560
*
* PCB Arduino Gestion 16 aiguillages par Mega 2560_b.dip
* Arduino Clavier digital.dip
* Ecran LCD par I2C
*
* 4 modules supplémentaires 74HC595
*
* 1 entrée DCC pour de futurs développements
*
*##### les interruptions Mega2560 ##### (corrigées)
* Pin #2 = interruption #4
* Pin #3 = interruption #5
* Pin #18 = interruption #3
* Pin #19 = interruption #2
* Pin #20 = interruption #1
* Pin #21 = interruption #0
* Détection du clavier par interruption sur D18
* LOW to trigger the interrupt whenever the pin is low,
* CHANGE to trigger the interrupt whenever the pin changes value
* RISING to trigger when the pin goes from low to high,
* FALLING for when the pin goes from high to low.
* HIGH to trigger the interrupt whenever the pin is high.
*#############################
* Début le 09/05/2022
* MAJ le 01/06/2022 => ajout du réglage de la valeur du ralenti => OK
* => ajout d'une led de visualisation de la valeur de valRalenti => OK
* => ajout de bounce sur les BP de réglage de valRalenti et de mise au point milieu => OK
* MAJ le 03/06/2022 => modification de l'enregistrement en eeprom de valRalenti. => OK
* MAJ le 04/06/2022 => mise en place de la procédure de point milieu
* TESTS le 05/06/2022 => OK
* MAJ le 06/06/2022 => forcer la mise en place à la dernière position quand on revient en mode commande => à faire
* MAJ le 14/06/2022 => séparation des boucles pour l'initialisation des Servos => tests à terminer.
* MAJ le 14/07/2022 => remplacemment des réglages par potentiomètre par un réglage avec 2 boutons => OK
* MAJ le 17/07/2022 => ajout de la bibliothèque Bounce2
* MAJ le 17/07/2022 => affichage du sens en cours de déplacement => OK
* MAJ le 18/07/2022 => ajout réglage ralenti en mode Réglage => OK
* MAJ le 20/07/2022 => procédure de validation à continuer! Difficultés avec la gestion du poussoir par Bounce2
* MAJ le 23/07/2022 => abandon de l'utilisation de bounce2 dans la procédure "validationReglages => OK
* => revoir l'utilisation du reglage du ralenti (ne fonctionne pas en cours de reglage des butées) => OK
* => voir la possibilité d'une procédure de PointMilieu général pour positionnement mécanique => fait => OK ..... utilisation seulement en position réglage ... doit désactiver tout le reste
* le 09/08/2022 => modification du timing des beep Commande / Arrêt => OK
* => modification séquence d'allumage de la led du ralenti pendant la procédure PM => OK
* le 11/08/2022 => affichage des valeurs de positions initiales des aiguillages => OK
* le 27/08/2022 => ajout d'une fonction de mise en veille
*/
#include "Wire.h"
#include "EEPROM.h" // bibliothèque pour gérer la mise en mémoire
#include "Bounce2.h"
/* LES CONNECTEURS */
const int pinBPValidationReglage = 4; // BP de validation des réglages sur D4
const int pinSelecteurButee = 5; // switch de sélection de la butée (Direct/devie) en cours de réglage sur D5
const int pinSelecteurChoixMode = 6; // switch de choix mode sur D6
const int pinLedvalRalenti = 7; // led témoin de la valeur du ralenti
const int pinBPvalRalenti = 8; // BP de réglage de la vitesse de déplacement des aiguillages
const int pinBPPointMilieu = 9; // positionne tous les aiguillages à leur point milieu.
// pins D10, D11, D12 réservés pour la gestion des 4 74HC595
const int pinLedTemoin = 13; // led de vérification du bon fonctionnement
const int pinBuzzer = 14; // buzzer sur D14
const int pinBPPlus = 15;
const int pinBPMoins = 16;
const int pinInterruptionClavier = 18; // pour la détection des touches du clavier INT3
const int pinDCC1 = 19; // pour les détections DCC / interruption INT2
//pin 20 et 21 réservés pour interruptions INT1 et INT0
//pins 22 à 37 réservés // les servos sont connectés du pin 22 au pin 37
//pins 38 à 53 réservés // les BP sont connectés du pin 38 au pin 53
/* =============== */
/* POUR LA MISE EN VEILLE */
// réveil par interruption sur D18
#include "LowPower.h"
uint32_t departExecution = 0ul;
uint32_t dureeInactivite = 60000ul; // mise en veille au bout de 60 secondes d'inctivité
//* ===================== */
/* LES VARIABLES POUR LES SERVOS */
const int nbAiguillages = 16;
const int pinDepartServo = 22;
int ServoEnCours = 0;
const int angleMini = 1000; // 544 pris pour 600
const int angleMaxi = 2000; // 2400
const int angleMilieu = (angleMaxi + angleMini) / 2;
int sens[nbAiguillages];
int angleIntermediaire[nbAiguillages];
int angleDirect[nbAiguillages];
int angleDevie[nbAiguillages];
int DernierePosition[nbAiguillages];
bool selectionServo[nbAiguillages];
byte valRalenti = 1; // peux prendre les valeurs de 1 à 5
/* pour gérer les servos */
#include "Servo.h"
Servo servoAiguillage[nbAiguillages];
/* ===================== */
/* pour gérer un écran LCD 2004
* l'adresse de l'écran peut être déterminée à l'aide
* du script "Scanner I2C"
*/
#include "LiquidCrystal_I2C.h" // bibliothèque pour gérer écran LCD 2004
LiquidCrystal_I2C lcd(0x27, 20, 4);
//LiquidCrystal_I2C lcd(0x3F, 20, 4);
/* ============================ */
/* POUR LE CLAVIER NUMERIQUE */
Bounce clavierBP[nbAiguillages] = Bounce();
volatile bool flagClavier = true;
const int pinDepartBP = 38;
int numBoutonPoussoir = 0;
int CompteurLoop = 0; int I = 0;
const int dureeAntiRebond = 50;
bool etatLedRalenti = LOW;
unsigned long precedentMillis = 0;
/* ======================== */
/* LES VARIABLES POUR LES REGLAGES */
bool ButeeEnCours;
int pasReglage = 10; // incrémentation des angles pour les réglages
bool flagPointMilieu = false;
Bounce BPvalRalenti = Bounce();
Bounce BP_Plus = Bounce();
Bounce BP_Moins = Bounce();
Bounce BPValidationReglage = Bounce();
Bounce BPPointMilieu = Bounce();
/* =============================== */
/* LES VARIABLES POUR LE BP DE VALIDATION */
unsigned long debutPressionBP = 0;
unsigned long finPressionBP = 0;
const int limitePressionCourteBP = 2000; // pression longue si + de 2 secondes
/* ================================== *
/* LES DRAPEAUX D'AFFICHAGE */
bool Z = 0; // flag affichage mode COMMANDE
bool Y = 0; // flag affichage mode REGLAGE
bool X = 0; // flag affichage butée droite (angle max)
bool W = 0; // flag affichage butée gauche (angle min))
bool V = 0; // flag desactivation interruptions D2 et D3 en mode REGLAGE
bool U = 0; // flag affichage suite mode REGLAGE
bool T = 0; // flag reglage valeur butées
bool R1; bool R2; // flag affichage direction en cours
/* ======================== */
/* =========== GESTION DES QUATRE 74HC595 EN SERIE ================ */
const int data_Pin = 10; //pin 14 (DS) du 74HC595 (Entrée)
const int verrou_Pin = 11; //pin 12 (ST_CP) du 74HC595 (Horloge de registre de sortie)
const int horloge_Pin = 12; //pin 11 (SH_CP) du 74HC595 (Horloge de registre de décalage)
const int pinDepartLed = 0;
#define Nombre_74hc595 4 // nombre de 74HC595 en série pour 16 leds bicolores
#define numOfRegisterPins Nombre_74hc595 * 8
boolean Registres[numOfRegisterPins];
/* ================================================================= */
void clearRegisters(){
//Place tous les pins du 74HC595 à l'état "OFF"
for(int i = numOfRegisterPins - 1; i >= 0; i--){
Registres[i] = LOW;
} // Fin de for
} // Fin de procédure clearRegisters()
void writeRegisters(){
//Enregistrer et afficher les valeurs dans le registre
//A n'executer que APRES que toutes les valeurs aient été programmées
digitalWrite(verrou_Pin, LOW);
for(int i = numOfRegisterPins - 1; i >= 0; i--){
digitalWrite(horloge_Pin, LOW);
int val = Registres[i];
digitalWrite(data_Pin, val);
digitalWrite(horloge_Pin, HIGH);
} // Fin de for
digitalWrite(verrou_Pin, HIGH);
} // Fin de procédure writeRegisters()
void setRegisterPin(int index, int value){
//Place un pin du 74HC595 à l'état HAUT ou BAS
Registres[index] = value;
} // Fin de procédure setRegisterPin()
/* ========================================================================== */
void setup() {
Serial.begin(9600);
lcd.init();
lcd.backlight();
/* Affichage message accueil pendant l'initialisation */
lcd.clear();
lcd.setCursor(0,0); lcd.print(" Bienvenue dans la ");
lcd.setCursor(0,1); lcd.print(" gestion des ");
lcd.setCursor(0,2); lcd.print("aiguillages 1 a 16.");
lcd.setCursor(0,3); lcd.print(" Initialisation ...");
/* =================================================== */
/* Initialisation des BP avec la bibliothèque Bounce2 */
BPvalRalenti.attach(pinBPvalRalenti, INPUT);
BPvalRalenti.interval(dureeAntiRebond);
BP_Plus.attach(pinBPPlus, INPUT);
BP_Plus.interval(dureeAntiRebond);
BP_Moins.attach(pinBPMoins, INPUT);
BP_Moins.interval(dureeAntiRebond);
BPValidationReglage.attach(pinBPValidationReglage, INPUT);
BPValidationReglage.interval(dureeAntiRebond);
BPPointMilieu.attach(pinBPPointMilieu, INPUT);
BPPointMilieu.interval(dureeAntiRebond);
/* ================================================= */
/* Initialisation des pins E/S */
pinMode(pinSelecteurButee, INPUT);
pinMode(pinSelecteurChoixMode, INPUT);
pinMode(pinLedvalRalenti, OUTPUT); digitalWrite(pinLedvalRalenti, LOW);
pinMode(pinLedTemoin, OUTPUT); digitalWrite(pinLedTemoin, HIGH);
pinMode(pinBuzzer, OUTPUT);
pinMode(pinDCC1, INPUT);
/* ========================== */
/* Initialisation des quatre 74HC595 pour la gestion des leds du TCO */
pinMode(data_Pin, OUTPUT);
pinMode(verrou_Pin, OUTPUT);
pinMode(horloge_Pin, OUTPUT);
//Reset tous les pins du 74HC595
clearRegisters();
/* Initialisation des pins servo et clavier
* Initialisation des BP du clavier digital avec la bibliothèque Bounce2
* Lecture en EEprom des données de chaque servo
* Positionnements des servos
* Allumage des leds correspondantes
*/
delay(2500);
lcd.clear();
for (int J = 0; J < nbAiguillages; J++){
pinMode(pinDepartServo + J, OUTPUT); // pour les servos à partir de 22
pinMode(pinDepartBP + J, INPUT); // pour le clavier à partir de 38
clavierBP[J].attach(pinDepartBP + J, INPUT); // pour Bounce2 du clavier
clavierBP[J].interval(dureeAntiRebond);
lectureEEProm(J);
servoAiguillage[J].writeMicroseconds(DernierePosition[J]);
if (!servoAiguillage[J].attached()) servoAiguillage[J].attach(pinDepartServo + J);
delay(50);
servoAiguillage[J].writeMicroseconds(DernierePosition[J]);
delay(400);
selectionServo[J] = false;
if (DernierePosition[J] == angleDirect[J]){
setRegisterPin((J * 2), HIGH);
setRegisterPin((J * 2) + 1, LOW);
} else {
setRegisterPin((J * 2) + 1, HIGH);
setRegisterPin((J * 2), LOW);
} // Fin de if (DernierePosition[J] == angleDirect[J])
} // Fin de for (int J = 0; J < nbAiguillages; J++)
writeRegisters();
/* Message de fin d'initialisation */
lcd.setCursor(0,0); lcd.print(" Gestion des ");
lcd.setCursor(0,1); lcd.print(" aiguillages 1 a 16.");
lcd.setCursor(0,2); lcd.print(" Ralenti regle a "); lcd.print(valRalenti); lcd.print(" ");
lcd.setCursor(0,3); lcd.print(" P R E T ! ! ");
/* =============================== */
/* visualisation de la valeur de valRalenti */
for (byte J = 0; J < valRalenti; J += 1){
digitalWrite(pinLedvalRalenti, HIGH);
delay(200);
digitalWrite(pinLedvalRalenti, LOW);
delay(300);
} // Fin de for (byte J = 0; J < valRalenti; J += 1)
/* ======================================== */
/* on détache les servos */
for (int J = 0; J < nbAiguillages; J++){
if (servoAiguillage[J].attached()) servoAiguillage[J].detach();
}
delay(2000);
/* ===================== */
/* on démarre la tempo de mise en veille */
departExecution = millis();
} // Fin de setup
void loop() {
if ((millis() - departExecution) >= dureeInactivite){
digitalWrite(pinLedTemoin, LOW);
lcd.setBacklight(LOW); //lcd.noDisplay();
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
lcd.setBacklight(HIGH); //lcd.display();
digitalWrite(pinLedTemoin, HIGH);
}
BPvalRalenti.update();
clavierBP[CompteurLoop].update();
CompteurLoop++; if (CompteurLoop == nbAiguillages) CompteurLoop = 0;
if (flagClavier) Clavier(); // détection par interruption sur D2
if (digitalRead(pinSelecteurChoixMode)== LOW) {
//**********************************************
// Sélecteur choix MODE à gauche => mode REGLAGE
//**********************************************
BPPointMilieu.update();
PointMilieu();
if (Y == 0){
Y = 1;
departExecution = millis();
dureeInactivite = 3600000ul;
initMessagesModeReglage();
} // fin de if (Y == 0)
// si un bouton poussoir valide a été appuyé
if ((numBoutonPoussoir > 0) && (numBoutonPoussoir < nbAiguillages + 1)){
//Serial.print(BP_Plus.read());Serial.print(F(" - "));Serial.println(BP_Moins.read());
if (V == 0) {
// on exécute ceci une seule fois
V = 1;
// on désactive le clavier...la réactivation se fera par la validation du réglage
detachInterrupt(digitalPinToInterrupt(2));
// on positionne le servo en cours à son point milieu pour un éventuel réglage mécanique
angleIntermediaire[ServoEnCours] = (angleMaxi + angleMini) / 2;
servoAiguillage[ServoEnCours].writeMicroseconds(angleIntermediaire[ServoEnCours]);
//Serial.print(F("Servo : "));Serial.print(ServoEnCours);Serial.print(F(" => "));Serial.println(angleIntermediaire[ServoEnCours]);
} // Fin de if (V == 0)
do {
choixButee();
BP_Plus.update();
BP_Moins.update();
BPValidationReglage.update();
if (BP_Plus.changed()){
if (BP_Plus.read() == HIGH){
angleIntermediaire[ServoEnCours] += pasReglage;
servoAiguillage[ServoEnCours].writeMicroseconds(angleIntermediaire[ServoEnCours]);
//Serial.println(angleIntermediaire[ServoEnCours]);
lcd.setCursor(4,3); lcd.print("Valeur : ");
lcd.setCursor(12,3);lcd.print(angleIntermediaire[ServoEnCours]);
}
}
if (BP_Moins.changed()){
if (BP_Moins.read() == HIGH){
angleIntermediaire[ServoEnCours] -= pasReglage;
servoAiguillage[ServoEnCours].writeMicroseconds(angleIntermediaire[ServoEnCours]);
//Serial.println(angleIntermediaire[ServoEnCours]);
lcd.setCursor(4,3); lcd.print("Valeur : ");
lcd.setCursor(12,3);lcd.print(angleIntermediaire[ServoEnCours]);
}
}
} while(BPValidationReglage.read() == 1); // Fin de while
validationReglage(ServoEnCours, ButeeEnCours, angleIntermediaire[ServoEnCours]);
} // Fin de if ((numPoussoir > 0) && (numPoussoir < nbAiguillages + 1))
} else { // else de if (digitalRead(pinSelecteurChoixMode) == LOW)
//***********************************************
// Sélecteur choix MODE à droite => mode COMMANDE
//***********************************************
// on active le réglage du ralentissement de déplacement des aiguillages
reglageRalenti();
if (Z == 0){
Z = 1;
departExecution = millis();
dureeInactivite = 600000ul;
initMessagesModeCommande();
} // fin de if (Z == 0)
if (selectionServo[CompteurLoop] == true) {
//Serial.print(F("Aiguillage : ")); Serial.print(CompteurLoop + 1); Serial.println(F(" actif "));
if (DernierePosition[CompteurLoop] == angleDirect[CompteurLoop]){
if(R1 == 0){
R1 = 1;
lcd.clear();
lcd.setCursor(0,0);lcd.print("Aiguillage ");
lcd.setCursor(13,0);lcd.print(CompteurLoop + 1);
lcd.setCursor(0,1);lcd.print(" vers devie ... ");
}
DirectToDevie(CompteurLoop);
} else {
if(R2 == 0){
R2 = 1;
lcd.clear();
lcd.setCursor(0,0);lcd.print("Aiguillage ");
lcd.setCursor(13,0);lcd.print(CompteurLoop + 1);
lcd.setCursor(0,1);lcd.print(" vers direct ... ");
}
DevieToDirect(CompteurLoop);
} // Fin de if (DernierePosition[CompteurLoop] == angleDirect[CompteurLoop])
} // Fin de if (selection[CompteurLoop] == true)
} // fin de if (digitalRead(pinBPMode) == LOW)
} // Fin de loop
void detectInterruptClavier(){
// ISR appelé par interruption sur D18
departExecution = millis();
flagClavier = true;
} // Fin de procédure detectInterruptClavier()
void Clavier(){
// Déclanchement par interruption sur D18
//Serial.println(F("Clavier OK"));
// on boucle sur les BP pour lire leur état
for (int J = 0; J < nbAiguillages; J++){
if (clavierBP[J].changed()) {
if (clavierBP[J].read() == HIGH) {
numBoutonPoussoir = J + 1;
ServoEnCours = J;
selectionServo[J] = true;
// On attache le servomoteur correspondant s'il n'est pas déjà attaché
if (!servoAiguillage[J].attached()) servoAiguillage[J].attach(pinDepartServo + J);
//Serial.print(F("Aiguillage "));Serial.print(ServoEnCours + 1); Serial.println(F(" attache!"));
// On sort de la boucle au premier BP sélectionné
flagClavier = false;
break;
} // Fin de if (clavierPB[J].read() == HIGH)
} // Fin de if (clavierPB[J].changed())
} // For for (int J = 0; J < nbAiguillages; J++)
} // Fin de procédure Clavier()
int lectureEEProm(int I){
/*
* byte 200 => valRalenti
* byte 10-11 => angleDirect
* byte 12-13 => angleDevie
* byte 14-15 => DernierPosition
*/
if (I == 0) {
valRalenti = EEPROM.read(200);
if ((valRalenti < 1) || (valRalenti > 5)) {
valRalenti = 1;
EEPROM.update(200, valRalenti);
} // Fin de if ((valRalenti < 1) || (valRalenti > 5))
} // Fin de if (I == 0)
angleDirect[I] = EEPROM.read(I * 10) | ((int)EEPROM.read((I * 10) + 1)) << 8; // lecture des 2 ints pour int angleDirect[]
if (angleDirect[I] > angleMaxi || angleDirect[I] < angleMini){ // si incohérence de valeur ou initialisation (=255)
angleDirect[I] = angleMini; // on enregistre la limite pour angleMin
EEPROM.update((I * 10), angleDirect[I] & 0xFF); // écrit le premier int de la valeur int
EEPROM.update((I * 10) + 1, angleDirect[I] >> 8); // écrit le second int de la valeur int
} // fin de if (angleDirect[I] > angleMaxi || angleDirect[I] < angleMini)
angleDevie[I] = EEPROM.read((I * 10) + 2) | ((int)EEPROM.read((I * 10) + 3)) << 8; // lecture des 2 ints pour int angleMax[]
if (angleDevie[I] > angleMaxi || angleDevie[I] < angleMini){ // si incohérence de valeur ou initialisation (=255)
angleDevie[I] = angleMaxi; // on enregistre la limite pour angleMax
EEPROM.update((I * 10) + 2, angleDevie[I] & 0xFF); // écrit le premier int de la valeur int
EEPROM.update((I * 10) + 3, angleDevie[I] >> 8); // écrit le second int de la valeur int
} // Fin de if (angleDevie[I] > angleMaxi || angleDevie[I] < angleMini)
DernierePosition[I] = EEPROM.read((I * 10) + 4) | ((int)EEPROM.read((I * 10) + 5)) << 8;
if (DernierePosition[I] != angleDevie[I] && DernierePosition[I] != angleDirect[I]){
DernierePosition[I] = (angleDirect[I] + angleDevie[I]) / 2; // si incohérence de valeur on se met au point milieu
EEPROM.update((I * 10) + 4, DernierePosition[I] & 0xFF); // écrit le premier int de la valeur int
EEPROM.update((I * 10) + 5, DernierePosition[I] >> 8); // écrit le second int de la valeur int
} // Fin de if (DernierePosition[I] < limitAngleMin || servoAiguillage[I].DernierePositionServo > limitAngleMax)
//Serial.print(F("Aiguillage "));Serial.print(I+1);
//Serial.print(F(" : "));Serial.print(angleDirect[I]);
//Serial.print(F(" - "));Serial.print(angleDevie[I]);
//Serial.print(F(" position ")); Serial.println(DernierePosition[I]);
lcd.setCursor(2,0); lcd.print("Aiguillage : ");lcd.setCursor(16,0); lcd.print(I + 1);
lcd.setCursor(0,1); lcd.print("Angle direct : ");lcd.setCursor(16,1);lcd.print(angleDirect[I]);
lcd.setCursor(0,2); lcd.print("Angle devie : ");lcd.setCursor(16,2);lcd.print(angleDevie[I]);
angleIntermediaire[I] = DernierePosition[I];
sens[I] = 1;
} // Fin de procédure lectureEEProm()
void initMessagesModeReglage(){
digitalWrite(pinLedvalRalenti, LOW);
tone(pinBuzzer,2000,300);
// activation du clavier => detection interruptions D2
attachInterrupt(digitalPinToInterrupt(pinInterruptionClavier), detectInterruptClavier, RISING);
//Serial.println(F("MODE REGLAGE : Pret!"));
//Serial.println(F("Selectionnez l'aiguillage a regler"));
//Serial.println(F("en appuyant sur le poussoir correspondant."));
lcd.clear(); lcd.setCursor(0,0);
lcd.print("MODE REGLAGE:Pret!");
lcd.setCursor(0,1);
lcd.print("Selection aiguillage");
lcd.setCursor(0,2);
lcd.print("en appuyant le pous-");
lcd.setCursor(0,3);
lcd.print("-soir correspondant.");
/* visualisation de la valeur de valRalenti */
for (byte J = 0; J < valRalenti; J += 1){
digitalWrite(pinLedvalRalenti, HIGH);
delay(200);
digitalWrite(pinLedvalRalenti, LOW);
delay(300);
} // Fin de for (byte J = 0; J < valRalenti; J += 1)
Z = 0; // RAZ flag affichage choix COMMANDE
numBoutonPoussoir = 0; ServoEnCours = 0;
} // Fin de procedure initReglage()
void choixButee(){
// ButeeEnCours = LOW => bouton à gauche => butée angleDirect
// ButeeEnCours = HIGH => bouton à droite => butée angleDevie
ButeeEnCours = digitalRead(pinSelecteurButee);
if (ButeeEnCours == HIGH){
if (W == 0){
W = 1;
U = 0;
//Serial.print(F("Angle direct aiguillage ")); Serial.print(numBoutonPoussoir);Serial.println(F(" en cours de reglage!"));
lcd.clear();
lcd.setCursor(4,0); lcd.print("Angle direct");
lcd.setCursor(4,1); lcd.print("aiguillage "); lcd.print(numBoutonPoussoir);
lcd.setCursor(0,2); lcd.print("en cours de reglage!");
} // Fin de if (W == 0)
} else {
if (U == 0){
U = 1;
W = 0;
//Serial.print(F("Angle devie aiguillage ")); Serial.print(numBoutonPoussoir);Serial.println(F(" en cours de reglage!"));
lcd.clear();
lcd.setCursor(4,0); lcd.print("Angle devie");
lcd.setCursor(4,1); lcd.print("aiguillage "); lcd.print(numBoutonPoussoir);
lcd.setCursor(0,2); lcd.print("en cours de reglage!");
} // Fin de if (U == 0)
} // Fin de if (ButeeEnCours == LOW)
}// Fin de procédure choixButee()
void validationReglage(int numServo, bool valButee, int valReglage) {
if (digitalRead(pinBPValidationReglage) == 1 && debutPressionBP == 0) {
debutPressionBP = millis();
}
if (digitalRead(pinBPValidationReglage) == 0 && debutPressionBP != 0) {
finPressionBP = millis();
if((finPressionBP - debutPressionBP) > 0) {
if((finPressionBP - debutPressionBP) < limitePressionCourteBP) {
//pression courte => validation
if (servoAiguillage[ServoEnCours].attached()) servoAiguillage[ServoEnCours].detach();
if (valButee == HIGH) {
//Serial.print(F(" Angle direct pour aguillage "));
//Serial.println(numServo + 1);
//Serial.print(F(" enregistre a "));
//Serial.println(valReglage);
lcd.clear();
lcd.setCursor(0,0); lcd.print(" Angle direct pour ");
lcd.setCursor(0,1); lcd.print(" aiguillage ");lcd.print(numServo + 1);
lcd.setCursor(0,2); lcd.print(" enregistre a ");lcd.print(valReglage);
angleDirect[numServo] = valReglage;
EEPROM.update((numServo * 10), angleDirect[numServo] & 0xFF);
EEPROM.update((numServo * 10) + 1, angleDirect[numServo] >> 8);
} else {
//Serial.print(F(" Angle devie pour aguillage "));
//Serial.println(numServo + 1);
//Serial.print(F(" enregistre a "));
//Serial.println(valReglage);
lcd.clear();
lcd.setCursor(0,0);lcd.print(" Angle devie pour");
lcd.setCursor(0,1);lcd.print(" aiguillage ");lcd.print(numServo + 1);
lcd.setCursor(0,2);lcd.print(" enregistre a ");lcd.print(valReglage);
angleDevie[numServo] = valReglage;
EEPROM.update((numServo * 10) + 2, angleDevie[numServo] & 0xFF);
EEPROM.update((numServo * 10) + 3, angleDevie[numServo] >> 8);
} // Fin de if (valButee == 0)
angleIntermediaire[numServo] = valReglage;
DernierePosition[numServo] = valReglage;
EEPROM.update((numServo * 10) + 4, DernierePosition[numServo] & 0xFF);
EEPROM.update((numServo * 10) + 5, DernierePosition[numServo] >> 8);
delay(400);
tone(pinBuzzer,2500,100); delay(100);tone(pinBuzzer,2000,1000);
// nouveau reglage
lcd.setCursor(0,3);lcd.print(" Nouveau reglage ");
attachInterrupt(digitalPinToInterrupt(pinInterruptionClavier), detectInterruptClavier, RISING);
selectionServo[numServo] = false; numBoutonPoussoir = 0; ServoEnCours = 0; debutPressionBP = 0; finPressionBP = 0;
Z = 0; Y = 0; X = 0; W = 0; V = 0; U = 0; T = 0;
} else {
//pression longue => annulation et on recommence
tone(pinBuzzer,2000,1000); delay(100);tone(pinBuzzer,3500,50); tone(pinBuzzer,3500,50);
//Serial.println(F("Operation annulee"));
lcd.clear();
lcd.setCursor(0,1);lcd.print(" O P E R A T I O N ");
lcd.setCursor(0,2);lcd.print(" A N N U L E E ! ! ");
for (int buz = 0; buz < 4; buz++){
tone(pinBuzzer,3000,50); delay(50);
} // Fin de for
servoAiguillage[numServo].writeMicroseconds(DernierePosition[numServo]);
delay(2500);
if (servoAiguillage[numServo].attached()) servoAiguillage[numServo].detach(); // on "débranche" le servo
delay(50);
attachInterrupt(digitalPinToInterrupt(pinInterruptionClavier), detectInterruptClavier, RISING);
selectionServo[numServo] = false; numBoutonPoussoir = 0; ServoEnCours = 0; debutPressionBP = 0; finPressionBP = 0;
Z = 0; Y = 0; X = 0; W = 0; V = 0; U = 0; T = 0;
} // Fin de if((finPressionBP - debutPressionBP) < limitePressionBP
} // Fin de if((finPressionBP - debutPressionBP) > 0)
} // Fin de if (digitalRead(pinBPValidationReglage) == 1 && debutPressionBP != 0)
} // Fin de procédure validationReglage(int numServo, bool valButee, int valReglage)
void initMessagesModeCommande(){
// activation du clavier => detection interruptions D2
attachInterrupt(digitalPinToInterrupt(pinInterruptionClavier), detectInterruptClavier, RISING);
tone(pinBuzzer,2500,100);
//Serial.println(F("MODE COMMANDE : Pret!"));
//Serial.println(F("Selectionnez l'aiguillage a commander"));
//Serial.println(F("en appuyant sur le poussoir correspondant."));
lcd.clear(); lcd.setCursor(0,0);
lcd.print("MODE COMMANDE:Pret!");
lcd.setCursor(0,1);
lcd.print("Selection aiguillage");
lcd.setCursor(0,2);
lcd.print("en appuyant le pous-");
lcd.setCursor(0,3);
lcd.print("-soir correspondant.");
Y = 0; // RAZ flag affichage choix REGLAGE
W = 0;
U = 0;
T = 0;
CompteurLoop = 0;
numBoutonPoussoir = 0;
ServoEnCours = 0;
} // Fin de procédure initCommande()
void DirectToDevie(int numServoEnCours)
{
if (angleDirect[numServoEnCours] > angleDevie[numServoEnCours])
{
sens[numServoEnCours] = -1;
} else {
sens[numServoEnCours] = 1;
}
angleIntermediaire[numServoEnCours] += sens[numServoEnCours];
servoAiguillage[numServoEnCours].writeMicroseconds(angleIntermediaire[numServoEnCours]);
delay(valRalenti * 2);
//Serial.println(servoAiguillage[numServoEnCours].read());
//if(abs(angleDevie[numServoEnCours] - angleIntermediaire[numServoEnCours]) < 0){
if (angleIntermediaire[numServoEnCours] == angleDevie[numServoEnCours]){
selectionServo[numServoEnCours] = false; // on annule la sélection du servo
if (servoAiguillage[numServoEnCours].attached()) servoAiguillage[numServoEnCours].detach(); // on "débranche" le servo
DernierePosition[numServoEnCours] = angleDevie[numServoEnCours];
/* allumage des leds correspondantes */
setRegisterPin((numServoEnCours * 2), LOW);
setRegisterPin((numServoEnCours * 2) + 1, HIGH);
writeRegisters();
/* ==================================*/
/* messages */
//Serial.print(F("Aiguillage "));Serial.print(numServoEnCours + 1);Serial.println(F(" devie. Detache! "));
//lcd.clear();
//lcd.setCursor(0,0);lcd.print("Aiguillage ");
//lcd.setCursor(13,0);lcd.print(numServoEnCours + 1);
R1 = 0;
lcd.setCursor(0,1);lcd.print(" D E V I E ! ! ");
lcd.setCursor(0,2);lcd.print("Autre choix avec le");
lcd.setCursor(1,3);lcd.print("BP correspondant.");
/* ======== */
/* mise em mémoire de la dernière position */
EEPROM.update((numServoEnCours * 10) + 4, DernierePosition[numServoEnCours] & 0xFF);
EEPROM.update((numServoEnCours * 10) + 5, DernierePosition[numServoEnCours] >> 8);
/* ======================================= */
} // Fin de if (angleIntermediaire[numServoEnCours] == angleDevie[numServoEnCours])
} // Fin de procédure DirectToDevie
void DevieToDirect(int numServoEnCours) {
if (angleDevie[numServoEnCours] > angleDirect[numServoEnCours])
{
sens[numServoEnCours] = -1;
} else {
sens[numServoEnCours] = 1;
}
angleIntermediaire[numServoEnCours] += sens[numServoEnCours];
servoAiguillage[numServoEnCours].writeMicroseconds(angleIntermediaire[numServoEnCours]);
delay(valRalenti * 2);
//Serial.println(servoAiguillage[numServoEnCours].read());
if (angleIntermediaire[numServoEnCours] == angleDirect[numServoEnCours]){
selectionServo[numServoEnCours] = false; // on annule la sélection du servo
if (servoAiguillage[numServoEnCours].attached()) servoAiguillage[numServoEnCours].detach(); // on "débranche" le servo
DernierePosition[numServoEnCours] = angleDirect[numServoEnCours];
/* allumage des leds correspondantes */
setRegisterPin((numServoEnCours * 2), HIGH);
setRegisterPin((numServoEnCours * 2) + 1, LOW);
writeRegisters();
/* ================================= */
/* messages */
//Serial.print(F("Aiguillage "));Serial.print(numServoEnCours + 1);Serial.println(F(" direct. Detache! "));
//lcd.clear();
//lcd.setCursor(0,0);lcd.print("Aiguillage ");
//lcd.setCursor(13,0);lcd.print(numServoEnCours + 1);
R2 = 0;
lcd.setCursor(0,1);lcd.print(" D I R E C T ! ! ");
lcd.setCursor(0,2);lcd.print("Autre choix avec le");
lcd.setCursor(1,3);lcd.print("BP correspondant.");
/* ======== */
/* mise em mémoire de la dernière position */
EEPROM.update((numServoEnCours * 10) + 4, DernierePosition[numServoEnCours] & 0xFF);
EEPROM.update((numServoEnCours * 10) + 5, DernierePosition[numServoEnCours] >> 8);
/* ======================================= */
} // Fin de if (angleIntermediaire[numServoEnCours] == angleDirect[numServoEnCours])
} // Fin de procédure DevieToDirect
void reglageRalenti(){
if (BPvalRalenti.changed()) {
//if ((BPvalRalenti.read() == HIGH) && (BPPointMilieu.read() == LOW)) {
if (BPvalRalenti.read() == HIGH) {
valRalenti += 1; if(valRalenti > 5) valRalenti = 1;
//Serial.print("RALENTI ");
//Serial.print("regle a : ");
//Serial.println(valRalenti);
} else {
EEPROM.update(200, valRalenti);
valRalenti = EEPROM.read(200);
//Serial.print("RALENTI ");
//Serial.print("enregistre a : ");
//Serial.println(valRalenti);
/* visualisation de la valeur de valRalenti */
for (byte J = 0; J < valRalenti; J += 1){
digitalWrite(pinLedvalRalenti, HIGH);
delay(200);
digitalWrite(pinLedvalRalenti, LOW);
delay(300);
} // Fin de for (byte J = 0; J < valRalenti; J += 1)
} // Fin de if (BP_ralenti.read() == HIGH)
} // Fin de if (BP_ralenti.changed())
} // Fin de procédure reglageRalenti
void PointMilieu(){
if (BPPointMilieu.changed() && BPPointMilieu.read() == HIGH) {
if (flagPointMilieu == false){
flagPointMilieu = true;
digitalWrite(pinLedvalRalenti, HIGH);
detachInterrupt(digitalPinToInterrupt(2));
for (int J = 0; J < nbAiguillages; J++){
servoAiguillage[J].writeMicroseconds((angleMaxi + angleMini) / 2);
if (!servoAiguillage[J].attached()) servoAiguillage[J].attach(pinDepartServo + J);
delay(50);
servoAiguillage[J].writeMicroseconds((angleMaxi + angleMini) / 2);
delay(500);
} // Fin de for (int J = 0; J < nbAiguillages; J++)
for (int J = 0; J < nbAiguillages; J++){
if (servoAiguillage[J].attached()) servoAiguillage[J].detach();
delay(50);
} // Fin de for (int J = 0; J < nbAiguillages; J++)
tone(pinBuzzer,5000,500);
//Serial.println(F("MODE POINT MILIEU ACTIF"));
//Serial.println(F("pour un centrage mecanique des aiguillages."));
//Serial.println(F("Desactivation de toutes les commandes!"));
lcd.clear();
lcd.setCursor(2,0); lcd.print("Mode Point Milieu");
lcd.setCursor(5,1); lcd.print("A C T I F !");
lcd.setCursor(0,2); lcd.print("pour un centrage des");
lcd.setCursor(5,3); lcd.print("aiguillages");
do{
BPPointMilieu.update();
unsigned long actuelMillis = millis();
if (actuelMillis - precedentMillis >= 250) {
precedentMillis = actuelMillis;
etatLedRalenti =! etatLedRalenti;
digitalWrite(pinLedvalRalenti, etatLedRalenti);
}
if(BPPointMilieu.changed() && BPPointMilieu.read() == HIGH && flagPointMilieu == true){
flagPointMilieu = false;
digitalWrite(pinLedvalRalenti, HIGH);
for (int J = 0; J < nbAiguillages; J++){
servoAiguillage[J].writeMicroseconds(DernierePosition[J]);
if (!servoAiguillage[J].attached()) servoAiguillage[J].attach(pinDepartServo + J);
delay(50);
servoAiguillage[J].writeMicroseconds(DernierePosition[J]);
delay(400);
} // Fin de for (int J = 0; J < nbAiguillages; J++)
for (int J = 0; J < nbAiguillages; J++){
if (servoAiguillage[J].attached()) servoAiguillage[J].detach();
delay(50);
} // Fin de for (int J = 0; J < nbAiguillages; J++)
tone(pinBuzzer,5000,500);
//Serial.println(F("MODE POINT MILIEU INACTIF"));
digitalWrite(pinLedvalRalenti, LOW);
Y = 0; Z = 0;
break;
}
}
while(1);
} //Fin de if (flagPointMilieu == true)
} // Fin de if (BPPointMilieu.changed() && BPPointMilieu.read() == HIGH)
} // Fin procédure PointMilieu()
Pages vues depuis 15/01/2020 : 408 589