Canalblog
Editer l'article Suivre ce blog Administration + Créer mon blog
Publicité
le petit train de Jembi

logo_jembi150px

Publicité
le petit train de Jembi
Archives
5 août 2019

Un décodeur d'accessoires DCC (digital) avec un arduino

Le but de cet article est de montrer pas à pas comment créer un décodeur dcc (qui se pilote avec la centrale digitale roco multimaus, z21, uhlenbrock intellibox, esu ECOS ou autre)

Je suis moi-même un parfait débutant.

voici un exemple de ce que j'ai réalisé en 1h environ.

exemple

Je me suis inspiré de l'article suivant : http://sam95.fr/blog/2016/01/30/decodeur-daccessoires-avec-un-arduino-partie-1/

  •  I : acheter le matériel et l'arduino 

Il faut un :

1

- 1 arduino UNO (environ 4€) et son câble usb (pas présenté sur la photo ci dessus) + en option une alimentation dédiée (transfo 5v 3A)

- des câbles (aussi appelé jumper wire)

pour relier la centrale DCC qui envoie du 16V à l'arduino qui fonctionne en 5V il faut un petit montage à base d'optocoupleur : 

- 1 petite plaque de montage rapide (0,40€)

- 2 résistances de 10KOhm (0,04€ 10 resistances 10k)
- 1 résistance de 1Kohm (0,04€ resistance 1k)
- 1 diode 1N4148 (0,07€)
- 1 optocoupleur 6N137 (0,13€)

  • II : le montage éléctronique

Un decriptif détaillé du montage de l'interface DCC est disponible en anglais ici : http://www.mynabay.com/dcc_monitor/

voici le shéma éléctronique à réaliser (il suffit de suivre les étapes ci dessous)

2

Je vais essayer de traduire les étapes en français :

1ère étape : insérer l'optocoupleur 6N137 sur la petite plaque de montage, la patte n°1 marqué d'un point en haut à droite (à noter que le composant chinois que j'ai acheté, n'a pas de point sur la patte n°1, donc j'ai mis l'écriture du composant à l'envers comme sur l'image ci dessous)

a

 

2ème étape : placer la diode 1N4148 entre la patte 2 et 3 (attention à l'orientation de la diode, le trait noir vers le bas)

b

3e étape : placer la résistance 1K entre la patte 2 et une ligne inutilisée (j'ai fais ce montage avec des resitances de couleur différente, verte par exemple, ça marche aussi)

c

4e étape : installet un morceau de cable entre la patte 8 et un slot (ligne) inutilisé : ceci sera l'alimentation en +5V

d

 

5e étape : insérer une résistance 10k entre la patte 7 et le slot +5V (de l'étape 4)

e

6e étape : placer l'autre resistance 10k entre la patte 6 et le slot +5V

f

7e étape : voici les cables qui seront relié au rails ou directement à la centrale digitale DCC (ici les 2 cables sont rouge) / un cable à la patte 3 et l'autre au slot de l'étape 3

g

8e étape : cabler le +5V à l'arduino, on utilise un cable orange

h

h2

9e étape : cabler le GND (masse) à l'arduino, on utilise un cable vert ici connecté à la patte 5

i

i2

10e étape : utiliser un cable bleu pour relier la patte 6 à l'entrée 2 de l'arduino

j

j2

et voilà le montage fini, il reste plus qu'a relier les 2 fils rouge au digital DCC

k

 

  • III : la partie logicielle
  1. pour installer le logiciel arduino (à télécharger ici), suivre les étapes d'installation installation_arduino_windows.pdf
  2. refermer le programme arduino
  3. ajouter la bibliothèque (librairie) DCC decoder, que l'on peut télécharger ici https://github.com/MynaBay/DCC_Decoder ou ici DCC_Decoder_master.zip
  4. décompresser le fichier .zip dans le repertoire C :\Program Files (x86)\Arduino\libraries  (on trouve des explications aussi ici)
  5. lancer le programme arduino et choisir le port COM pour communiquer avec l'arduino (chez moi c'est le port COM3)
  6. charger l'exemple DCC_Monitor 

    11

  7. transférer le programme dans l'arduino (bouton flèche à droite)

    22

  8. attendre la fin du transfert
  9. ouvrir la fenêtre serial monitor

    33

  10. appuyer sur un bouton de la central Digital (intellibox ou multimaus) et on voit que la communication fonctionne ! l'arduino reconnait les commandes DCC !  (pour ceux qui veulent en savoir plus sur les trames DCC qui sont affichés : allez voir ici sur le site locoduino)

    44

 

 

  •  IV : Allumer et éteindre un led verte avec sa centrale digitale

dans le logiciel arduino, charger maintenant un autre exemple : DCC_Basic_Acc_Decoder

remplacer dans le programme

void ConfigureDecoder()
  {
  gAddresses[0].address = 714;
  gAddresses[0].output = 0;
  gAddresses[0].outputPin = 5;
  gAddresses[0].isDigital = false;
  gAddresses[0].isFlasher = false;
  gAddresses[0].analogValue = 250;
  gAddresses[0].durationMilli = 500;

par

void ConfigureDecoder()
  {
  gAddresses[0].address = 20; //activé par l'aiguille 20 sur la centrale digital
  gAddresses[0].output = 0;
  gAddresses[0].outputPin = 5; //pin 5 sur l'arduino où on branche la led (et aussi à la masse GND)
  gAddresses[0].isDigital = false;
  gAddresses[0].isFlasher = false;
  gAddresses[0].analogValue = 250;
  gAddresses[0].durationMilli = 0; //laisse la led tout le temps allumée

 

 

 

Publicité
Publicité
Commentaires
F
Bonjour Jembi<br /> <br /> <br /> <br /> Merci pour ton site <br /> <br /> <br /> <br /> J'ai essayé tes deux montages avec mon arduino, Cela fonctionne parfaitement.<br /> <br /> <br /> <br /> J'ai essayé le décodeur sur un attiny85, grande déception ça ne fonctionne pas.<br /> <br /> Quelles seraient mes erreurs? Je précise que j'utilise un attiny85 à 8mhz pas un digispark.<br /> <br /> <br /> <br /> Merci pour ton aide<br /> <br /> <br /> <br /> infra voici mon code :<br /> <br /> <br /> <br /> <br /> <br /> //attiny85<br /> <br /> <br /> <br /> #include <br /> <br /> <br /> <br /> //adresse multimaus = adresse + 4<br /> <br /> // Defines and structures<br /> <br /> //<br /> <br /> #define kDCC_INTERRUPT 0<br /> <br /> <br /> <br /> typedef struct<br /> <br /> {<br /> <br /> int address; // Address to respond to<br /> <br /> byte output; // State of output 1=on, 0=off<br /> <br /> int outputPin; // Arduino output pin to drive<br /> <br /> boolean isDigital; // true=digital, false=analog. If analog must also set analogValue field<br /> <br /> boolean isFlasher; // true=flash output, false=no time, no flash.<br /> <br /> byte analogValue; // Value to use with analog type.<br /> <br /> int durationMilli; // Milliseconds to leave output on for. 0 means don't auto off<br /> <br /> <br /> <br /> unsigned long onMilli; // Used internally for timing<br /> <br /> unsigned long offMilli; // <br /> <br /> } DCCAccessoryAddress;<br /> <br /> <br /> <br /> DCCAccessoryAddress gAddresses[4]; // nombre d'adresse, 4 sorties disponibles<br /> <br /> <br /> <br /> //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////<br /> <br /> //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////<br /> <br /> //<br /> <br /> // Decoder Init <br /> <br /> //<br /> <br /> void ConfigureDecoder()<br /> <br /> {<br /> <br /> gAddresses[0].address = 5;// adresse multimaus 9<br /> <br /> gAddresses[0].output = 1;<br /> <br /> gAddresses[0].outputPin = 0;// led<br /> <br /> gAddresses[0].isDigital = false;<br /> <br /> gAddresses[0].isFlasher = false;<br /> <br /> gAddresses[0].analogValue = 250;<br /> <br /> gAddresses[0].durationMilli = 0;<br /> <br /> <br /> <br /> gAddresses[1].address = 6;// adresse multimaus 10<br /> <br /> gAddresses[1].output = 1;<br /> <br /> gAddresses[1].outputPin = 1;<br /> <br /> gAddresses[1].isDigital = false;<br /> <br /> gAddresses[1].isFlasher = false;<br /> <br /> gAddresses[1].analogValue = 250;<br /> <br /> gAddresses[1].durationMilli =0;<br /> <br /> <br /> <br /> gAddresses[2].address = 7;// adresse multimaus 11<br /> <br /> gAddresses[2].output = 1;<br /> <br /> gAddresses[2].outputPin = 3;<br /> <br /> gAddresses[2].isDigital = false;<br /> <br /> gAddresses[2].isFlasher = false;<br /> <br /> gAddresses[2].analogValue = 250;<br /> <br /> gAddresses[2].durationMilli = 0;<br /> <br /> <br /> <br /> gAddresses[3].address = 8;// adresse multimaus 11<br /> <br /> gAddresses[3].output = 1;<br /> <br /> gAddresses[3].outputPin = 4;<br /> <br /> gAddresses[3].isDigital = false;<br /> <br /> gAddresses[3].isFlasher = false;<br /> <br /> gAddresses[3].analogValue = 250;<br /> <br /> gAddresses[3].durationMilli = 0;<br /> <br /> <br /> <br /> // Setup output pins<br /> <br /> for(int i=0; i> 1;<br /> <br /> <br /> <br /> boolean enable = (data & 0x01) ? 1 : 0;<br /> <br /> <br /> <br /> for(int i=0; i= (int)(sizeof(gAddresses)/sizeof(gAddresses[0])) )<br /> <br /> {<br /> <br /> addr = 0;<br /> <br /> }<br /> <br /> <br /> <br /> ////////////////////////////////////////////////////////////////<br /> <br /> // Turn off output?<br /> <br /> if( gAddresses[addr].offMilli && gAddresses[addr].offMilli<millis() )<br /> <br /> {<br /> <br /> // Clear off time<br /> <br /> gAddresses[addr].offMilli = 0;<br /> <br /> <br /> <br /> // Disable output<br /> <br /> if( gAddresses[addr].isDigital )<br /> <br /> {<br /> <br /> digitalWrite( gAddresses[addr].outputPin, LOW);<br /> <br /> }else{<br /> <br /> analogWrite( gAddresses[addr].outputPin, 0);<br /> <br /> }<br /> <br /> <br /> <br /> // If still enabled and a flash type, set on time<br /> <br /> if( gAddresses[addr].output && gAddresses[addr].isFlasher)<br /> <br /> {<br /> <br /> gAddresses[addr].onMilli = millis() + gAddresses[addr].durationMilli;<br /> <br /> }else{<br /> <br /> gAddresses[addr].output = 0;<br /> <br /> }<br /> <br /> <br /> <br /> return;<br /> <br /> }<br /> <br /> <br /> <br /> ////////////////////////////////////////////////////////////////<br /> <br /> // Turn on output?<br /> <br /> if( gAddresses[addr].onMilli && gAddresses[addr].onMilli<=millis() )<br /> <br /> {<br /> <br /> // Clear off time<br /> <br /> gAddresses[addr].onMilli = 0;<br /> <br /> <br /> <br /> // Enable output<br /> <br /> if( gAddresses[addr].isDigital )<br /> <br /> {<br /> <br /> digitalWrite( gAddresses[addr].outputPin, HIGH);<br /> <br /> }else{<br /> <br /> analogWrite( gAddresses[addr].outputPin, gAddresses[addr].analogValue);<br /> <br /> }<br /> <br /> <br /> <br /> // If still enabled and a flash type, set off time<br /> <br /> if( gAddresses[addr].durationMilli )<br /> <br /> {<br /> <br /> gAddresses[addr].offMilli = millis() + gAddresses[addr].durationMilli;<br /> <br /> }<br /> <br /> <br /> <br /> return;<br /> <br /> }<br /> <br /> <br /> <br /> }
Répondre
Publicité