hf
©Patrice Barthélemy 2017
ligne
Décodeur de signaux
f
Décodeur de Signaux
ligne

Le cahier des charges de ce type de décodeurs est simple: piloter des signaux à 2 ou 3 couleurs avec commun au courant ou à la masse (identique pour tous les signaux d'un décodeur).

Je me suis largement inspiré de l'article de JPClaude du 3 avril 2016. http://www.locoduino.org/spip.php?article161

L'Arduino Nano supporte 5 LEDS allumées en même temps donc notre décodeur sera à 5 voies.

C'est le décodeur le plus simple de la série, son shéma est visible ci-dessous:

lkiuh

Le circuit imprimé est exécuté en simple face pour une question de coût.

Outre le décodeur qui renvoie les sorties sur un connecteur 20 pôles pour câble plat, il intégre 4 bus d'alimentation: DCC, 12V-dc, 18V-ac, 5V-dc.

éplioj

zutio

 

nhjhb

 

gfdhgg

et, le programme pour l'Arduino Nano

/*
* Décodeur pour signaux à 3 feux basé sur un controleur Arduino Nano.
*
* Programme librement interprété par Babar sur la base de celui de JPClaude du 3 avril 2016.
*
* Les feux sont rouges par défaut
* La broche 2 reçoit les interruptions DCC
*
* Signal à 3 couleurs ROUGE; VERT; JAUNE.
* 5 décodeurs par microcontrolleur
* Les leds sont connectées aux broches 3 a A3 par groupes de 3
* Signal 1: 3,4,5
* Signal 2: 6,7,8
* Signal 3: 9,10,11
* Signal 4: 12,13,A0
* Signal 5: A1,A2,A3
* 2 addresses par signal
* paires pour les feux rouges et verts
* impaires pour les feux jaunes
*
*/

/***************************************************************************************
* CONFIGURATION SETTING
*
* MODE : LOW si le +5V des LEDs est commun, HIGH si la masse est commune
* FIRST_ID_DCC : Adresse DCC du premier signal. Avec les centrales Roco, enlever 4 à la valeur desirée
* NB_TRAFFIC_LIGHT : flag qui donne le nombre de couleurs par feu (2 ou 3)
*
****************************************************************************************/


#define MODE HIGH // LOW ou HIGH
#define FIRST_ID_DCC 206 //210-4 Première adresse DCC (pour les centrales Roco n'oubliez pas de la décaler de 4 )
#define NB_TRAFFIC_LIGHT TRICOLOR // signaux 3 couleurs

/******************************************************************************
* Parametres internes
*
********************************************************************************/


#include <DCC_Decoder.h> // Librairie Minabay
#define kDCC_INTERRUPT 0 // la broche 2 recoit les interrupts DCC
int previous_address = 0; // empêche les multiples adresses DCC
int previous_position = 2; // empêche les multiple ordres DCC
volatile boolean update_light; // décide si une mise à jour est nécessaire après une commande DCC

#define TRICOLOR 5 // 5 signaux à 3 leds
#define FIRST_PIN 3 // Broche du premier signal
#define GREEN 0 // adresse DCC/0
#define RED 1 // adresse DCC/1
#define YELLOW 2 // adresse DCC+1/0

/*********************************************************************************
* Definition des signaux
*
********************************************************************************/

struct light {
int address; // son adresse
int current_position; // green / red / yellow (vert / rouge / jaune )
int green; // broche de la LED verte
int red; // broche de la LED rouge
int yellow; // Broche de la LED jaune
boolean activation_request; // demande d'activation
};
light traffic_light[NB_TRAFFIC_LIGHT];

/********************************************************************
* Routine appelée si une requette est faite par le DCC
*
*******************************************************************/


void activation_traffic_light() {
for (int i = 0; i < NB_TRAFFIC_LIGHT; i++) // contrôle pour tous les signaux
{
if (traffic_light[i].activation_request == true) // si le signal est en attente d'activation
{
switch(traffic_light[i].current_position) // on contrôle son état actuel
{
case GREEN :{ // si c'est vert
digitalWrite(traffic_light[i].green,MODE); // allume le vert
digitalWrite(traffic_light[i].red,!MODE); // éteint le rouge
digitalWrite(traffic_light[i].yellow,!MODE); // éteint le jaune
break;}
case RED : { // si c'est rouge
digitalWrite(traffic_light[i].green,!MODE); // éteint le vert
digitalWrite(traffic_light[i].red,MODE); // allume le rouge
digitalWrite(traffic_light[i].yellow,!MODE); // éteint le jaune
break;}
case YELLOW : { // si c'est jaune
digitalWrite(traffic_light[i].green,!MODE); // éteint le vert
digitalWrite(traffic_light[i].red,!MODE); // éteint le rouge
digitalWrite(traffic_light[i].yellow,MODE); // allume le jaune
break;}
}
}
traffic_light[i].activation_request = false; // le signal est declaré mis à jour
}
update_light = false; // toutes les mises à jour sont faites
}


/*************************************************************************************
* Décodage du DCC
*
***********************************************************************************/

void BasicAccDecoderPacket_Handler(int address, boolean activate, byte data)
{

address -= 1; address *= 4; address += 1; address += (data & 0x06) >> 1; // décodage de l'adresse DCC
int led = (data & 0x01) ? GREEN : RED; // DCC/0 ou DCC/1
int traffic_light_index = address; // Index du signal
int color = led; // Couleur de la LED
boolean activation = false;
if ((address != previous_address) || ((led != previous_position) &&
(address == previous_address))){ // Si on change l'adresse ou l'état
switch (NB_TRAFFIC_LIGHT) {

case TRICOLOR : { // rappel signaux 3 couleurs
if ((address >= FIRST_ID_DCC) && (address < FIRST_ID_DCC + (2*NB_TRAFFIC_LIGHT))){
if (address%2 != 0) { traffic_light_index = address - 1; color = YELLOW;} // si l'adresse est impaire >> couleur jaune
traffic_light_index = (traffic_light_index - FIRST_ID_DCC)/2; // Index du signal
activation = true;}
break;}
}
traffic_light[traffic_light_index].activation_request = activation; // activation demandée
traffic_light[traffic_light_index].current_position = color; // cherche couleur de la LED
update_light = activation; // Mise a jour du signal demandée
}e
previous_address = address; previous_position = led; // l'activation est sauvegardée
}


/**********************************************************************************************
* setup + met les signaux au rouge au démarrage
*
*********************************************************************************************/

void setup() {
int pin_jump = 0; // variable broche
int traffic_light_jump = 0; // variable signal
for (int i=0; i<NB_TRAFFIC_LIGHT; i++){ // pour tous les signaux
traffic_light[i].activation_request = false; // pas de demande d'activation
traffic_light[i].green = pin_jump + FIRST_PIN; // Broche de la LED verte
pinMode(traffic_light[i].green, OUTPUT); // broche LED verte en sortie(ID DCC/0)
digitalWrite(traffic_light[i].green, !MODE); // LED verte éteinte
traffic_light[i].red = 1+ pin_jump + FIRST_PIN; // broche de la LED rouge
pinMode(traffic_light[i].red, OUTPUT); // broche LED rouge en sortie (ID DCC/1)
digitalWrite(traffic_light[i].red, MODE); // LED rouge allumée
traffic_light[i].address = traffic_light_jump + FIRST_ID_DCC + i; // son adresse DCC
traffic_light[i].yellow = 2+ pin_jump + FIRST_PIN; // broche de la LED jaune
pinMode(traffic_light[i].yellow, OUTPUT); // broche LED jaune en sortie (ID DCC+1/0)
digitalWrite(traffic_light[i].yellow, !MODE); // LED jaune eteinte
traffic_light_jump++; // signal suivant
pin_jump+=3; // broche suivante



}

DCC.SetBasicAccessoryDecoderPacketHandler(BasicAccDecoderPacket_Handler, true); // initialise le DCC
DCC.SetupDecoder( 0x00, 0x00, kDCC_INTERRUPT ); // son interrupt
update_light = false; // pas de modification

}

/*************************************************************************
* loop
*
******************************************************************/


void loop() {
DCC.loop(); // y-a t-il une commande DCC ?
if (update_light) {activation_traffic_light();} // si oui routine d'activation des signaux
}

La liste de pièces et les coûts

Décodeur
Nom Référence  Prix unitaire pièces par jeu Prix par jeu
Print décodeur 1
1,90
Bornier 2p 0,05 8
0,39
Prise cable plat 20p 0,49 1
0,49
Microcontroleur Arduino nano 1,85 1
1,85
Diode 1N4148 0,01 1
0,01
résistance 10k 0,01 2
0,01
résistance 1k 0,01 1
0,01
Dupport dip8 0,02 1
0,02
Optocoupler 6N137 0,76 1
0,76
bornier nano 0,10 2
0,19
Prix de revient
5,63
Interface
Nom Référence    Prix unitaire pièces par jeu nb pièces
Print interface 1
1,32
Prise cable plat 20p 0,49 1
0,49
connecteur cable 4x 0,07 5
0,33
Prix de revient
2,14

Rappel: 1 jeu = 5 signaux.

 

 

 

 

ligneligneligne