Auteur Sujet: Code decodeur pour aiguillage à solenoides  (Lu 10874 fois)

becbunsen

  • Newbie
  • *
  • Messages: 46
    • Voir le profil
Code decodeur pour aiguillage à solenoides
« le: novembre 30, 2023, 09:45:00 pm »
Bonjour à tous,

Je viens de réaliser le décodeur pour aiguillages à solenoides
https://www.locoduino.org/spip.php?article318

J'ai suivi scrupuleusement la liste des composants, je comprend bien le schema electronique mais je bute sur la partie logicielle:
J'ai chargé tel quel le code fourni sur la page, mais je ne sais pas à quelle adresse il répond, ou faut il l'indiquer, quelle commande DCC faut il envoyer, j'utilise "ma premiere centrale DCC" avec un arduino mega et un shield moteur. les locomotives fonctionnent bien.

Je ne suis pas sur non plus de la commande à envoyer, j'ai essayé <a 001 0 1> et d'autres combinaisons et adresses mais sans succés. je ne sais pas si mon arduino reçoit bien les trames DCC.
il me manque peut-être le petit condensateur ceramique à rajouter sur l'optocoupleur.

Bref, si vous avez une idée pour tester....

J'ai cherché si il y'avait eu un forum concernant ce montage mais je n'ai pas trouvé

Merci de votre aide

becbunsen

  • Newbie
  • *
  • Messages: 46
    • Voir le profil
Re : Code decodeur pour aiguillage à solenoides
« Réponse #1 le: novembre 30, 2023, 09:46:33 pm »
Le code:

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Arduino DCC Solenoid Switch Decoder.
// Author: Ruud Boer - January 2015.  This sketch turns an Arduino
// into a DCC decoder to drive max 8 dual coil solenoid switches. pins 14 to 19 for A0 to A5
// The DCC signal is optically separated and fed to pin 2 (=Interrupt 0). Schematics: www.mynabay.com
// Many thanks to www.mynabay.com for publishing their DCC monitor and -decoder code.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// msport version for Locoduino paper 27 03 2022 and dilc3 pcb
// https://www.locoduino.org/spip.php?article318
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// IMPORTANT: GOTO lines 22 and 47 to configure some data!                                                                       <---- je ne sais pas ce qu'il faut faire!!
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include <DCC_Decoder.h>
#define kDCC_INTERRUPT 0

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// FILL IN
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const byte maxaccessories=8; //The number of switches you want to control with this Arduino
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

typedef struct
{
  int               address;         // Address to respond to
  byte              output;          // State of accessory: 1=on, 0=off (for internal use only)
  int               outputPin;       // Arduino output pin
  int               outputPin2;      // Arduino output pin2, used for solenoid junctions
  byte              highlow;         // State of outputpin: 1=HIGH, 0=LOW
  byte              highlow2;        // State of outputpin2: 1=HIGH, 0=LOW
  boolean           finished;        // Memory location that says the oneshot is finished
  boolean           finished2;       // Memory location that says the second oneshot (for solenoid) is finished
  int               durationMilli;   // ms flash time
  unsigned long     onMilli;         // for internal use
  unsigned long     offMilli;        // for internal use
}
DCCAccessoryAddress;
DCCAccessoryAddress accessory[maxaccessories];

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Initialization: COPY - PASTE the structure as many times as you have switches and fill in the values you want.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ConfigureDecoderFunctions() // The amount of accessories must be same as in line 19 above!
{
  accessory[0].address = 1; // K1 connector
  accessory[0].durationMilli = 250;
  accessory[0].outputPin = 4;
  accessory[0].outputPin2 = 3;
  accessory[0].highlow = 0; // Do not change this value
  accessory[0].highlow2 = 0; // Do not change this value
  accessory[0].finished = false; // Do not change this value
  accessory[0].finished2 = true; // Do not change this value
  accessory[0].output = 0; // Do not change this value

  accessory[1].address = 2; // K2 connector
  accessory[1].durationMilli = 250;
  accessory[1].outputPin = 6;
  accessory[1].outputPin2 = 5;
  accessory[1].highlow = 0; // Do not change this value
  accessory[1].highlow2 = 0; // Do not change this value
  accessory[1].finished = false; // Do not change this value
  accessory[1].finished2 = true; // Do not change this value
  accessory[1].output = 0; // Do not change this value
 
  accessory[2].address = 3; // K3 connector
  accessory[2].durationMilli = 250;
  accessory[2].outputPin = 8;
  accessory[2].outputPin2 = 7;
  accessory[2].highlow = 0; // Do not change this value
  accessory[2].highlow2 = 0; // Do not change this value
  accessory[2].finished = false; // Do not change this value
  accessory[2].finished2 = true; // Do not change this value
  accessory[2].output = 0; // Do not change this value

  accessory[3].address = 4; // K4 connector
  accessory[3].durationMilli = 250;
  accessory[3].outputPin = 10;
  accessory[3].outputPin2 = 9;
  accessory[3].highlow = 0; // Do not change this value
  accessory[3].highlow2 = 0; // Do not change this value
  accessory[3].finished = false; // Do not change this value
  accessory[3].finished2 = true; // Do not change this value
  accessory[3].output = 0; // Do not change this value

  accessory[4].address = 5; // K5 connector
  accessory[4].durationMilli = 250;
  accessory[4].outputPin = 12; 
  accessory[4].outputPin2 = 11;
  accessory[4].highlow = 0; // Do not change this value
  accessory[4].highlow2 = 0; // Do not change this value
  accessory[4].finished = false; // Do not change this value
  accessory[4].finished2 = true; // Do not change this value
  accessory[4].output = 0; // Do not change this value

  accessory[5].address = 6; // K6 connector
  accessory[5].durationMilli = 250;
  accessory[5].outputPin = 15;   // A1
  accessory[5].outputPin2 = 14;  // A0
  accessory[5].highlow = 0; // Do not change this value
  accessory[5].highlow2 = 0; // Do not change this value
  accessory[5].finished = false; // Do not change this value
  accessory[5].finished2 = true; // Do not change this value
  accessory[5].output = 0; // Do not change this value

  accessory[6].address = 7; // K7 connector
  accessory[6].durationMilli = 250;
  accessory[6].outputPin = 17; // A3
  accessory[6].outputPin2 = 16; // A2
  accessory[6].highlow = 0; // Do not change this value
  accessory[6].highlow2 = 0; // Do not change this value
  accessory[6].finished = false; // Do not change this value
  accessory[6].finished2 = true; // Do not change this value
  accessory[6].output = 0; // Do not change this value

  accessory[7].address = 8; // K8 connector
  accessory[7].durationMilli = 250;
  accessory[7].outputPin = 19; // A5
  accessory[7].outputPin2 = 18; // A4
  accessory[7].highlow = 0; // Do not change this value
  accessory[7].highlow2 = 0; // Do not change this value
  accessory[7].finished = false; // Do not change this value
  accessory[7].finished2 = true; // Do not change this value
  accessory[7].output = 0; // Do not change this value
 
  // Setup output pins
  for(int i=0; i<maxaccessories; i++)
  {
    if( accessory.outputPin )
      {
      pinMode( accessory.outputPin, OUTPUT );
      digitalWrite( accessory.outputPin, LOW);
    }
    if( accessory.outputPin2 )
      {
      pinMode( accessory.outputPin2, OUTPUT );
      digitalWrite( accessory.outputPin2, LOW);
    }
  }
} // END ConfigureDecoderFunctions

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// DCC packet handler
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void BasicAccDecoderPacket_Handler(int address, boolean activate, byte data)
{
  // Convert NMRA packet address format to human address
  address -= 1;
  address *= 4;
  address += 1;
  address += (data & 0x06) >> 1;

  boolean enable = (data & 0x01) ? 1 : 0;

  for(int i=0; i<maxaccessories; i++)
   {
    if( address == accessory.address )
      {
      if( enable ) accessory.output = 1;
      else accessory.output = 0;
    }
  }
} // END BasicAccDecoderPacket_Handler

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Setup (run once)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup()
{
  DCC.SetBasicAccessoryDecoderPacketHandler(BasicAccDecoderPacket_Handler, true);
  ConfigureDecoderFunctions();
  DCC.SetupDecoder( 0x00, 0x00, kDCC_INTERRUPT );
  pinMode(2,INPUT_PULLUP); //Interrupt 0 with internal pull up resistor (can get rid of external 10k)
  pinMode(13,OUTPUT);
  digitalWrite(13,LOW); //turn off Arduino led at startup

  for (int n=0; n<maxaccessories; n++) accessory[n].output = 0; //all servo's to min angle and functions to 0
} //END setup

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Main loop (run continuous)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop()
{
  static int addr = 0;

  DCC.loop(); // Loop DCC library

  if( ++addr >= maxaccessories ) addr = 0; // Bump to next address to test

  if (accessory[addr].output == 1)
   {
      if (!accessory[addr].highlow && !accessory[addr].finished)
      {
         accessory[addr].highlow = 1;
         accessory[addr].offMilli = millis() + accessory[addr].durationMilli;
      }
      if (accessory[addr].highlow && millis() > accessory[addr].offMilli)
      {
         accessory[addr].highlow = 0;
         accessory[addr].finished = true;
      }
      accessory[addr].finished2 = false;
  }

  else // output==0
  {
      accessory[addr].highlow=0;
      accessory[addr].finished = false;
      if (!accessory[addr].highlow2 && !accessory[addr].finished2)
      {
         accessory[addr].highlow2 = 1;
         accessory[addr].offMilli = millis() + accessory[addr].durationMilli;
      }
      if (accessory[addr].highlow2 && millis() > accessory[addr].offMilli)
      {
         accessory[addr].highlow2 = 0;
         accessory[addr].finished2 = true;
      }
  }

  if (accessory[addr].highlow) digitalWrite( accessory[addr].outputPin, HIGH);
  else digitalWrite( accessory[addr].outputPin, LOW);
  if (accessory[addr].highlow2) digitalWrite( accessory[addr].outputPin2, HIGH);
  else digitalWrite( accessory[addr].outputPin2, LOW);

} //END loop

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

msport

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 2217
  • HO avec DCC++ en DIY Réseaux très éphémères
    • Voir le profil
Re : Code decodeur pour aiguillage à solenoides
« Réponse #2 le: novembre 30, 2023, 10:19:24 pm »
Bonsoir,
vous avez dans l'article : https://www.locoduino.org/spip.php?article317 les codes DCC de commande des aiguillages.
Vous pouvez les envoyer depuis le serial monitor à la centrale.

Le petit condensateur 22 - 270pF peut se révéler nécessaire avec certains 6N137

Cela dit, je vous recommande de réaliser le montage tel qu'il est décrit. La variante suggérée avec alimentation par les voies peut vous amener des ennuis surtout si vous ne maitrisez pas bien le schéma.

De toute manière toutes les tensions utilisées sont des tensions continues.
15V CC proposée pour les bobines ne pose pas de problème.
Utiliser une tension alternative a toutes les chances de griller votre montage.

Relisez :
Tel qu’il est configuré, le programme permet de commander l’aiguillage sur le connecteur K1 à l’adresse 1, K2 à l’adresse 2 et ainsi de suite jusqu’à K8 à l’adresse 8. Vous pouvez commander les aiguillages aux adresses de votre choix en décalant par pas de 8 les adresses 1 à 8 dans le programme fourni. (ex : 9 à 17)
Cordialement

becbunsen

  • Newbie
  • *
  • Messages: 46
    • Voir le profil
Re : Code decodeur pour aiguillage à solenoides
« Réponse #3 le: novembre 30, 2023, 11:31:05 pm »

Merci pour votre réponse
Oui, j'ai bien effectué le montage comme décrit avec l'alimentation séparée (12v continu pour ma part)
L'arduino seul est par contre alimenté d'office par le circuit du DCC sur ce montage (d'après ce que j'ai compris...)

Pour vérifier mon montage, j'ai réalisé le petit test qu'avait ecrit un autre membre ici:
https://forum.locoduino.org/index.php?topic=1620.msg17335#msg17335

j'ai donc bien +/-2,5v en presence de DCC à la borne D2 du nano
j'ai installé le petit sketch avec le timer, il affiche bien "l'interruption s'est déclenchée" sur le moniteur serie lorsque j'envoie par exemple <a 200 2 1>


Relisez :
Tel qu’il est configuré, le programme permet de commander l’aiguillage sur le connecteur K1 à l’adresse 1, K2 à l’adresse 2 et ainsi de suite jusqu’à K8 à l’adresse 8. Vous pouvez commander les aiguillages aux adresses de votre choix en décalant par pas de 8 les adresses 1 à 8 dans le programme fourni. (ex : 9 à 17)
C'est justement ce que je n'ai pas compris : comment spécifie t'on qu'on utilise la plage 1 à 8? Il me semblait avoir lu quelque part qu'on utilisait aussi les sous adresses mais c'est peut être dans un autre montage

Merci
Julien



 

« Modifié: novembre 30, 2023, 11:39:01 pm par becbunsen »

msport

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 2217
  • HO avec DCC++ en DIY Réseaux très éphémères
    • Voir le profil
Re : Code decodeur pour aiguillage à solenoides
« Réponse #4 le: décembre 01, 2023, 09:58:44 am »
Bonjour,
"l'interruption s'est déclenchée"  montre que la partie détection fonctionne.

Adresse / sous adresse, c'est la cuisine du NMRA, ce n'est pas l'adresse de l'accessoire.
Pour le décodeur tout est dit dans :
accessory[0].address = 1; // K1 connector

Accessoire adresse 1 sur connecteur K1

Si vous remplacez = 1  par = 9 vous aurez Accessoire adresse 9 sur connecteur K1

Cordialement

becbunsen

  • Newbie
  • *
  • Messages: 46
    • Voir le profil
Re : Code decodeur pour aiguillage à solenoides
« Réponse #5 le: décembre 01, 2023, 01:24:12 pm »
Bonjour,
Merci de votre aide mais pour être sur de bien comprendre, avec le code en état, quel ordre faut il que j'envoie à ma centrale DCC pour que faire fonctionner le connecteur K1?

msport

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 2217
  • HO avec DCC++ en DIY Réseaux très éphémères
    • Voir le profil
Re : Code decodeur pour aiguillage à solenoides
« Réponse #6 le: décembre 01, 2023, 04:16:28 pm »
Bonjour,
comme dit dans l'article 317, déjà cité :
https://www.locoduino.org/spip.php?article317
pour l’adresse 1 : <a 1 0 0> pour normal puis <a 1 0 1> pour dévié.
Via le serial monitor correctement configuré.
Vous avez bien une réponse à <1> ?


Cordialement

becbunsen

  • Newbie
  • *
  • Messages: 46
    • Voir le profil
Re : Code decodeur pour aiguillage à solenoides
« Réponse #7 le: décembre 01, 2023, 06:28:15 pm »
Oui, mon shield moteur allume ses leds et je peux controler mes locomotives, je n'ai pas de retour dans le moniteur serie. je ne sais pas si c'est attendu.
Par contre, il me semble qu'une commande <a xxx x x> devrait renvoyer <A xxx x x> dans le moniteur.

Je n'ai pas encore pu investiguer depuis mon précédent message mais le fait que le décodeur affiche bien l'interruption est encourageant, je vais refaire des essais. (je pense pourtant avoir testé votre commande)

Le probleme est que que je n'étais pas du tout sûr de la commande à transmettre et donc je ne savais pas d'ou venait le non fonctionnement. je vais déja pouvoir essayer avec la bonne commande.
Sinon, il faudra que je me penche un peu sur la bibliotheque Decoder

Je vous tiens au courant

msport

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 2217
  • HO avec DCC++ en DIY Réseaux très éphémères
    • Voir le profil
Re : Code decodeur pour aiguillage à solenoides
« Réponse #8 le: décembre 01, 2023, 07:01:55 pm »
Bonsoir,

à priori, la commande <a ... ne renvoie rien dans le moniteur serie.

Pour avoir un retour il faut déclarer les aiguillages avec la commande T pour avoir un ID.
Et ensuite passer des commandes <T ID ... sur cet ID. On a alors un retour avec <H ID ...

Voir https://www.locoduino.org/IMG/docx/commandes_pour_dcc_basestation.docx

<t doit renvoyer un <T ... (locos)
Cordialement

msport

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 2217
  • HO avec DCC++ en DIY Réseaux très éphémères
    • Voir le profil
Re : Code decodeur pour aiguillage à solenoides
« Réponse #9 le: décembre 04, 2023, 03:29:40 pm »
Bonjour,

avez vous pu vérifier ?
Cordialement

becbunsen

  • Newbie
  • *
  • Messages: 46
    • Voir le profil
Re : Code decodeur pour aiguillage à solenoides
« Réponse #10 le: décembre 05, 2023, 11:37:40 am »
Oui,
Ca ne marche pas... :-[ Je séche pour le moment.... je vais reprendre depuis le début en réassemblant une carte avec uniquement la partie DCC vers Arduino (sans le circuit de puissance uln) et essayer de comprendre le code de la bibliotheque pour allumer juste une led.
Je n'ai même plus le message de l'interruption, j'ai peut-être grillé quelque chose avec mon montage volant...

Merci tout de même pour votre aide, je pense que je n'etais pas loin,

(j'aurais probablement du placer ce post dans la partie débutant...)

msport

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 2217
  • HO avec DCC++ en DIY Réseaux très éphémères
    • Voir le profil
Re : Code decodeur pour aiguillage à solenoides
« Réponse #11 le: décembre 05, 2023, 12:20:51 pm »
Bonjour,

les tests avec <a...  et <T... ne nécessitent aucun montage c'est juste les retours d'une BaseStation.

Vous avez au moins le retour à <1> ?

Je ne sais pas si il est utile de comprendre la bibliothèque mais bien de voir ce que fait le programme et ses variantes.

En particulier, utilisez la LED_BUILTIN, la 13 et vous n'avez qu'à relier le montage Mynabay. : 5V, IO2 et GND.

sur un mini programme avec :

const byte maxaccessories=1; //The number of switches you want to control with this Arduino

  accessory[0].address = 1; // DCC address
  accessory[1].mode = 2; // Oneshot: HIGH for ontime ms, then LOW and stays LOW.
  accessory[1].outputPin = 13;
  accessory[1].ontime = 1000;

PS : le programme de Ruud Boer original avec ses quatre modes.



Cordialement

becbunsen

  • Newbie
  • *
  • Messages: 46
    • Voir le profil
Re : Code decodeur pour aiguillage à solenoides
« Réponse #12 le: décembre 17, 2023, 10:22:30 am »
Bonjour, J'avoue que je suis un peu perdu.... :-[
J'ai installé le programme original que vous m'avez transmis.
J'ai modifié la ligne du début pour ecrire
const byte maxaccessories=1; //The number of switches you want to control with this Arduino

et utiliser dans un premier temps le mode 1:
 accessory[0].address = 1; // DCC address
 accessory[0].mode = 1; // Continuous: HIGH until DCC switches the address off again
 accessory[0].outputPin = 13; // Arduino pin to which this accessory is connected

La, miracle, ça fonctionne ( à l'envers ) la led s'éteind lorsque j'envoie <a 1 0 1>  et s'allume bien lorsque je fait <a 1 0 0>

j'avais un probleme de timer avec le mode 2 (1000ms n'était pas visible, il fallait que je mette 50000) mais c'est resolu

par contre, ca ne fonctionne pas si je modifie
 accessory[0].address = 2
 et que j'envoie <a 2 0 1>

Bref je continue mes recherches mais si vous avez une idée....


« Modifié: décembre 17, 2023, 11:33:11 am par becbunsen »

msport

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 2217
  • HO avec DCC++ en DIY Réseaux très éphémères
    • Voir le profil
Re : Code decodeur pour aiguillage à solenoides
« Réponse #13 le: décembre 17, 2023, 11:45:18 am »
Bonjour,

il faut peut-être traduire (google) :
const byte maxaccessories=1; //The number of switches you want to control with this Arduino
const octet maxaccessories=1 ; //Le nombre de commutateurs que vous souhaitez contrôler avec cet Arduino
Avec cette ligne, vous n'aurez jamais qu'un seul accessoire.
Si vous voulez tester 8 adresses, il faut remettre :
const byte maxaccessories=8; //The number of switches you want to control with this Arduino
les adresses étant définies au départ de 1 à 8
 accessory[0].address = 1; // K1 connector
   ...
 accessory[7].address = 8; // K8 connector

Chaque bloc concerne une adresse.
Cordialement

becbunsen

  • Newbie
  • *
  • Messages: 46
    • Voir le profil
Re : Code decodeur pour aiguillage à solenoides
« Réponse #14 le: décembre 20, 2023, 10:26:20 pm »
Oui, j'avais noté ce point aprés mon message mais je n'avais pas modifié,
Cela dit, je suis arrivé parfois à un resultat dans mes tests: celui d'avoir le message d'interruption et controler la led 13 en mode 1.
Malheureusement, ce n'est pas reproductible, aujourd'hui, je n'arrive plus à rien....

J'ai refait un montage sur breadboard avec juste la partie signal et pas la partie alim. Que des composants neufs. j'ai à ma disposition un oscilloscope qui me montre bien un beau signal carré à la broche 2 de l'arduino, 2,6v au voltmetre. j'ai essayé 4 arduino, des uno, des nano, j'ai changé 2 fois l'optocoupleur.... rien n'y fait.

Je commence par mettre en doute ma centrale sur sa capacité à générer un beau signal pour accessoire. (mega+motor shield) pourtant 0 probleme avec les locos.

Le montage est décrit des centaines de fois sur internet, je ne comprend pas comment pourquoi je n'y arrive pas :(
D'autant que sans decodeur, on ne fait rien marcher du tout...

Bref, je ne sais plus quoi faire. achat d'un decodeur du commerce pour voir comment ça se comporte, réalisation d'une autre cenrale,...