Auteur Sujet: besoin d'aide sur Universal Accesory Decoder  (Lu 42266 fois)

bagou91

  • Jr. Member
  • **
  • Messages: 52
    • Voir le profil
besoin d'aide sur Universal Accesory Decoder
« le: novembre 17, 2016, 05:16:28 pm »
Bonjour,

J'ai lu les 3 articles sur le site à propos de la réalisation Universal Accessory Decoder.
J'aimerai l'utiliser pour actionner mes aiguillages Jouef 3 fils (2 solenoides).

Sur le 3ème article, http://www.locoduino.org/spip.php?article35, je n'arrive bien à comprendre comment déclarer les objets type accessoires par rapport à mes aiguillages.
Pourriez vous m'aider ?

Pour l'instant, je souhaite controler 3 aiguillages avec 3 boutons poussoirs.
Voici le début du code que j'ai mis dans la partie setup()
void setup(){
UAD_StartSetup();
  // Setup of Dcc commander
  dccCommander.Setup(0x00, 0x00, kDCC_INTERRUPT);
  dccCommander.SetStatusLedPin(13);

buttonsCommander.Setup(1,
new ButtonsCommanderPush(2)
);
//bouton n°0, adresse ID 40, pin digital 3 attachée
PUSH(buttonsCommander, 0)->AddDccId(40, 0);
PUSH(buttonsCommander, 0)->AddDccId(40, 1);
PUSH(buttonsCommander, 0)->Setup(3);

  //bouton n°1, adresse ID 41, pin digital 4 attachée
PUSH(buttonsCommander, 1)->AddDccId(41, 0);
PUSH(buttonsCommander, 1)->AddDccId(41, 1);
  PUSH(buttonsCommander, 1)->Setup(4);

  //bouton n°2, adresse ID 42, pin digital 5 attachée
  PUSH(buttonsCommander, 2)->AddDccId(42, 0);
  PUSH(buttonsCommander, 2)->AddDccId(42, 1);
  PUSH(buttonsCommander, 2)->Setup(5);

//là je bute et ne sais comment déclarer mes solenoides d'aiguillages...
accessories.Setup(AccessoryNumber,
new AccessoryLight(40, ...
new AccessoryLight(41, ...
new AccessoryLight(42, ...
);

}

bagou91

  • Jr. Member
  • **
  • Messages: 52
    • Voir le profil
Re : besoin d'aide sur Universal Accesory Decoder
« Réponse #1 le: novembre 17, 2016, 08:41:33 pm »
Finalement après avoir épluché la librairie fourni ici: http://www.locoduino.org/spip.php?article34
j'ai trouvé d'autres classes comme AccessoryMotorOneWay, et DriverArduino.

voici ce que j'ai réussi à coder:
// total number of pushbuttons / accessories.
#define AccessoryNumber 1
#define BOBINE1         0
#define BOBINE2         1
#define BOBINE1_PORT    0
#define BOBINE2_PORT    1

// Accessories
Accessories accessories;
DccCommander dccCommander;
ButtonsCommander buttonsCommander;

// Drivers
DriverArduino *arduino;


void setup()
{
UAD_StartSetup();

    // Setup of the Dcc commander.
dccCommander.Setup(0x00, 0x00, kDCC_INTERRUPT);
dccCommander.SetStatusLedPin(13);

    // Setup of the buttons, one by accessory
buttonsCommander.Setup(1,
new ButtonsCommanderPush(2)
);
    // Each button assigned to an accessory Dcc code.
PUSH(buttonsCommander, 0)->AddDccId(20, 0);
PUSH(buttonsCommander, 0)->AddDccId(20, 1);
  PUSH(buttonsCommander, 0)->Setup(4);
 
    // Declare the Arduino pins.
//PUSH(buttonsCommander, 1)->Setup(5);

// Drivers setups

  // List of the ports on the Arduino. Pors 9,10 and 11 are handled in analog mode for fading.
  arduino = new DriverArduino(2, 0);
  arduino->Setup();
  arduino->SetupPortMotor(BOBINE1_PORT, 6);
  arduino->SetupPortMotor(BOBINE2_PORT, 7);

// Accessories setups

    // Assign Dcc code for each accessory.
accessories.Setup(2);
accessories.Add(new AccessoryMotorOneWay(20, 0, 250)); // DIRECT
accessories.Add(new AccessoryMotorOneWay(20, 1, 250)); // DEVIEE

   // Attach each accessory to its driver/port.
MOTOR1WAY(accessories, BOBINE1)->Setup(arduino, BOBINE1_PORT, 250);
MOTOR1WAY(accessories, BOBINE2)->Setup(arduino, BOBINE2_PORT, 250);

UAD_EndSetup();
}

Et ça fonctionne miraculeusement comme je le voulais ! :D
en appuyant sur le bouton poussoir, cela change l'aiguillage de direction (direct -> déviée), et inversement lorsque je ré-appuie sur le BP.


par contre j'ai quelques interrogations sur le code:

que signifie ces définitions (j'ai déjà compris que ce ne sont pas des pins physiques):
#define BOBINE1         0
#define BOBINE2         1
#define BOBINE1_PORT    0
#define BOBINE2_PORT    1

et m'expliquer les variables données en paramètres ici (les ???):
MOTOR1WAY(objet_accessoire, ???)->Setup(objet_driver, ???, durée);
MOTOR1WAY(accessories, BOBINE1)->Setup(arduino, BOBINE1_PORT, 250);

dans laquelle de ces 2 lignes, les 250ms d'activation de la bobine sont prises en compte:
accessories.Add(new AccessoryMotorOneWay(20, 0, 250));
MOTOR1WAY(accessories, BOBINE1)->Setup(arduino, BOBINE1_PORT, 250);

c'est pointilleux comme demande d'explications, mais j'aime comprendre ce que je passe en paramètres :)

merci pour vos lumières

Thierry

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 810
    • Voir le profil
Re : besoin d'aide sur Universal Accesory Decoder
« Réponse #2 le: novembre 18, 2016, 01:54:25 pm »
Bonjour

En fait c'est assez simple.

D'un côté vous avez une liste d'accessoires que vous avez appelé 'accessories'. Dans cette liste, vous avez ajouté deux moteurs 'AccessoryMotorOneWay', vous auriez tout aussi bien pu ajouter un 'AccessoryMotorTwoWays', le résultat aurait été le même... Mais ça marche aussi comme ça !

De l'autre côté, vous avez un driver, votre 'arduino'. Ce driver dispose d'une liste de ports, un pour chaque broche utilisée.

Ces deux objets sont indépendants. Rien ne les relie automatiquement dans le code. C'est le rôle des 'Setup' d'accessoire de faire le lien.
En écrivant 'MOTOR1WAY(accessories, BOBINE1)->Setup(arduino, BOBINE1_PORT, 250);'
vous dites que l'élément BOBINE1 (donc 1) de la liste des accessoires 'accessories' est relié au port BOBINE1_PORT (donc 1) de la liste des ports du driver 'arduino'. Accessoirement (si j'ose dire), le délai permet effectivement de limiter le temps d'activation du port à 250ms.

J’espère juste qu'entre les broches de l'Arduino et votre aiguillage il y a bien un L298N ou autre pour apporter assez de courant aux bobines. Sinon c'est un bon motif de friture d'Arduino !

Je voudrais ajouter que ce week-end, je devrais être en mesure de publier un article au sujet du successeur de UAD, j'ai nommé 'Accessories'.  Voici la nouvelle version de votre programme pour elle :

#include "Commanders.h"
#include "Accessories.h"

// Accessories
AccessoryMotorOneWay droit, devie;

ButtonsCommanderPush push;

// Drivers
PortOnePin portDroit, portDevie;

#define DCCID_DROIT    DCCINT(20, 0)
#define DCCID_DEVIE   DCCINT(20, 1)

void setup()
{
  Commanders::begin(LED_BUILTIN);
  Accessories::begin();

  // Setup of the Dcc commander.
  DccCommander.begin(0x00, 0x00, digitalPinToInterrupt(3));

  // Setup of the buttons, one by accessory
  push.begin(3, DCCID_DROIT);
  push.AddEvent(DCCID_DEVIE);
 
  // Setup of ports
  portDroit.begin(6, DIGITAL);
  portDevie.begin(7, DIGITAL);

  // Accessories setups

  droit.begin(&portDroit, DCCID_DROIT, 255, 250);
  devie.begin(&portDevie, DCCID_DEVIE, 255, 250);
}

void loop()
{
  unsigned long id = Commanders::loop();
 
  if (id != UNDEFINED_ID)
  {
    // Renvoie l'événement reçu de Commanders, vers les accessoires...
    Accessories::RaiseEvent(id, (ACCESSORIES_EVENT_TYPE) Commanders::GetLastEventType(), Commanders::GetLastEventData());
  }
 
  Accessories::loop();
}

Le gain ? Une écriture plus ramassée, pas de pointeurs, beaucoup moins de macros comme MOTOR1WAY, pas d'indices dans des listes... Mais aussi la disparition des Drivers, une gestion étendue à l'ensemble des circuits d'alimentation du marché présents et à venir. Bref, que des avantages... Par contre la partie Commanders a été extraite et doit être aussi utilisée comme une bibliothèque externe. Le loop peut paraître plus compliqué, mais en fait c'est toujours le même, il ne change pas quel que soit le nombre de boutons, de Commanders utilisés (DCC, mais aussi Série, I2C, CAN...) ou d'accessoires !

Cette bibliothèque est déjà disponible ici : https://git.framasoft.org/locoduino.org/Accessories/blob/master/Accessories.zip.
De son côté, Commanders est dispo ici: https://framagit.org/locoduino.org/Commanders/blob/master/Commanders.zip

Bon courage.

bagou91

  • Jr. Member
  • **
  • Messages: 52
    • Voir le profil
Re : besoin d'aide sur Universal Accesory Decoder
« Réponse #3 le: novembre 18, 2016, 02:41:42 pm »
Merci de m'avoir répondu.
C'est un peu plus clair pour les déclarations avec UAD.

Votre nouvelle librairie est clairement plus simple en déclaration :)
Je remplace donc les fichiers librairies que j'ai dans UAD par ceux de Accessories.zip ?

Maintenant j'aimerai utiliser un autre Arduino pour la partie Commandes en envoyant les ordres par DCC.
Avez vous un exemple pour cela ?

J'ai essayé la librairie CmdrArduino de cet article http://www.locoduino.org/spip.php?article18 , mais rien ne se passe coté UAD à part la LED 13 qui clignote...
Pour visualiser les trames qui sont envoyées j'ai utilisé DCC_Monitor trouvable également sur le site et j'ai bien des trames émises:
A chaque appui momentané sur le bouton poussoir:

méthode: dps.setBasicAccessory(20,0x00);     //adresse dcc 20, position 1 (cf DIRECT)
envoie cette trame: 10010100 11111001 01101101

méthode: dps.unsetBasicAccessory(20,0x00);     //adresse dcc 20, position 0 (cf DEVIE)
envoie cette trame: 10010100 11111000 01101100

pour comprendre la trame, j'ai lu cet article: http://www.train35.fr/dcc18.html#Ancre5 paragraphe 5.4
pour moi, les trames envoyées correspondent bien au contrôle de mon aiguillage (adresse 20, position 0 ou 1).

Merci pour votre aide

Thierry

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 810
    • Voir le profil
Re : besoin d'aide sur Universal Accesory Decoder
« Réponse #4 le: novembre 18, 2016, 02:58:46 pm »
Pour les librairies, oui, il suffit d'installer Accessories et Commanders. Attention, ces deux là ont aussi besoin d'une troisième librairie en embuscade :) : DIO2. Elle est présente dans le répertoire extras de Commanders et Accessories. Normalement c'est le même fichier zip, à installer comme n'importe quelle bibliothèque. UAD peut rester en place, il ne devrait pas y avoir de collisions.

Sur un réseau, il ne peut y avoir qu'un seul donneur d'ordre Dcc. En clair, il n'est pas possible d'insérer un Arduino sur un réseau piloté par une centrale quelle qu'elle soit. Si l'Arduino est seul, alors il est possible de pousser des trames via un cmdrArduino ou un Dcc++, sinon il faut passer par un autre canal.
Dans Commanders, il y a un Commander I2C. Cette interface de communication est présente sur presque tous les Arduino. Dans les exemples de commanders se trouve un programme autonome sans Commanders qui est un émetteur d'ordres I2C, sachant que Commanders est lui un récepteur. Dans cette optique on aurait un Arduino 'TCO' avec Commanders pour gérer ses boutons, et une copie de l'exemple émetteur d'ordres I2C. De l'autre un Arduino (ou plusieurs) avec Commanders et Accessories recevant ses ordres via le I2CCommander et agissant sur les accessoires.
Ce que je dis là avec I2C est également vrai pour une liaison CAN, bien plus sûre tant en distance qu'en sensibilité aux perturbations...

bagou91

  • Jr. Member
  • **
  • Messages: 52
    • Voir le profil
Re : besoin d'aide sur Universal Accesory Decoder
« Réponse #5 le: novembre 18, 2016, 03:10:23 pm »
OK je vais voir en I2C...

Entre temps j'ai essayé les nouvelles librairies et j'ai des erreurs:
dans DIO2.zip, il manque un dossier board. J'ai trouvé cette version qui l'a bien: https://github.com/jdolinay/Arduino_DIO2/files/247586/DIO2.zip

Ensuite, autre erreur, et là je sèche:
C:\Users\bag\Documents\Arduino\libraries\Accessories\src\Port.cpp:99:59: error: macro "CHECKPIN" passed 3 arguments, but takes just 2

  CHECKPIN(inPin, inType, "Incorrect pin number in MovePin");

                                                           ^

C:\Users\bag\Documents\Arduino\libraries\Accessories\src\Port.cpp: In member function 'void Port::MovePin(int, int, PIN_TYPE) const':

C:\Users\bag\Documents\Arduino\libraries\Accessories\src\Port.cpp:99:2: error: 'CHECKPIN' was not declared in this scope

  CHECKPIN(inPin, inType, "Incorrect pin number in MovePin");

  ^
« Modifié: novembre 18, 2016, 03:45:54 pm par bagou91 »

Thierry

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 810
    • Voir le profil
Re : besoin d'aide sur Universal Accesory Decoder
« Réponse #6 le: novembre 18, 2016, 03:40:31 pm »
La version de Jay est celle qui m'a permis de commencer, mais je l'ai abondamment modifiée. Il faut absolument utiliser celle qui est présente dans les répertoires extras de mes deux librairies. Pour installer une bibliothèque, je rappelle qu'il faut utiliser l'option ' Croquis/Inclure une bibliothèque.../Ajouter le bibliothèque ZIP... ' qui garantit une installation conforme. Et en faisant ça, dans mon IDE 1.6.11 (donc pas le dernier...) j'ai bien le dossier board !

bagou91

  • Jr. Member
  • **
  • Messages: 52
    • Voir le profil
Re : besoin d'aide sur Universal Accesory Decoder
« Réponse #7 le: novembre 18, 2016, 03:47:38 pm »
OK j'ai importé votre librairie via l'IDE ARduino, ça fonctionne bien pour DIO2.

Par contre j'ai toujours l'autre erreur sur CHECKPIN.

Je compile sur Leonardo.

Thierry

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 810
    • Voir le profil
Re : besoin d'aide sur Universal Accesory Decoder
« Réponse #8 le: novembre 18, 2016, 04:00:54 pm »
Je viens de repousser le zip sur la forge. Il y avait une erreur sur CHECK_PIN dans certains cas particuliers...

bagou91

  • Jr. Member
  • **
  • Messages: 52
    • Voir le profil
Re : besoin d'aide sur Universal Accesory Decoder
« Réponse #9 le: novembre 18, 2016, 04:44:40 pm »
Merci pour la correction.
Ca compile bien ! :)

Maintenant j'ai bien les trames DCC envoyées par CmdrArduino qui sont bien reçues et comprises par DCCCommander.
1er appui BP sur CmdrArduino:
Dcc packet found : real data : 20 / 0 / 1  converted : 77 / 0 / 1
2ème appui BP sur CmdrArduino:
Dcc packet found : real data : 20 / 1 / 1  converted : 77 / 1 / 1

En revanche, le comportement attendu ne se fait pas:
- Mes sorties 6 et 7 ne s'activent pas via l'envoi de la trame DCC.
- Depuis DCCCommander, un appui sur le BP en pin 4 active ma sortie 6, un second appui active la sortie 7. Les 2 sorties restent activées indéfiniment.
la sortie DEBUG:
ButtonsCommanderButton id:20 selected !
 PortOnePin 6 MoveRightDir()
ButtonsCommanderButton id:10020 selected !
 PortOnePin 7 MoveRightDir()
ButtonsCommanderButton id:20 selected !
 PortOnePin 6 MoveRightDir()
ButtonsCommanderButton id:10020 selected !
 PortOnePin 7 MoveRightDir()

mon code DCCCommander:
#include "Commanders.h"
#include "Accessories.h"

// Accessories
AccessoryMotorOneWay droit, devie;

ButtonsCommanderPush push;

// Drivers
PortOnePin portDroit, portDevie;

#define DCCID_DROIT    DCCINT(20, 0)
#define DCCID_DEVIE   DCCINT(20, 1)

void setup()
{
  Commanders::begin(LED_BUILTIN);
  Accessories::begin();

  // Setup of the Dcc commander.
  DccCommander.begin(0x00, 0x00, digitalPinToInterrupt(3));

  // Setup of the buttons, one by accessory
  push.begin(DCCID_DROIT, 4);
  push.AddEvent(DCCID_DEVIE);
 
  // Setup of ports
  portDroit.begin(6, DIGITAL);
  portDevie.begin(7, DIGITAL);

  // Accessories setups

  droit.begin(&portDroit, DCCID_DROIT, 255, 250);
  devie.begin(&portDevie, DCCID_DEVIE, 255, 250);
}

void loop()
{
  unsigned long id = Commanders::loop();
 
  if (id != UNDEFINED_ID)
  {
    // Renvoie l'événement reçu de Commanders, vers les accessoires...
    Accessories::RaiseEvent(id, (ACCESSORIES_EVENT_TYPE) Commanders::GetLastEventType(), Commanders::GetLastEventData());
     
  }
 
  Accessories::loop();
}

Merci pour votre aide au debuggage

Thierry

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 810
    • Voir le profil
Re : besoin d'aide sur Universal Accesory Decoder
« Réponse #10 le: novembre 18, 2016, 05:06:37 pm »
Pas de souci, j'ai aussi besoin de cas concrets pour déverminer le code...

Je n'avais pas pensé à cela. Effectivement, rien ne dit que les deux moteurs sont dépendants... Changeons notre fusil d'épaule en utilisant un seul moteur :

#include "Commanders.h"
#include "Accessories.h"

// Accessories
AccessoryMotorTwoWays aiguille;

ButtonsCommanderPush push;

// Drivers
PortTwoPins port;

#define DCCID_DROIT   DCCINT(20, 0)
#define DCCID_DEVIE   DCCINT(20, 1)

void setup()
{
  Commanders::begin(LED_BUILTIN);
  Accessories::begin();

  // Setup of the Dcc commander.
  DccCommander.begin(0x00, 0x00, digitalPinToInterrupt(3));

  // Setup of the buttons, one by accessory
  push.begin(DCCID_DROIT, 4);
  push.AddEvent(DCCID_DEVIE);
 
  // Setup of ports
  port.begin(6, 7, DIGITAL);

  // Accessories setups

  aiguille.beginTwoWays(&port, DCCID_DROIT, DCCID_DEVIE, 255, 250);
}

void loop()
{
  unsigned long id = Commanders::loop();
 
  if (id != UNDEFINED_ID)
  {
    // Renvoie l'événement reçu de Commanders, vers les accessoires...
    Accessories::RaiseEvent(id, (ACCESSORIES_EVENT_TYPE) Commanders::GetLastEventType(), Commanders::GetLastEventData());
  }
 
  Accessories::loop();
}

bagou91

  • Jr. Member
  • **
  • Messages: 52
    • Voir le profil
Re : besoin d'aide sur Universal Accesory Decoder
« Réponse #11 le: novembre 19, 2016, 08:16:26 am »
Merci pour cette correction.

Le comportement est OK avec le BP sur l'arduino DCCCommander.

Par contre les ordres envoyés par CmdrArduino ne sont toujours pas compris.
DCCCommander recoit bien les trames mais rien ne se passe sur les sorties.

que signifie le "converted" (adresse 20 passe en valeur 77) ?
Dcc packet found : real data : 20 / 1 / 1  converted : 77 / 1 / 1

Thierry

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 810
    • Voir le profil
Re : besoin d'aide sur Universal Accesory Decoder
« Réponse #12 le: novembre 19, 2016, 10:46:36 am »
Le Dcc fournit des valeurs brutes (real data) qu'il faut interpréter pour obtenir quelque chose qui ressemble à ce qui est affiché sur l'écran de la plupart des centrales...

Je ne sais pas quelle centrale vous utilisez, mais il semble que les valeurs transmises par la trame Dcc soient déjà les valeurs converties...
Pour tester cette idée, ajoutez la ligne DccCommander.UseRawDccAddresses = true; juste après le begin de DccCommander.

bagou91

  • Jr. Member
  • **
  • Messages: 52
    • Voir le profil
Re : besoin d'aide sur Universal Accesory Decoder
« Réponse #13 le: novembre 19, 2016, 11:54:21 am »
Je n'ai pas de centrale DCC. J'utilise CmdrArduino pour transmettre des trames Dcc.

J'ai essayé avec DccCommander.UseRawDccAddresses = true;
La console m'affiche bien les trames non converties:
Dcc packet found : real data : 20 / 0 / 1  converted : 20 / 0 / 1
Dcc packet found : real data : 20 / 1 / 1  converted : 20 / 1 / 1

Mais toujours aucune réaction sur mes sorties.

J'ai également essayé dans ce sens:
J'ai changé les adresses en 77.
Commenté DccCommander.UseRawDccAddresses = true;
#define DCCID_DROIT   DCCINT(77, 0)
#define DCCID_DEVIE   DCCINT(77, 1)
Je suppose que la trame converti donnant la valeur 77 pourrait correspondre à l'adresse que j'ai modifiée ici ?
Mais pas plus de chance: pas de réaction de mes sorties.

A quoi correspond la dernière valeur de la trame ?
La 2eme valeur correspond je pense au changement de l'aiguille car elle varie entre 0 et 1.
"Dcc packet found : real data : 20 / 1 / ? converted : 20 / 1 / ?"
« Modifié: novembre 19, 2016, 12:27:26 pm par bagou91 »

Thierry

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 810
    • Voir le profil
Re : besoin d'aide sur Universal Accesory Decoder
« Réponse #14 le: novembre 19, 2016, 07:04:42 pm »
Une adresse Dcc pour accessoire est décomposée en deux parties : la première donne l'adresse du décodeur, la seconde est le numéro de l'accessoire pour ce gestionnaire, entre 0 et 7. Mais sur les centrales classiques, par exemple sur ma MS2 Trix, les accessoires ont une adresse de 1 à 320, et un numéro associé de 0 ou 1. C'est le rôle de la version convertie de passer de 22 / 4 à 90 / 0 (calcul fait de tête sans garantie !). enfin la troisième valeur demande à activer ou désactiver l'accessoire, c'est à dire 0 ou 1. DccCommander ne se préoccupe que de 0...
Tout ça pour dire que cmdrArduino doit envoyer une adresse calculée selon la norme (décodeur + n° accessoire parmi 8) pour que Dcccommander interprète cette adresse et utilise ces valeurs pour les accessoires. L'autre solution est celle que nous avons appliquée : cmdrArduino envoie une valeur brute (20/0) et DccCommander n'interprète pas (avec useRaw...) et prend ces valeurs telles quelles... Ce qui ne semble pas marcher non plus. Je sèche !