Skip to content

Commit

Permalink
Merge pull request #14 from Julaye/Preconf-Automatismes
Browse files Browse the repository at this point in the history
Preconf automatismes plus passage en version bêta ...
  • Loading branch information
Julaye committed Oct 14, 2023
2 parents 9f542db + 1b8057f commit f81130a
Show file tree
Hide file tree
Showing 10 changed files with 667 additions and 380 deletions.
120 changes: 120 additions & 0 deletions ConfigAutomatismes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// Lumieres::ConfigAutomatismes.h
// Exemple pour le forum 3rails / Julie Dumortier / Licence GPL
//
// Ce fichier concerne la configuration d'automatismes de base selon la
// cartographie suivante (et en cela, on a une sorte de M83 plus puissant !):
//
// 00 : seq1: chenillard (séquences de tests), seq2: anti-rebond (seq1: ExB -> Sx+1 , seq2: ExH -> Sx+1)
// 01 : seq1: paparazzi (E1B -> S2 flash), seq2: néons ateliers + soudure (ExB -> Sx+1)
// 10 : signal SNCB (TBD)
// 11 : automatisme utilisateur (programmé dans ConfigLumieres.h) (mode par défaut)
// ================================================================

// === Prog00x ===
// seq1: chenillard (séquences de tests)
// seq2: filtre anti-rebond (ExB -> Sx , seq2: ExH -> Sx+4)

/* PROG 0 */
DEBUTSEQ(Prog000)
MARK /* Point de retour */
1, 1, _SET,
2, 1, _SET,
4, 1, _SET,
8, 1, _SET,
16, 1, _SET,
32, 1, _SET,
64, 1, _SET,
128, 1, _SET,
0, 1, _WAIT, /* Eteint tout et Attend pendant 1 secondes */
255, 2, _SET, /* Allume tout pendant 2 secondes */
ESTARTH,0,_WSTOP, /* Vérifie que la startPin est toujours à 1 */
LOOP /* Retoune au point de retour */
FINSEQ(Seq1_Prog000)

/* PROG 1 */
DEBUTSEQ(Prog001)
1, E1B, _ATTACH,
2, E2B, _ATTACH,
4, E3B, _ATTACH,
8, E4B, _ATTACH,
16, E1H, _ATTACH,
32, E2H, _ATTACH,
64, E3H, _ATTACH,
128, E4H, _ATTACH,
END /* fin de la séquence */
FINSEQ(Prog001)

// === Prog01x ===
// seq1: néons neufs (S1,S3), paparazzi (E1B -> S2 flash), gyrophare (E2B -> S4 gyrophare), brasero (E3B -> S5), néon vieux (E4B -> S6, S8), soudure (S7)
// seq2: néons neufs (S1,S3), paparazzi (E1B -> S2 flash), gyrophare (E2B -> S4 gyrophare), brasero (S5), néon vieux(E4H -> S6, S8), soudure (E3B -> S7)

/* PROG 2 */
DEBUTSEQ(Prog010)
SETMODE(S1+S3,ETYPE_NEONNEUF)
SETMODE(S2,ETYPE_FLASH)
SETMODE(S4,ETYPE_GYROPHARE)
SETMODE(S5,ETYPE_FIRE)
SETMODE(S6+S8,ETYPE_NEONVIEUX)
SETMODE(S7,ETYPE_SOUDURE)
PERM(S1)
PERM(S3)
ATTACH(S4,E2B)
ATTACH(S5,E3B)
ATTACH(S6,E4B)
PERM(S8)
PERM(S7)
MARK /* Point de retour */
WSTOP(E1B,1) /* Attend que l'entrée E1 passe à 0, échantillonage à la seconde */
ALEA(S2,4) /* lance le flash configuré sur la sortie S2 aléatoirement (0..3) */
LOOP /* Retoune au point de retour */
FINSEQ(Prog010)

/* PROG 3 */
DEBUTSEQ(Prog011)
SETMODE(S1+S3,ETYPE_NEONNEUF)
SETMODE(S2,ETYPE_FLASH)
SETMODE(S4,ETYPE_GYROPHARE)
SETMODE(S5,ETYPE_FIRE)
SETMODE(S6+S8,ETYPE_NEONVIEUX)
SETMODE(S7,ETYPE_SOUDURE)
PERM(S1)
PERM(S3)
ATTACH(S4,E2B)
PERM(S5)
ATTACH(S6,E4H)
PERM(S8)
ATTACH(S7,E3B)
MARK /* Point de retour */
WSTOP(E1B,2) /* Attend que l'entrée E1 passe à 0 pendant 2 secondes */
ALEA(S2,4) /* lance le flash configuré sur la sortie S2 aléatoirement (0..3) */
LOOP /* Retoune au point de retour */
FINSEQ(Prog011)

// === Prog10x ===
// seq1: signal SNCB (TBD) +
// seq2: Passage à niveau (E1/E2 -> servo S6/S7 + clignotement S8)

/* PROG 4 */
DEBUTSEQ(Prog100)
MARK /* Point de retour */
LOOP /* Retoune au point de retour */
FINSEQ(Prog100)

/* PROG 5 */
DEBUTSEQ(Prog101)
SETMODE(S6,ETYPE_SERVO) /* S6 (32) ou SM1 : servo moteur de la barrière (PWM) */
SETMODE(S7,ETYPE_SERVO) /* S7 (64) ou SM2 : servo moteur de la barrière (PWM) */
SETMODE(S8,ETYPE_CLIGNOTANT) /* S8 (128) : feu clignotant (PWM) */
MARK /* Point de retour */
WSTOP(E1B,1) /* attend que E1 passe à 0 -> détection convoi en amont */
SET(S8,1) /* lance le feu clignotant */
PERM(S6) /* ferme la barrière 1 */
PERM(S7) /* ferme la barrière 2 */
WSTOP(E2B,1) /* attend que E2 passe à 0 -> détection convoi proche du PN */
PERM(S8) /* clignotant devient fixe */
WSTOP(E2H,1) /* attend que E2 repasse à 1 -> convoi est passé */
UNSET(S8) /* eteint le feu clignotant */
UNSET(S7) /* ouvre la barrière 2 */
UNSET(S6) /* ouvre la barrière 1 */
LOOP /* Retoune au point de retour */
FINSEQ(Prog101)
130 changes: 57 additions & 73 deletions ConfigLumieres.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,89 +13,73 @@
//
// Plus d'exemples dans la documention, notamment pour les fonctions les
// avancées comme le poste de soudure, le flash du photographe, ...
//
// =====================================================================

// === Ce fichier est à adapter en fonction de vos automatismes ========

// ---------------------------------------------------------------------
// --- ICI COMMENCE LA CONFIGURATION EN FONCTION DE VOTRE SCENE ---

// Affectation des types d'éclairage ou de fonctions à chaque sortie
const byte ledCnf[] = {
/* D2 */ ETYPE_NEONNEUF, /* S1 (1) : bureau administratif (IO) *
/* D3 */ ETYPE_SOUDURE, /* S2 (2) : accueil (PWM) */
/* D4 */ ETYPE_STANDARD, /* S3 (4) : bureau M. CLaude (IO) */
/* D5 */ ETYPE_GYROPHARE, /* S4 (8) : couloir haut (PWM) */
/* D6 */ ETYPE_FIRE, /* S5 (16) : escalier (PWM) */
/* D7 */ ETYPE_NEONNEUF, /* S6 (32) : couloir bas (IO) */
/* D8 */ ETYPE_NEONNEUF, /* S7 (64) : bureau M. Gaston (IO) */
/* D9 */ ETYPE_NEONVIEUX, /* S8 (128) ou SM1 : bureau secrétaire (PWM) */
/* D10 */ ETYPE_STANDARD, /* S9 (256) ou SM2 : bureau Mlle Pélerin (PWM) */
/* D11 */ ETYPE_GYROPHARE /* S10 (512) : gyrophare (PWM) */
};
// Prog 6 : Lumières d'une fosse d'inspection
// En voici les spécifications :
// 1. fosse normalement éteinte sauf si forçage par entrée digital (M83 - bouton vert - au commun==GND)
// 2. une locomotive passe sans s’arrêter, la fosse reste éteinte sauf si le forçage est en cours
// 3. une locomotive stationne, au bout d’un temps programmable, la fosse s’allume
// 4. la fosse allumée s’éteint au bout d’un certain temps programmable, économie d’énergie oblige
// 5. une locomotive repart, la fosse allumée s’éteint au bout d’un temps programmable
// 6. entrée digital pour un forçage éteint même si des locomotives stationnent (M83 - bouton rouge - au commun==GND)

// Pour la commande d'un servo moteur sur la sortie D9 ou D10 uniquement
// LIGNE CI-APRÈS À METTRE EN COMMENTAIRE SI VOUS N'UTILISEZ AUCUN SERVO
//#include <Servo.h>
DEBUTSEQ(myProg_Seq1)
SETMODE(S2,ETYPE_STANDARD) /* relai pour allumer les lampes */

ATTACH(E2B,S2) /* force l'allumage sur un lien */
ATTACH(E3B,S2) /* force l'extinction sur un autre lien */

// Séquence est une liste de couple (sorties, durée d'allumage en secondes, commande)
// Cf le fichier FSMLumieres.h pour la signification de chaque commande utilisée
0,5,_MARK,
WSTOP(E1B,10) /* loco avérée pendant 10 secondes */
UNTIL(S2,4) /* allume S2 pendant 4 minutes */
WSTOP(E1H,10) /* loco s'en va, attend 10 secondes */
UNSET(S2) /* au cas où S2 soit encore allumé */
LOOP
FINSEQ(mySeq1)

// Je peux me définir des symboles pour faciliter la lecture de mon automatisme
#define Administratif S1
#define Accueil S2
#define Claude S3
#define CouloirEtage S4
#define Escalier S5
#define CouloirRDC S6
#define Gaston S7
#define Secretaire S8
#define LaMiss S9
#define Incendie S10
// Prog 7 : Automatismes d'un atelier

/* Séquence 1 : Miss Pélerin passe (avec ou sans M. Gaston) */
DEBUTSEQ(mySeq1)
ATTACH(Incendie,E1B) /* déclenche le gyrophare si l'entrée 1 passe à l'état bas */
SET(Accueil,10) /* allume l'accueil (néon neuf) pendant 10 secondes */
SET(Accueil+CouloirRDC,10) /* laisse l'accueil allumé et allume le couloir RDC (néon neuf) pendant 10 secondes */
SET(Escalier+CouloirRDC,10) /* éteint l'accueil et allume le couloir RDC (néon neuf) et l'escalier (néon ancien) pendant 10 secondes */
SET(Escalier+CouloirEtage,10) /* ETC :) */
SET(CouloirEtage+LaMiss,10)
ALEA(Gaston,2) /* parfois M. gaston accompagne la miss (50% de chance) */
ALEA(Secretaire,2) /* parfois la secrétaire accompagne la miss (50% chance) */
STANDBY(LaMiss,10) /* la miss reste dans son bureau un certain temps (1 à 10 minutes) */
SET(CouloirEtage+LaMiss,2)
SET(CouloirEtage,10)
SET(CouloirEtage+Escalier,10)
SET(Escalier+CouloirRDC,10)
SET(CouloirRDC+Accueil,10)
SET(Accueil,10) /* éteint le couloir du RDC, allume l'accueil pendant 10 secondes */
END /* fin de la séquence, tout est éteint */
FINSEQ(mySeq1)
DEBUTSEQ(myProg_Seq2)
SETMODE(S1,ETYPE_NEONNEUF) /* S1 : lampe de l’atelier (IO) */
SETMODE(S2,ETYPE_NEONNEUF) /* S2 : néon de l’atelier (PWM) */

SETMODE(S4,ETYPE_SOUDURE) /* S4 : poste de soudure de l’atelier (PWM) */

SETMODE(S6,ETYPE_BUZZER) /* S6 : buzzer du poste de soudure (PWM) */
SETMODE(S7,ETYPE_SERVO) /* S7 : servomoteur de la porte (PWM) */
SETMODE(S8,ETYPE_GYROPHARE) /* S8 : gyrophare de la porte (PWM) */

PERM(S1+S2) /* l’atelier se met au travail au démarrage de l’Arduino … */

0,5,_MARK, /* point de retour de l’automatisme (et timeout à 5 minutes) */
WSTOP(E1orE2B,1) /* attend la détection d’une locomotive sur la voie 1 ou voie 2 */
UNTIL(S8,2) /* lance le gyrophare configuré sur la sortie D11 pour deux minutes */
WAIT(5) /* attend 5 secondes */
UNTIL(S7,2) /* envoie 90° sur la sortie D10 du servomoteur pour deux minutes */
WSTOP(E1andE2H,1) /* attend la non détection de la locomotive sur la voie 1 ou voie 2 */
UNSET(S7) /* envoie 0° sur la sortie D10 du servomoteur */
WAIT(5) /* attend 5 secondes */
UNSET(S8) /* arrête le gyrophare configuré sur la sortie D11 */

WSTOP(E2B,1) /* attend la détection d’une locomotive sur la voie 2 */

/* Séquence 2 : le dépot fonctionne de nuit */
DEBUTSEQ(mySeq2)
ATTACH(Incendie,E1B) /* déclenche le gyrophare si l'entrée 1 passe à l'état bas */
SET(Accueil,10)
PERM(Accueil)
SET(CouloirRDC,10)
SET(CouloirRDC+Administratif,2)
SET(Administratif,2)
PERM(Administratif)
SET(Escalier,10)
SET(Escalier+CouloirEtage,10)
PERM(Secretaire)
ALEA(LaMiss,4) /* La Miss n'est pas toujours présente la nuit ! */
ALEA(Gaston,2)
ALEA(Claude,2)
WSTOP(ESTARTB,3)
UNSET(LaMiss+Secretaire+Gaston+Claude) /* éteint les bureaux de l'étage */
SET(Escalier,10)
UNSET(CouloirEtage+Administratif) /* eteint couloir haut et administratif */
WAIT(10)
UNSET(CouloirRDC) /* éteint couloir bas */
WAIT(10)
UNSET(Accueil) /* éteint accueil */
END /* fin de la séquence */
0,5,_MARK, /* point de retour de l’automatisme (et timeout à 5 minutes) */
WAIT(5) /* 5 secondes */
SET(S4+S6,15) /* un peu de soudure sur la locomotive qui vient de rentrer pendant 15 secondes */
UNTIL(S7,2) /* envoie 90° sur la sortie D10 du servomoteur pour deux minutes */

WSTOP(E2H,1) /* attend la non détection de la locomotive sur la voie 2 */
UNSET(S4+S6) /* arrête le poste soudure, la loco est partie ! */
UNSET(S7) /* envoie 0° sur la sortie D10 du servomoteur */
WAIT(5) /* 5 secondes */

RESET /* boucle attendre la locomotive suivante */
FINSEQ(mySeq2)

// --- ICI SE TERMINE LA CONFIGURATION EN FONCTION DE VOTRE SCENE ---
Expand Down
49 changes: 36 additions & 13 deletions ConfigNano.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,39 +26,62 @@ const byte LIGHT_FAD4 = PWM_FOR_LED/4;
const byte LIGHT_FAD8 = PWM_FOR_LED/8;
const byte LIGHT_OFF = 0;

// Configuration du mode de chaque sortie (Arduino Nano)
const byte outputMode[] = {
// mapping sortie logique (0..maxoutputs-1) -> sortie physique
const byte gDx[] = {
/* D2 : S1 */ 2,
/* D3 : S2 */ 3,
/* D4 : S3 */ 4,
/* D5 : S4 */ 5,
/* D6 : S5 */ 6,
/* D9 : S6 ou SM1 */ 9,
/* D10 : S7 ou SM2 */ 10,
/* D11 : S8 */ 11
};

// index des servo moteurs dans la table des sorties physiques
#define Index_SM1 5
#define Index_SM2 6

// mode de chaque sortie : IO standard ou PWM
const byte gMode[] = {
/* D2 : S1 */ MODE_IO,
/* D3 : S2 */ MODE_PWM,
/* D4 : S3 */ MODE_IO,
/* D5 : S4 */ MODE_PWM,
/* D6 : S5 */ MODE_PWM,
/* D7 : S6 */ MODE_IO,
/* D8 : S7 */ MODE_IO,
/* D9 : S8 ou SM1 */ MODE_PWM,
/* D10 : S9 ou SM2 */ MODE_PWM,
/* D11 : S10 */ MODE_PWM,
/* D9 : S6 ou SM1 */ MODE_PWM,
/* D10 : S7 ou SM2 */ MODE_PWM,
/* D11 : S8 */ MODE_PWM
};

// Nombre maximum d'éclairages dans le tableau précédent
#define maxLights sizeof(outputMode)/sizeof(byte)
#define maxOutputs sizeof(gMode)

// Entrée digital D15 permettant de choisir la séquence 1 ou la séquence 2 (Pull-up)
const byte seqPin = 15;

// Entrée digital D14 permettant de passer en RUN (1) ou en STOP (0) (Pull-up)
const int startPin = 14; /* ESTARTB/ESTARTH selon l'état bas (STOP) ou haut (RUN) */
// Entrées D7 et D8 pour extraire le numéro d'automatisme, cumulés avec seqPin !
const byte prog0Pin = 7;
const byte prog1Pin = 8;

// Entrées digitals utilisateur (Pull-Up)
// Entrée digitale D14 permettant de passer en RUN (1) ou en STOP (0) (Pull-up)
const byte startPin = 14; /* ESTARTB/ESTARTH selon l'état bas (STOP) ou haut (RUN) */

// Entrées digitales utilisateur (Pull-Up)
const byte inputUserPin1 = 16; /* E1B / E1H selon l'état bas ou haut */
const byte inputUserPin2 = 17; /* E2B / E2H selon l'état bas ou haut */
const byte inputUserPin3 = 18; /* E3B / E3H selon l'état bas ou haut */
const byte inputUserPin4 = 19; /* E4B / E3H selon l'état bas ou haut */

// Anti-rebond optimisé pour la rétro-signalisation Marklin C / Platine Obourg v2
const byte maxInputPins = 5; /* nombre d'entrées à gérer en anti-rebond */
const byte maxInputs = maxInputPins+3;

const byte maxFiltreH = 8; /* en millisecondes, le temps que l'entrée doit être stabilisée avant de passer de 1 -> 0 */
const byte maxFiltreB = 512; /* en millisecondes, le temps que l'entrée doit être stabilisée avant de passer de 0 -> 1 */

// Entrée pour le seed Generator
const byte seedPin = 7;
// Entrée analogique A6 non utilisée
const byte unusedPin = A6;

// Entrée Analogique (A7/D21) pour le seed Generator
const byte seedPin = A7;
Loading

0 comments on commit f81130a

Please sign in to comment.