LOCODUINO

Bibliothèque DCCpp

Encore un DCC++ ? Mais à quoi ça sert ?

.
Par : Thierry

DIFFICULTÉ :

Les lecteurs des articles et du forum Locoduino qui s’intéressent au DCC connaissent forcément DCC++, la perle de Gregg E. Berman déjà maintes fois utilisée dans nos projets. Pourtant, à chaque utilisation, les sources de DCC++ sont copiés puis adaptés dans le nouveau projet. Si une évolution intervient dans le code de DCC++, il faut recommencer la copie et l’adaptation dans chaque projet qui l’utilise et qui veut bénéficier des nouveautés...
C’est exactement pour faciliter cela que l’IDE Arduino a créé les bibliothèques !

Pourquoi une bibliothèque ?

Nous sommes devant le cas typique d’un projet dont une bonne partie du code doit pouvoir être ré-utilisée dans d’autres projets. C’est le but d’une bibliothèque, et c’est ce que j’ai décidé de faire après avoir vu tout le monde ici s’en servir, et l’avoir moi-même utilisé dans au moins deux projets différents : Bibliothèque DcDccNanoController et sa grande sœur encore en gestation...

Une bibliothèque comme celle-ci doit répondre à plusieurs contraintes :

  • Respecter le travail du véritable auteur et minimiser les modifications apportées.
    Lorsque vous êtes l’auteur d’une bibliothèque, vous n’avez personne à qui rendre des comptes à propos du contenu ou de la forme de cette bibliothèque. Ce n’est pas le cas ici, puisque je suis parti du remarquable travail de Gregg. Il a donc fallu reproduire intégralement les copyrights, les documentations du source et conserver autant que possible l’API, c’est à dire les noms des classes et des fonctions exposées aux utilisateurs.
  • Fournir une boite noire
    Une bibliothèque, c’est un truc obscur que les utilisateurs ne voient qu’à travers la liste des fonctions exposées dans le fichier .h principal. C’est ce que l’on appelle une boite noire : on l’installe, et on l’oublie. Pas question de changer quoi que ce soit dedans. Tout le paramétrage doit se faire à partir du croquis de l’utilisateur. C’est la grande différence avec la version originale de DCC++ qui imposait la modification de plusieurs fichiers .h pour régler son fonctionnement. On va malgré tout voir que je n’ai malheureusement pas pu tout régler aussi élégamment que ce que j’aurai voulu...
  • Fournir une API claire et simple
    L’API, c’est un peu la signature d’une bibliothèque. C’est à la fois la liste des fonctions et/ou des classes et de ses fonctions membres. Si l’on veut qu’une bibliothèque soit utilisée, son rôle doit être parfaitement défini, et le nombre de choses à implémenter dans le croquis doit être aussi logique et limité que possible.
    Logique par le nommage et le rôle de chaque objet et fonction, et limité à ce qui est vraiment nécessaire et suffisant pour ne pas noyer l’utilisateur dans des choses d’usage rare ou incompréhensibles, ou dans les rouages internes du fonctionnement dont il n’a probablement rien à faire.
  • Fournir une documentation et des exemples
    Expliquer à un utilisateur dans une documentation à quoi sert une bibliothèque est le meilleur moyen de fixer une API, parce que l’on se rend compte des besoins et des attentes. Fournir des exemples est encore plus utile, puisque l’on s’aperçoit en l’écrivant de la cohérence et de la simplicité ou pas de l’interface. C’est souvent le moment d’une remise en cause de certaines choses que l’on croyait simples et évidentes !

Rôle de la bibliothèque

Laissons Gregg parler pour nous expliquer à quoi sert DCC++ (extrait d’un texte traduit par mes soins, le readme de Github, lien tout en haut de l’article...) :

DCC++ BASE STATION est un programme C++ pour l’Arduino Uno et l’Arduino Mega utilisant l’Arduino IDE 1.6.6.

Il permet à un Arduino Uno ou Mega standard équipé d’un Arduino Motor Shield (ou d’un autre) d’être utilisé comme une centrale DCC complète, conforme aux standards DCC du NMRA, pour un réseau de modélisme ferroviaire digital.

Cette version de DCC++ BASE STATION supporte :

  • Adresse de décodeur sur deux (adresse courte) et quatre octets (adresse longue).
  • Contrôle simultané de plusieurs locomotives.
  • Commande à 128 pas de vitesse.
  • Fonctions F0 à F28
  • Activation d’accessoires utilisant 512 adresses, chacune avec 4 sous adresses (norme NMRA complète).
  • Est incluse la possibilité de stocker l’état courant d’aiguillages connectés à cette centrale.
  • Programmation d’un décodeur sur la voie principale
    • Ecriture de CV par octets
    • Ecriture de CV par mise à jour de certains bits individuellement.
  • Programmation sur une voie dédiée de programmation
    • Ecriture de CV par octets
    • Ecriture de CV par mise à jour de certains bits individuellement.
    • Lecture des données émises par le décodeur en cours de programmation.

DCC++ BASE STATION est contrôlé par des commandes textes recues par l’interface série de l’Arduino. Elles peuvent être envoyées par la console série de l’IDE Arduino, ou par des interfaces ou des programmes extérieurs.

Sur un Arduino Mega, un shield Ethernet peut être utilisé pour recevoir des ordres via un réseau informatique plutôt que par la liaison série.

Le rôle de la nouvelle bibliothèque sera grosso-modo le même, avec quelques adaptations pour rendre son usage un petit peu plus facile et mieux répondre à des besoins généraux.

Adaptations

Arduino
Grâce à l’intervention de Dominique, le code de DCC++ a été rendu compatible avec un Arduino Nano, qui est quasiment identique à un Uno avec quelques broches de plus (A6 et A7). C’est ce qui m’a permis de l’utiliser pour la Bibliothèque DcDccNanoController. La bibliothèque a aussi été rendue compatible avec les ESP32, Arduino plus puissants et multi-coeurs. Au passage, l’IDE 1.8.13 a été testé et validé pour la bibliothèque.
Commandes texte
Dans la version originale de DCC++, les trains sont uniquement pilotés à partir de commandes texte. J’ai voulu y ajouter un moyen plus direct, des commandes envoyées par des fonctions membres d’une classe dédiée DCCpp. Elle donne accès à toutes les commandes utiles pour piloter un ou plusieurs trains et des accessoires. La partie commande texte devient optionnelle, mais elle reste disponible si besoin.
Shields moteur
Le choix des shields compatibles avec le programme original résulte sans doute de ce que Gregg a pu trouver au moment de l’écriture de son code. Il s’agit de l’Arduino Motor shield V3 et du Pololu MC33926 Motor shield. A noter que pour le premier, j’ai trouvé un compatible en chine pour la moitié du prix, et il marchait très bien... jusqu’à ce qu’il grille ! Sans doute une mauvaise manip de ma part sur un shield probablement plus fragile que l’original. Les shields originaux permettent aussi la mesure de courant pour la remontée d’information des décodeurs. Pour ma propre centrale, mon choix s’est porté sur le fameux LMD18200 dont nous parlons beaucoup ici... Après avoir écarté la mesure de courant imprécise fournie par le LMD lui-même, c’est le petit circuit Max471 qui remplit ce rôle. Cette configuration est bien connue puisque déjà utilisée dans cet article et bien d’autres. Bien sûr, pas question de nous brider à ces seuls matériels, il faut que l’interface soit aussi ouverte que possible, sans perdre son héritage !
Shields Ethernet
Là encore Gregg a utilisé plusieurs shields : Arduino Ethernet Shield v1, Arduino Ethernet Shield v2, et le Seeed Studio Ethernet Shield qui semble avoir disparu. De mon côté, je me suis procuré des shields et des petits modules (chinois toujours...) à base du circuit ENC28J60.

La nouvelle bibliothèque

DCCpp.h
Il s’agit du fichier include principal de la bibliothèque. Comme dans mes autres bibliothèques, c’est le fichier à modifier si l’on veut exclure des parties inutiles pour le croquis. C’est aussi le seul fichier à modifier si besoin. Ceux qui connaissaient la version classique de DCC++ doivent oublier les config.h et autres comm.h ! Les classes Turnout, Output, Sensor et EEStore (sauvegarde de l’état général des autres classes dans l’EEPROM) peuvent être totalement ou partiellement exclues de la compilation, évitant ainsi de polluer l’espace mémoire programme de votre application. Par défaut tout est désactivé, et il suffit de retirer le ’//’ de début de commentaire devant la ligne #define que l’on veut pour activer une partie de la bibliothèque.

////////////////////////////////////////////////////////
// Add a '//' at the beginning of the line to be in release mode.
//#define DCCPP_DEBUG_MODE

///////////////////////////////////////////////////////
// Verbose mode lets you see all actions done by the 
// library, but with a real flood of text to console...
// Has no effect if DCCPP_DEBUG_MODE is not activated.
//#define DCCPP_DEBUG_VERBOSE_MODE

///////////////////////////////////////////////////////
// The function DCCpp::printConfiguration()
// is very heavy in program memory. So to avoid problems
// you can make this function available by uncomment the next line.
//#define DCCPP_PRINT_DCCPP

//  Inclusion area
//

/**Comment this line to avoid using and compiling Turnout.*/
//#define USE_TURNOUT
/**Comment this line to avoid using and compiling EEPROM saving.*/
//#define USE_EEPROM
/**Comment this line to avoid using and compiling Outputs.*/
//#define USE_OUTPUT
/**Comment this line to avoid using and compiling Sensors.*/
//#define USE_SENSOR
/**Comment this line to avoid using and compiling Serial commands.*/
//#define USE_TEXTCOMMAND
/**Comment this line to avoid using and compiling Ethernet shield using Wiznet 5100 chip.*/
//#define USE_ETHERNET_WIZNET_5100
/**Comment this line to avoid using and compiling Ethernet shield using Wiznet 5500 chip.*/
//#define USE_ETHERNET_WIZNET_5500
/**Comment this line to avoid using and compiling Ethernet shield using Wiznet 5200 chip.*/
//#define USE_ETHERNET_WIZNET_5200
/**Comment this line to avoid using and compiling Ethernet shield using ENC28J60 chip.*/
//#define USE_ETHERNET_ENC28J60

On peut également décider d’utiliser ou non la partie commande par texte, baptisée SerialCommand dans la version originale, mais rebaptisée TextCommand ici, vu que la liaison Ethernet utilise aussi ce canal... Si dans les petites classes précédemment citées, l’IDE était probablement capable tout seul d’éliminer les sources dont le code n’est pas utilisé, le problème est différent avec TextCommand qui comme son nom l’indique contient beaucoup de texte qui va forcément remplir la mémoire SRAM, la mémoire vive de l’Arduino, et ce même s’il n’est pas utilisé. Dans l’esprit de ne pas modifier plus que nécessaire l’oeuvre de Gregg, je ne suis pas repassé partout pour transférer ces textes en mémoire programme avec des F("")...
Comme d’habitude chez moi, des macros DCCPP_DEBUG_MODE et DCCPP_PRINT_DCCPP existent aussi, qui permettent respectivement d’activer un mode d’affichage qui va envoyer quantité d’informations sur la console afin de mieux comprendre ce qui se passe, de voir les erreurs éventuelles, et permettre d’imprimer un rapport complet de la configuration utilisée si besoin.
Enfin, comme je l’ai un peu dévoilé plus haut, je n’ai pas pu laisser le créateur de croquis choisir librement son shield Ethernet sans l’obliger à passer par la modification de ce fichier et l’activation ou non de l’une des macros USE_ETHERNET_WIZNET_5100 (Shield v1), USE_ETHERNET_WIZNET_5500 (shield v2), USE_ETHERNET_WIZNET_5200 (Seeed) ou USE_ETHERNET_ENC28J60.

Fonctionnement général de DCCpp/DCC++ : les registres

Exactement comme la version originale de Gregg, la bibliothèque dispose par défaut de 12 registres pour la voie principale, et 3 pour la voie de programmation. Un registre sert à stocker des ordres DCC à envoyer. Le moteur de DCC++ va scanner tous les registres en séquence et envoyer ces ordres dès qu’il le peut. Le registre 0 est destiné aux ordres transitoires, ceux que l’on envoie qu’une seule fois, comme l’activation d’accessoire ou l’arrêt d’urgence.
Tous les ordres DCC placés dans les autres registres seront répétés à l’infini. Par exemple la commande de vitesse est répétée en permanence, permettant ainsi à une loco qui subit une micro coupure de courant de retrouver immédiatement son ordre de vitesse et sa direction. Si l’ordre n’avait été envoyé qu’une seule fois, la loco se serait arrêtée et attendrait un ordre. Par défaut, le code de Gregg pousse l’activation de fonction dans le registre 0, en faisant ainsi un ordre unique, potentiellement perdu à la première coupure venue. J’ai choisi pour ma part de laisser le choix à l’utilisateur de la bibliothèque.
Si l’on retire le registre 0 qui est réservé pour les ordres uniques, il reste onze registres. Donc en gros 11 locomotives pilotables simultanément. Grâce à sa mémoire vive plus vaste, on pourrait aller plus loin sur un Mega en allouant plus de registres et ainsi piloter plus de locos...

Classe DCCpp
C’est la classe principale. Elle contient quelques fonctions que l’on peut classer en quatre groupes :

  • celles du setup avec begin(), beginMain() pour la voie principale, beginProg() pour la voie de programmation, et beginEthernet() pour le shield Ethernet. A noter que ces trois dernières fonctions sont toutes facultatives. Par exemple si beginProg n’est pas appelée, cela signifiera pour la bibliothèque que la partie voie de programmation sera complètement ignorée, les broches ne seront évidemment pas réservées, et le moteur d’envoi de paquet ne se préoccupera pas de cette partie. Bien sûr, si à la fois beginMain et beginProg ne sont pas appelées, la partie DCC n’aura plus beaucoup de travail...
    Les beginMain et beginProg réclament essentiellement des numéros de broche à activer ou interroger, mais toutes sont facultatives ! J’ai utilisé ici une astuce de programmation : un numéro de broche est stocké dans un ’byte’ dont la valeur peut varier entre 0 et 255. Aucun Arduino aujourd’hui n’a plus de broches que le Mega, et celui-ci en compte 69 en comptant les broches analogiques. Je peux donc utiliser toutes les valeurs au-dessus de 69 pour dire autre chose à la fonction. Pour ce genre de choses, mieux vaut utiliser des valeurs frappantes, comme 0 ou 255, et comme le 0 est un numéro de broche valide, j’ai décidé de lui dire que cette broche n’était pas utile avec le numéro 255. Une constante UNDEFINED_PIN a été définie à 255 pour que le stratagème soit plus évident à comprendre...
    Afin de simplifier l’accès aux shields moteurs historiques, j’ai ajouté les fonctions beginMainMotorShield() et beginProgMotorShield() pour le shield Arduino Motor Shield, et beginMainPololu() et beginProgPololu() pour le shield Pololu. Ces fonctions ne réclament aucun arguments et sont strictement équivalentes à un beginMain ou un beginProg avec les bons arguments.
  • les fonctions générales loop() à appeler forcément dans la loop du croquis, panicStop(true/false) à appeler en cas de besoin. Il y a aussi powerOn() et powerOff() pour mettre et couper le courant, et setAccessory() pour envoyer un ordre DCC d’activation/désactivation d’un accessoire.
  • les fonctions de pilotage pour la voie principale : setSpeedMain() pour le sens et la direction, setFunctionsMain() pour les fonctions de la loco, readCvMain() pour la lecture de variables de configuration du decodeur et writeCvMain() pour les écrire. Une fonction getCurrentMain() est aussi disponible pour consulter une valeur pondérée du courant consommé.
  • et les mêmes fonctions de pilotage pour la voie de programmation setSpeedProg(), setFunctionsProg(), readCvProg(), writeCvProg() et getCurrentProg(). Vous noterez que c’est une amélioration puisque dans le code original, impossible de déplacer une loco ou d’utiliser une de ses fonctions sur la voie de programmation ! D’ailleurs la classe TextCommand ne permet pas de fixer la vitesse, la direction ou l’état d’une fonction d’une loco sur la voie de programmation par une commande texte.

Les fonctions

Pour gérer les fonctions d’une loco, il faut envoyer sur la voie un paquet DCC qui utilise l’adresse du décodeur concerné et deux octets qui correspondent à un champ de bits correspondant à un petit ensemble de fonctions. La norme DCC défini cinq ensembles : F0 à F4, F5 à F8, F9 à F12, F13 à F20 et enfin F21 à F28. Il n’est pas possible d’activer séparément telle ou telle fonction , la norme réclame l’envoi de l’état de toutes les fonctions actives du même ensemble dans ce paquet. Il faut donc tenir une comptabilité de l’état des fonctions actives pour une loco donnée. Et en fonction de ce qui a été activé, envoyer les bons groupes...
Pour simplifier cette gestion, j’ai ajouté une classe FunctionsState. Il doit y avoir une instance de cette classe pour chaque loco pilotée. Les méthodes setFunctionsMain et Prog reçoivent une instance de classe FunctionsState en argument et en déduisent ce qu’il faut envoyer en DCC...

Les classes annexes
Ce que j’appelle les classes annexes sont celles qui ne sont pas directement liées au fonctionnement de la centrale DCC, mais qui peuvent y ajouter des fonctionnalités, comme manœuvrer un accessoire ou surveiller un capteur. D’ailleurs je dis classe, mais en réalité ce sont des structures. Et là on redécouvre une particularité du C++ : les structures sont des classes publiques dont tous les membres sont publics ! A tel point qu’il est possible d’y implanter des fonctions membre, et même des constructeurs ! La suite de l’article parlera de classes, mais ce sont bien des structures...
Tout comme le reste de DCC++, ces classes étaient exclusivement prévues pour une gestion par la ligne de commande. Cette possibilité est évidemment conservée si USE_TEXTCOMMAND est activé, mais un fonctionnement plus ’objet’ a été ajouté.
Dans le cas d’utilisation de TextCommand, rien n’est à faire dans le croquis. Sans TextCommand, il faut déclarer les objets utilisés, puis les initialiser avec un begin(). Ceci doit impérativement être fait avant DCCpp::begin(), parce que si la sauvegarde EEPROM est activée (avec USE_EEPROM) alors c’est pendant ce begin que les configurations des différents objets annexes seront rechargées depuis l’EEPROM.

Classe Turnout
DCCpp est capable de gérer des accessoires en envoyant la commande DCC qui va bien pour en changer l’état, et en mémorisant l’état courant dans l’EEPROM de l’Arduino. Chaque accessoire doit être une instance de la classe Turnout. Le fichier source a été renommé pour mieux coller au nom de la classe, l’original s’appelait Accessories.c . Le nom de la classe n’a pas changé, c’était déjà Turnout.

Classe Sensor
DCCpp est capable aussi de vérifier à intervalle régulier l’état d’une broche de l’Arduino. Lorsqu’une broche change d’état, alors un message est envoyé sur l’interface série ou Ethernet utilisée pour les commandes textuelles. Sans la commande textuelle, une fonction isActive() permet de tester l’état de cette broche à n’importe quel moment. Chaque broche scannée doit être gérée par une instance de la classe Sensor.

Classe Output
DCCpp est capable d’activer ou de désactiver des broches. Chaque broche gérée doit être déclarée avec une instance de la classe Output. La classe permet l’activation avec un état haut ou bas de la broche associée, selon le besoin de ce qui y est raccordé.

Classe EEStore
Si l’EEprom est activée, alors les autres classes annexes sauveront leur état lorsque la fonction store() sera appelée. Le chargement avec load() se fait tout seul pendant le setup(), mais le store() n’est pas automatique. Votre croquis doit l’appeler de temps à autre pour tenir compte des changements qui ont pu intervenir pendant l’exécution... Une fonction clear() est disponible pour réinitialiser la mémoire. Enfin le stockage par EEStore commence à l’octet 0 de la mémoire EEPROM, et sur une longueur qui dépend des nombres de Output, Sensor et Turnout. Donc si vous avez d’autres données à sauver derrière, laissez une place suffisante !

Un peu de pratique

Le matériel

Savoir quel matériel brancher, et comment, sont des sujets déjà parfaitement traités dans l’article Réalisation de centrales DCC avec le logiciel libre DCC++ (3) de Christophe que je vous recommande chaudement...

Exemple Série

L’exemple le plus simple d’utilisation de la bibliothèque est celui qui passe par une liaison série pour envoyer des ordres, par exemple en se servant de la console de l’IDE lorsque l’Arduino est connecté à l’ordinateur :

/*************************************************************
project: <Dc/Dcc Controller>
author: <Thierry PARIS>
description: <Dcc Serial Controller sample>
*************************************************************/

#include "DCCpp.h"

#ifndef USE_TEXTCOMMAND
#error To be able to compile this sample,the line #define USE_TEXTCOMMAND must be uncommented in DCCpp.h
#endif

void setup()
{
	Serial.begin(115200);

	DCCpp::begin();
  // Configuration for my LMD18200. See the page 'Configuration lines' in the documentation for other samples.
#if defined(ARDUINO_ARCH_ESP32)
	DCCpp::beginMain(UNDEFINED_PIN, 33, 32, 36);
#else
	DCCpp::beginMain(UNDEFINED_PIN, DCC_SIGNAL_PIN_MAIN, 11, A0);
#endif
}

void loop()
{
	DCCpp::loop();
}

Pas grand-chose dans cet exemple. On commence par l’inclusion de la bibliothèque, puis vient un message de sécurité réclamant l’ouverture de l’utilisation de la classe TextCommand obligatoire pour cet exemple avec la définition de USE_TEXTCOMMAND dans DCCpp.h .
Le setup() lance DCCpp avec le begin, et configure la voie principale via beginMain. L’appel à beginMain est différent selon que l’on compile pour un Uno ou un Mega, ou un ESP32. Cette fonction comprend quatre arguments :

  • Le premier argument est la broche qui sert de renvoi du signal sur un Arduino Mega équipé d’un shield moteur Arduino. Dans le cas de cet exemple, c’est un LMD18200 qui est utilisé, il n’y a donc pas besoin de cette broche et UNDEFINED_PIN est donné en argument. Pour les shields permis par le DCC++ original, il faut utiliser MOTOR_SHIELD_DIRECTION_MOTOR_CHANNEL_PIN_A ou POLOLU_DIRECTION_MOTOR_CHANNEL_PIN_A.
  • Le deuxième argument est la broche de signal, généralement dépendante du fonctionnement des interruptions de l’Arduino utilisé. Dans les cas de Uno, Nano ou Mega, le DCC++ original fixait déjà la bonne valeur dans une constante DCC_SIGNAL_PIN_MAIN que j’ai juste ré-utilisée ici. Inutile de dire que mettre UNDEFINED_PIN ici est possible, mais supprime tout traitement DCC pour cette voie...
  • Le troisième argument correspond à la broche ’PWM’ du LMD18200 et sert à activer ou pas la sortie DCC. Avec un PWM à 0, le courant est coupé sur la voie ! Pour les cas de shield Arduino ou Pololu, cette broche est donnée avec la constante
    MOTOR_SHIELD_SIGNAL_ENABLE_PIN_MAIN ou POLOLU_SIGNAL_ENABLE_PIN_MAIN. Il est aussi possible de raccorder cette broche ’PWM’ directement au 5V, et laisser UNDEFINED_PIN en argument. Dans ce cas, DCCpp ne pourra pas couper le courant sur la voie, et il faudra prévoir un autre mécanisme pour les cas d’urgence...
  • Le quatrième argument correspond à la broche de mesure de courant pour la programmation des CVs. Dans le cas des shields habituels, sont à utiliser MOTOR_SHIELD_CURRENT_MONITOR_PIN_MAIN ou POLOLU_CURRENT_MONITOR_PIN_MAIN. Il est aussi possible de ne pas utiliser de mesure de courant en mettant UNDEFINED_PIN. Dans ce cas on peut toujours programmer les CVs, mais pas lire leur contenu, ni être sûr que la programmation s’est bien passée...

Pour beginProg, les arguments ont la même signification, mais le nom des constantes à utiliser se terminent par _PROG au lieu de _MAIN.

Pour mieux comprendre, voici ce qu’il faut mettre dans le setup() pour les cas décrits dans l’article de Christophe :

Arduino Uno + LMD18200 + MAX471

DCCpp::beginMain(UNDEFINED_PIN, DCC_SIGNAL_PIN_MAIN, 3, A0);

Arduino Uno + 2 LMD18200 + 2 MAX471

DCCpp::beginMain(UNDEFINED_PIN, DCC_SIGNAL_PIN_MAIN, 3, A0);
DCCpp::beginProg(UNDEFINED_PIN, DCC_SIGNAL_PIN_PROG, 5, A1);

Arduino Mega2560 + LMD18200 + MAX471

DCCpp::beginMain(UNDEFINED_PIN, DCC_SIGNAL_PIN_MAIN, 3, A0);

Arduino Mega2560 + 2 LMD18200 + 2 MAX471

DCCpp::beginMain(UNDEFINED_PIN, DCC_SIGNAL_PIN_MAIN, 3, A0);
DCCpp::beginProg(UNDEFINED_PIN, DCC_SIGNAL_PIN_PROG, 11, A1);

Arduino Uno ou Mega2560 + Arduino Motor Shield

DCCpp::beginMainMotorShield();
DCCpp::beginProgMotorShield();

Ce qui est strictement équivalent à :

DCCpp::beginMain(MOTOR_SHIELD_DIRECTION_MOTOR_CHANNEL_PIN_A, DCC_SIGNAL_PIN_MAIN, MOTOR_SHIELD_SIGNAL_ENABLE_PIN_MAIN, MOTOR_SHIELD_CURRENT_MONITOR_PIN_MAIN);
DCCpp::beginProg(MOTOR_SHIELD_DIRECTION_MOTOR_CHANNEL_PIN_B, DCC_SIGNAL_PIN_PROG, MOTOR_SHIELD_SIGNAL_ENABLE_PIN_PROG, MOTOR_SHIELD_CURRENT_MONITOR_PIN_PROG);

Malgré les différences de câblage entre un Uno et un Mega, ce sont les définitions des constantes qui changent automatiquement au moment de la compilation.

Arduino Uno ou Mega2560 + Pololu Motor Shield

DCCpp::beginMainPololu();
DCCpp::beginProgPololu();

Ce qui là encore est strictement équivalent à :

DCCpp::beginMain(POLOLU_DIRECTION_MOTOR_CHANNEL_PIN_A, DCC_SIGNAL_PIN_MAIN, POLOLU_SIGNAL_ENABLE_PIN_MAIN, POLOLU_CURRENT_MONITOR_PIN_MAIN);
DCCpp::beginProg(POLOLU_DIRECTION_MOTOR_CHANNEL_PIN_B, DCC_SIGNAL_PIN_PROG, POLOLU_SIGNAL_ENABLE_PIN_PROG, POLOLU_CURRENT_MONITOR_PIN_PROG);

On voit que pour les shields, toutes les broches sont en dur dans le code, forcées par des constantes. Dans les cas de LMD18200, les deux dernières broches sont libres et ne sont pas imposées par le matériel. A vous de choisir ce qui convient le mieux. Il suffit de se rappeler que la broche de mesure de courant est forcément analogique !

Attention aux deux premières broches sur des circuits AVR (Uno, Mega, Leonardo, Micro, Mini...) : sur ces micro-contrôleurs seules quelques broches sont capables d’être pilotées par des interruptions. Et c’est ce que fait DCC++/DCCpp. Donc si vous choisissez de changer ces broches pour d’autres, assurez vous qu’elles soient capables de ça ! La consultation du datasheet de l’Arduino, ou plus simplement des articles dédiés aux interruptions sur Locoduino est fortement conseillée..

Pour terminer l’examen du code de l’exemple, la fonction loop ne fait que lancer le loop de DCCpp !

Si tout va bien et que vous êtes branchés correctement, alors les ordres saisis en texte dans la console de l’IDE sont transmis à l’Arduino, qui les transmet à DCC++, qui les transforme en signal DCC, qui est lu par un décodeur de loco qui fait ce qu’on lui dit. Ouf !

Exemple Ethernet

/*************************************************************
project: <Dc/Dcc Controller>
author: <Thierry PARIS>
description: <Dcc Ethernet Controller sample>
*************************************************************/

#include "DCCpp.h"

#if !defined(USE_TEXTCOMMAND) || !defined(USE_ETHERNET)
#error To be able to compile this sample,the lines #define USE_TEXTCOMMAND and #define USE_ETHERNET must be uncommented in DCCpp.h
#endif

// the media access control (ethernet hardware) address for the shield:
uint8_t mac[] = { 0xBE, 0xEF, 0xBE, 0xEF, 0xBE, 0xEF };
//the IP address for the shield:
uint8_t ip[] = { 192, 168, 1, 200 };

EthernetServer DCCPP_INTERFACE(2560);                  // Create and instance of an EthernetServer

void setup()
{
	Serial.begin(115200);

	DCCpp::begin();
  // Configuration for my LMD18200. See the page 'Configuration lines' in the documentation for other samples.
#if defined(ARDUINO_ARCH_ESP32)
  DCCpp::beginMain(UNDEFINED_PIN, 33, 32, 36);
#else
	DCCpp::beginMain(UNDEFINED_PIN, DCC_SIGNAL_PIN_MAIN, 3, A0);
#endif
	DCCpp::beginEthernet(mac, ip, EthernetProtocol::TCP);
}

void loop()
{
	DCCpp::loop();
}

Par rapport à l’exemple par la liaison série la différence réside dans le beginEthernet qui réclame des arguments classiques pour une liaison réseau : adresse MAC de l’appareil (six octets : notez le texte que représente les valeurs : BEEF BEEF BEEF ! C’est juste pour le fun...), et adresse Ip (quatre octets en IPv4) du serveur. Le port du serveur (ici 2560, comme le Méga !) est quant à lui fixé par la déclaration du serveur elle-même au début du source :

// Serveur de l'Arduino, avec un numéro de port.
EthernetServer DCCPP_INTERFACE(2560);

Pour que ce code puisse compiler, il faut quand même modifier DCCpp.h dans le répertoire de la bibliothèque et activer la bonne interface réseau :

/**Comment this line to avoid using and compiling Ethernet shield using Wiznet 5100 chip.*/
//#define USE_ETHERNET_WIZNET_5100
/**Comment this line to avoid using and compiling Ethernet shield using Wiznet 5500 chip.*/
//#define USE_ETHERNET_WIZNET_5500
/**Comment this line to avoid using and compiling Ethernet shield using Wiznet 5200 chip.*/
//#define USE_ETHERNET_WIZNET_5200
/**Comment this line to avoid using and compiling Ethernet shield using ENC28J60 chip.*/
#define USE_ETHERNET_ENC28J60

Dans mon cas, c’est la dernière interface, celle pour un shield ou un circuit équipé d’un ENC28J60. N’oubliez pas qu’il faut aussi décommenter la ligne #define USE_TEXTCOMMAND un peu plus tôt dans ce même fichier, parce que l’interface Ethernet ne fonctionne qu’à travers des commandes texte.

Exemple MiniDcc
Le but de cet exemple est de se passer de liaison série ou Ethernet, et d’utiliser de vrais boutons physiques. Comme d’habitude, c’est Commanders qui s’y colle :

/*************************************************************
project: <Dc/Dcc Controller>
author: <Thierry PARIS>
description: <Minimalist Dcc Controller sample>
*************************************************************/

#include "Commanders.h"

#include "DCCpp.h"

#define EVENT_NONE    0
#define EVENT_MORE    1
#define EVENT_LESS    2
#define EVENT_SELECT  3
#define EVENT_CANCEL  4
#define EVENT_MOVE    5
#define EVENT_START   6
#define EVENT_END   7
#define EVENT_EMERGENCY 8
#define EVENT_FUNCTION0 9
#define EVENT_FUNCTION1 10
#define EVENT_ENCODER 11

ButtonsCommanderPush buttonSelect;
ButtonsCommanderEncoder buttonEncoder;
ButtonsCommanderPush buttonCancel;
ButtonsCommanderPush buttonEmergency;
ButtonsCommanderSwitchOnePin buttonF0;
ButtonsCommanderSwitchOnePin buttonF1;

// in this sample, only one loco is driven...
int locoId; // DCC id for this loco
int locoStepsNumber;  // 14, 28 or 128
int locoSpeed;  // Current speed
bool locoDirectionForward;  // current direction.
FunctionsState locoFunctions; // Current functions

void setup()
{
  Serial.begin(115200);

  buttonSelect.begin(EVENT_SELECT, A0);
  buttonEncoder.begin(EVENT_ENCODER, 14, 8, 2);
  buttonCancel.begin(EVENT_CANCEL, A3);
  buttonEmergency.begin(EVENT_EMERGENCY, A4);
#if defined(ARDUINO_ARCH_ESP32)
  buttonF0.begin(EVENT_FUNCTION0, A5);
  buttonF1.begin(EVENT_FUNCTION1, A6);
#else
  buttonF0.begin(EVENT_FUNCTION0, A1);
  buttonF1.begin(EVENT_FUNCTION1, A2);
#endif

  DCCpp::begin();
  // Configuration for my LMD18200. See the page 'Configuration lines' in the documentation for other samples.
#if defined(ARDUINO_ARCH_ESP32)
  DCCpp::beginMain(UNDEFINED_PIN, 33, 32, 36);
#else
  DCCpp::beginMain(UNDEFINED_PIN, DCC_SIGNAL_PIN_MAIN, 11, A5);
#endif

  locoId = 3;
  locoStepsNumber = 128;
  locoSpeed = 0;
  locoDirectionForward = true;
  //locoFunctions.Clear();  // Already done by the constructor...
}

void loop()
{
  DCCpp::loop();
  unsigned long event = Commanders::loop();

  switch (event)
  {
  case EVENT_ENCODER:
  {
    int data = Commanders::GetLastEventData();

    if (data > 0)
    {
      if (locoStepsNumber >= 100)
        locoSpeed += 10;
      else
        locoSpeed++;
      if (locoSpeed > locoStepsNumber)
        locoSpeed = locoStepsNumber;
      DCCpp::setSpeedMain(1, locoId, locoStepsNumber, locoSpeed, locoDirectionForward);
    }
    if (data < 0)
    {
      if (locoStepsNumber >= 100)
        locoSpeed -= 10;
      else
        locoSpeed--;
      if (locoSpeed < 0)
        locoSpeed = 0;
      DCCpp::setSpeedMain(1, locoId, locoStepsNumber, locoSpeed, locoDirectionForward);
    }
    break;
  }

  case EVENT_FUNCTION0:
    if (locoFunctions.isActivated(0))
      locoFunctions.inactivate(0);
    else
      locoFunctions.activate(0);
    DCCpp::setFunctionsMain(2, locoId, locoFunctions);
    break;

  case EVENT_FUNCTION1:
    if (locoFunctions.isActivated(1))
      locoFunctions.inactivate(1);
    else
      locoFunctions.activate(1);
    DCCpp::setFunctionsMain(2, locoId, locoFunctions);
    break;
  }
}

La déclaration, puis la configuration des différents boutons correspond à ce qui est décrit dans l’article sur Commanders, je ne reviens pas dessus. La partie intéressante pour nous est à deux endroits : DCCpp.h qui a certainement vu commenté sa ligne #define USE_TEXTCOMMAND puisque l’interface texte ne sera pas utilisée ici, et le grand switch de loop dans lequel chaque changement important provoqué par les boutons (vitesse, fonctions...) donne lieu à un appel direct d’une fonction de la classe DCCpp.
Comme expliqué plus haut, activer ou désactiver une fonction nécessite de renvoyer en DCC l’état de toutes les fonctions du même ensemble ! Le code associé à EVENT_FUNCTION0 et EVENT_FUNCTION1 (lignes 103 à 117) montre comment procéder dans DCCpp. Lorsqu’une fonction doit changer d’état, on informe la classe locoFunctions correspondant à la loco concernée de son activation (activate) ou pas (inactivate), puis on demande à cette classe d’envoyer l’ordre DCC correspondant avec setFunctionsMain(). En argument, le numéro de registre pour les fonctions de cette loco, son adresse DCC, et la classe que l’on va interroger pour savoir à l’instant ’t’ quels sont les fonctions activées et en déduire quel(s) ensemble(s) et quels octets sont à envoyer sur les rails.

Exemple étendu aux classes annexes

/*************************************************************
project: <Dc/Dcc Controller>
author: <Thierry PARIS>
description: <Dcc++ Controller sample with all options>
*************************************************************/

#include "Commanders.h"

#include "DCCpp.h"

#define EVENT_NONE		0
#define EVENT_MORE		1
#define EVENT_LESS		2
#define EVENT_SELECT	3
#define EVENT_CANCEL	4
#define EVENT_MOVE		5
#define EVENT_START		6
#define EVENT_END		7
#define EVENT_EMERGENCY	8
#define EVENT_FUNCTION0	9
#define EVENT_FUNCTION1	10
#define EVENT_ENCODER	11

#define EVENT_TURNOUT1	20
#define EVENT_TURNOUT2	21

ButtonsCommanderPush buttonSelect;
ButtonsCommanderEncoder buttonEncoder;
ButtonsCommanderPush buttonCancel;
ButtonsCommanderPush buttonEmergency;
ButtonsCommanderSwitchOnePin buttonF0;
ButtonsCommanderSwitchOnePin buttonF1;
ButtonsCommanderSwitchOnePin buttonTurnout1;
ButtonsCommanderSwitchOnePin buttonTurnout2;

// in this sample, only one loco is driven...
int locoId;	// DCC id for this loco
int locoStepsNumber;	// 14, 28 or 128
int locoSpeed;	// Current speed
bool locoDirectionForward;	// current direction.
FunctionsState locoFunctions;	// Current functions

Turnout turn1, turn2;
Output output1, output2;
Sensor sensor1, sensor2;

void setup()
{
	Serial.begin(115200);

	buttonSelect.begin(EVENT_SELECT, A0);
	buttonEncoder.begin(EVENT_ENCODER, 14, 8, 2);
	buttonCancel.begin(EVENT_CANCEL, A3);
	buttonEmergency.begin(EVENT_EMERGENCY, A4);
#if defined(ARDUINO_ARCH_ESP32)
  buttonF0.begin(EVENT_FUNCTION0, A5);
  buttonF1.begin(EVENT_FUNCTION1, A6);
#else
  buttonF0.begin(EVENT_FUNCTION0, A1);
  buttonF1.begin(EVENT_FUNCTION1, A2);
#endif
	buttonTurnout1.begin(EVENT_TURNOUT1, 30);
	buttonTurnout2.begin(EVENT_TURNOUT2, 31);

	DCCpp::begin();
  // Configuration for my LMD18200. See the page 'Configuration lines' in the documentation for other samples.
#if defined(ARDUINO_ARCH_ESP32)
  DCCpp::beginMain(UNDEFINED_PIN, 33, 32, 36);
  DCCpp::beginProg(UNDEFINED_PIN, 21, 22, 23);
#else
	DCCpp::beginMain(UNDEFINED_PIN, DCC_SIGNAL_PIN_MAIN, 11, A0);
	DCCpp::beginProg(UNDEFINED_PIN, DCC_SIGNAL_PIN_PROG, 3, A1);
#endif

	locoId = 3;
	locoStepsNumber = 128;
	locoSpeed = 0;
	locoDirectionForward = true;
	//locoFunctions.Clear();	// Already done by the constructor...

	turn1.begin(1, 100, 1);
	turn2.begin(2, 200, 2);

	output1.begin(1, 5, B110);
	output2.begin(2, 6, B110);

	sensor1.begin(1, 7, 0);
	sensor2.begin(2, 9, 1);
}

void loop()
{
	DCCpp::loop();

	// activate first output from first sensor state.
	bool active = sensor1.isActive();

	if (active != output1.isActivated())
		output1.activate(active);

	// activate second output from second sensor state.
	active = sensor2.isActive();

	if (active != output2.isActivated())
		output2.activate(active);
		
	unsigned long event = Commanders::loop();

	switch (event)
	{
	case EVENT_ENCODER:
	{
		int data = Commanders::GetLastEventData();

		if (data > 0)
		{
			if (locoStepsNumber >= 100)
				locoSpeed += 10;
			else
				locoSpeed++;
			if (locoSpeed > locoStepsNumber)
				locoSpeed = locoStepsNumber;
			DCCpp::setSpeedMain(1, locoId, locoStepsNumber, locoSpeed, locoDirectionForward);
		}
		if (data < 0)
		{
			if (locoStepsNumber >= 100)
				locoSpeed -= 10;
			else
				locoSpeed--;
			if (locoSpeed < 0)
				locoSpeed = 0;
			DCCpp::setSpeedMain(1, locoId, locoStepsNumber, locoSpeed, locoDirectionForward);
		}
	}

	case EVENT_FUNCTION0:
		if (locoFunctions.isActivated(0))
			locoFunctions.inactivate(0);
		else
			locoFunctions.activate(0);
		DCCpp::setFunctionsMain(2, locoId, locoFunctions);
		break;

	case EVENT_FUNCTION1:
		if (locoFunctions.isActivated(1))
			locoFunctions.inactivate(1);
		else
			locoFunctions.activate(1);
		DCCpp::setFunctionsMain(2, locoId, locoFunctions);
		break;

	case EVENT_TURNOUT1:
		if (turn1.isActivated())
			turn1.inactivate();
		else
			turn1.activate();
		break;

	case EVENT_TURNOUT2:
		if (turn2.isActivated())
			turn2.inactivate();
		else
			turn2.activate();
		break;		
	}
}

Parce qu’il en fallait un, un exemple d’utilisation de ces fameuses classes annexes. Pour lui, il faut activer les parties concernées dans DCCpp.h : USE_TURNOUT, USE_SENSOR et USE_OUTPUT. L’exemple est exactement identique au précédent. La seule chose qui change, ce sont les Turnout, Sensor et Output déclarés (lignes 43 à 45). En mode ligne de commande, ces objets sont créés dynamiquement en mémoire. Sans la ligne de commande, il faut les déclarer comme n’importe quel objet... Une fois déclarés, les begin (lignes 81 à 88) vont fixer les broches utilisées, et les identifiants si nécessaire. Enfin dans le loop, les fonctions de gestion (lignes 95 à 105 et 153 à 165) seront utilisées pour changer l’état des sorties (activate, inactivate...) ou tester les entrées (isActivated, isActive).

Exemple de test

Un exemple Autotest est aussi présent. Il permet de vérifier que la centrale marche bien, en tout cas en mode texte. Il faudra peut être changer dans le code des commandes l’adresse DCC fixée à 3 par défaut. Ensuite placez une loco configurée à cette adresse sur la voie et lancez l’Arduino. La loco décrira une petite séquence avant/arrière/clignotement des feux qui peut être modifiée à loisir.

Où ça se passe...

La bibliothèque est disponible sur la forge Locoduino.

Notez que dans le répertoire ’extras/Doc’ se trouve une documentation html visible sur n’importe quel système avec n’importe quel navigateur un peu moderne. Cette documentation reprend en Anglais l’ensemble des informations données ici et détaille plus précisément les rôles des classes, des fonctions et de leurs arguments. Sous Windows pour la lancer, il suffit de double cliquer sur le fichier StartDoc.bat présent dans le répertoire de la bibliothèque, sinon il faut manuellement double-cliquer sur le fichier ’extras/Doc/index.html’ . La page ’Revision History’ donne la liste des versions et les changements apportés en français et en anglais !

La bibliothèque DCCpp est destinée à remplacer tous les usages des sources de DCC++ dans vos projets. Elle est bien plus configurable que son originale, et possède un peu plus de fonctionnalités. De plus, bien configurée elle devrait dans certains usages prendre beaucoup moins de mémoire. Vous gagnerez au change !

Article mis à jour le 10/11/2020

99 Messages

  • Bibliothèque DCCpp 26 décembre 2017 10:25, par bagou91

    Merci pour cet article et la présentation de cette bibliothèque.
    Après lecture, j’ai l’impression que cela va être bien plus simple à utiliser pour se concevoir un circuit avec quelques accessoires et locos.
    Jusqu’à présent j’ai essayé plusieurs bibliothèques proposées : d’un coté les accessoires, d’un autre le contrôle des locos, mais sans vraiment pouvoir tout réunir.
    Avec cette bibliothèque, je crois que c’est chose faite :
    Les quelques exemples donnés montrent la gestion d’accessoires en même temps que le contrôle des locos.

    Plus qu’à mettre en pratique :)

    Répondre

  • Bibliothèque DCCpp 31 décembre 2017 18:35, par BobyAndCo

    Ma petite contribution à ce formidable travail. J’ai pu tester la bibliothèque de Thierry en mode TEXTCOMMAND, en Ethernet avec le LMD18200 et aussi le POLOLU MC33926 Motor shield.

     

    Je n’ai rencontré aucun problème, que ce soit en pilotage sur la voie Main ou en programmation, sur la voie Prog avec l’une et l’autre des cartes moteur.

     

    Il ne faut pas oublier de modifier le fichier DCCpp comme cela est indiqué dans l’article (lignes 310 et 312 à décommenter)

    /**Comment this line to avoid using and compiling Serial commands.*/
    #define USE_TEXTCOMMAND
    /**Comment this line to avoid using and compiling Ethernet shield using Wiznet 5100 chip (Arduino Shield v1).*/
    #define USE_ETHERNET_WIZNET_5100

     

    mais vous serrez rapidement rappelé à l’ordre en cas d’oubli au moment où vous chercherez à téléverser le programme sur l’Arduino.

     

    Pour cela, dans le menu Exemples de l’IDE d’Arduino, on choisit EthernetDCC. Si vous utilisez un LMD18200, vous n’aurez rien à modifier, sauf une petite erreur qui est juste dans l’exemple (pas dans l’article). Sur la voie Main, la broche pour le PWM est la 3 et non la 11 (la 11 étant celle de la voie Prog)

     

    Voici le code modifié et complété :

     

    // Configuration for my LMD18200. See the page 'Configuration lines' in the documentation for other samples.
    DCCpp::beginMain(UNDEFINED_PIN, DCC_SIGNAL_PIN_MAIN, 3, A0);
    DCCpp::beginProg(UNDEFINED_PIN, DCC_SIGNAL_PIN_PROG, 11, A1);

    En cas d’utilisation d’un Pololu, le code à ajouter est celui-ci :

     

    // Configuration for my POLOLU MC33926 Motor shield.
    DCCpp::beginMain(POLOLU_DIRECTION_MOTOR_CHANNEL_PIN_A, DCC_SIGNAL_PIN_MAIN, POLOLU_SIGNAL_ENABLE_PIN_MAIN, POLOLU_CURRENT_MONITOR_PIN_MAIN);
    DCCpp::beginProg(POLOLU_DIRECTION_MOTOR_CHANNEL_PIN_B, DCC_SIGNAL_PIN_PROG, POLOLU_SIGNAL_ENABLE_PIN_PROG, POLOLU_CURRENT_MONITOR_PIN_PROG);

     

    Bravo encore.

     

    Christophe

    Répondre

  • Bibliothèque DCCpp 2 janvier 2018 11:13, par DDEFF

    Magnifique travail !

    Je n’ai malheureusement pas encore de réseau, mais il est évident qu’il sera commandé avec cette bibliothèque.
    .
    Pour l’avoir découvert la première fois, j’avais bien saisi le potentiel de l’appli de Greg, qui mêlait le C++ pour l’Arduino et Processing pour l’interface de commande des trains.
    .
    L’interface Processing était efficace, mais uniquement adaptée à son réseau, vraiment spécifique. L’adapter à un autre réseau est complexe.
    Mais elle permet d’envoyer à l’Arduino des commandes simples qui respectent parfaitement les normes DCC.
    Il s’ensuit qu’on peut déconnecter la partie Arduino et la partie Processing. C’est ce qui a déjà été fait dans les très bons articles de Dominique et Christophe qui ajoutent chacun une fonctionnalité.
    .
    Tu ajoutes une idée force supplémentaire en créant une bibliothèque qui permet de ne plus se soucier d’avoir à intervenir directement dans le programme.
    .
    Un grand bravo !

    Répondre

  • Bibliothèque DCCpp 2 janvier 2018 21:57, par Thierry

    Merci pour votre soutien. Il reste des pistes d’amélioration, comme la disponibilité pour un ESP32, un ESP8266 ou un STM32. Et puis l’accès aux commandes via Wifi... Encore du boulot !

    Répondre

  • Bibliothèque DCCpp installation 5 janvier 2018 00:40, par Rob1

    Une petite question de débutant pour enfin m’associer aux remerciements et félicitations.
    Les sources à utiliser sont-elles celles que l’on trouve dans
    Biblios et Logiciels DCC + BaseStation-master + DCCpp_Uno
    J’hésite car il n’y a pas DCCpp.h Si oui doit-on le créer au même niveau que DCCpp_UnoRob1.ino ?
    Peut-être ai-je raté un lien dans l’article.

    Merci d’avance pour votre aide

    Répondre

  • Bibliothèque DCCpp 6 février 2018 18:52, par pat95

    Bonjour, bravo pour le travail réalisé je m’associe aux félicitations.
    Je n’arrive pas à faire fonctionner la nouvelle bibliothèque avec mon ancien dossier DCC_Ethernet de BobyAnco !!
    j’ai réussi avec la liaison SERIAl mais rien avec l’exemple ethernet. Est-ce le dossier HTML sur la carte SD qui bloque ? Faut-il reprogrammer un nouveau fichier HTML ? Merci d’avance pour votre aide.

    Répondre

  • Bibliothèque DCCpp 6 février 2018 20:40

    Bonjour et merci.

    Avez vous fait ce qu’il faut dans DCCpp pour gérer une liaison Ethernet, c’est à dire activé USE_TEXTCOMMAND et l’un des shields réseau avec USE_ETHERNET_* ?
    Quel fichier ino employez vous ?

    Le fichier HTML n’y est pour rien, il s’agit beaucoup plus probablement d’une absence de connexion au réseau...

    Répondre

    • Bibliothèque DCCpp 7 février 2018 13:12, par pat95

      Bonjour,
      j’ai fait fonctionné l’exemple SerialDcc sans problème. Je crois que mon problème est de lire sur la carte SD le fichier "control.htm" fichier en HTML. Comment faire ?. Je cherche...

      Répondre

  • Bibliothèque DCCpp 7 février 2018 14:07, par pat95

    Bonjour,
    j’ai testé l’exemple serialDcc sans problème. J’ai ensuite chargé l’exemple EthernetDcc, modifié mac[], activé #define USE_TEXTCOMMAND, sélectionné #define USE_ETHERNET_WIZNET_5500 (arduino.org, ethernet2), modifié DCCpp::beginMain(UNDEFINED_PIN, DCC_SIGNAL_PIN_MAIN, 3, A0) ;. Et rien... Rien sur la console pas même la connexion ethernet !!. Je continue à chercher.

    Répondre

  • Bibliothèque DCCpp 26 février 2018 17:10, par Didier44

    Je découvre seulement tes bibliothèques, occupé par ailleurs par la construction de mon réseau. Un seul mot : bravo. Je viens d’essayer ton exemple Autotest et ton mini "programmateur" me donne bien des idées.

    Répondre

  • Bibliothèque DCCpp 3 mars 2018 13:27, par Jocelyn DAVID

    Bonjour, je viens de télécharger la dernière version DCCpp-1.1.0 et je ne suis pas capable d’afficher le fichier DCCpp.h pour le modifier. Je suis allé voir sur le forum sans trouver l’astuce. Soit je suis (assez ?) nul, soit c’est bien caché. Merci pour votre retour

    Répondre

  • Bibliothèque DCCpp 3 mars 2018 15:44, par Thierry

    Bonjour

    Si vous avez installé correctement la bibliothèque comme expliqué dans l’article Installer une bibliothèque , vous avez un répertoire ’Libraries/DCCpp/src’ à côté de vos croquis Arduino (dans ’Mes documents/Arduino’ sous Windows) . Vous y trouverez le fichier en question. Si vous n’avez que téléchargé le fichier zip, il vous faut installer la bibliothèque.

    Répondre

    • Bibliothèque DCCpp 3 mars 2018 16:58, par Jocelyn DAVID

      Merci, Thierry. J’ai effectivement trouvé après coup le fichier dans le sous-répertoire "src". L’aventure continue ... Pas facile de se remettre à niveau après 20 ans d’interruption (sans jeu de mots)... aha

      Répondre

  • Bibliothèque DCCpp 6 mars 2018 11:17, par Jocelyn DAVID

    Bonjour à tous les lecteurs. Ma quête laborieuse se poursuit. J’ai quelques questions complémentaires. J’ai fait l’acquisition de 2 locos "N" Bachmann avec "DCC on board". Jusque là, pas de soucis (sauf si quelqu’un a rencontré des problèmes avec ce matériel ?). Par défaut, l’adresse du décodeur est "3". En faisant fonctionner mon Arduino Uno + LMD18200 + MAX471 avec une seule loco sur la voie principale et avec la bibliothèque CmdrArduino, aucun problème. J’ai donc testé la bibliothèque DCCpp ... puis DCC++ BaseStation, rien ne va plus. Par exemple, le mode TEXTE ne produit aucune réaction. Est-ce que quelqu’un a une idée du problème ? merci pour votre retour.

    Répondre

    • Bibliothèque DCCpp 6 mars 2018 12:02, par Thierry

      Bonjour

      Qu’entends-tu par ’mode TEXTE’ ? si c’est l’utilisation de la console pour envoyer des commande, il suffit de l’activer dans DCCpp (maintenant que tu as trouvé le fichier :) ) en retirant la remarque devant #define USE_TEXTCOMMAND.

      Répondre

  • Bibliothèque DCCpp 7 mars 2018 21:00, par Guillaume45

    Tout d’abord un très grand merci pour tout ce travail magnifique que vous nous donner et vraiment bravo !!!
    J’ai rencontré un petit problème avec la bibliothèque DCCpp et la dernière version de l’ide arduino.
    erreur de compilation #include "arduino.h" manquant.
    j’ai réussi à résoudre ce problème en remplaçant "arduino.h" par "Arduino.h" dans le fichier source DCCpp.cpp et Config.h .

    Je cherche à commander mes trains en utilisant la fonction DCCpp::setSpeedMain(......)
    A quoi le paramètre nreg ou registre et comment faire pour piloter plusieurs locomotive simultanément ?
    Lorsque l’on ne veut plus commander une loc, existe -t-il une fonction pour faire un raz ?

    Merci pour votre aide
    Guillaume

    Répondre

  • Bibliothèque DCCpp 8 mars 2018 09:34, par Thierry.

    Bonjour et merci :)

    Je vais corriger les includes et pousser une nouvelle version. Le problème vient de mon Windows qui n’est pas sensible à la casse des noms de fichiers. Alors quand c’est compilé sur un MacOs ou un Linux, il peut y avoir des problèmes que je n’ai pas vu...
    Comme je l’explique dans la doc livrée avec la bibliothèque (sous Windows lancer startdoc.bat du répertoire de la bibliothèque, sinon lancer le fichier html DCCpp\extras\Doc\index.html dans un navigateur), chaque registre est un canal de commande DCC. Conformément à la norme, les ordres DCC doivent être répétés à l’infini pour qu’une loco qui perd le contact électrique avec la voie pendant une milliseconde retrouve sa consigne dès que le contact est rétabli. Chaque registre contient donc un ordre à répéter. On peut jongler avec les onze registres en répétant onze ordres pour la même loco, ou en pilotant onze locos, ou en mixant les deux...
    Et non, il n’y a pas de Raz dans DCCpp, mais des commandes similaires existent dans la norme DCC.

    Répondre

  • Bibliothèque DCCpp 2 avril 2018 09:03, par Guillaume45

    Bonjour,
    J’apprends à utiliser votre bibliothèque depuis quelques semaines, et je ne rencontre aucune difficulté pour la commande des locomotives.
    Par contre pour la lecture des CV sur voie de prog, c’est un peu plus compliqué.
    la fonction "identifyLocoIdProg" me donne bien la bonne valeur.
    l’écriture cv prog à bien fonctionné aussi ( j’ai juste reprogrammé l’adresse)
    mais la lecture cv "readCvProg" me retourne toujours -1.
    y a t’il une particularité pour l’utilisation de cette fonction ?
    (pour info j’utilise 2 lmd18200 avec max471)

    Merci pour votre aide
    Guillaume

    Répondre

  • Bibliothèque DCCpp 2 avril 2018 10:05, par Thierry

    Bonjour

    Content de voir que ça marche ! Pour la lecture des CVs, il y a un petite incohérence dans mon code qui fait que la lecture de l’adresse ne peut fonctionner que sur la voie principale, tandis que la lecture de CV peut se faire sur les deux voies...
    Si votre décodeur est sur la voie principale, cela peut expliquer le fonctionnement que vous décrivez. L’adresse est bien lue, mais readCvProg ne peut pas fonctionner... Si votre loco avait été sur la voie de programmation, la lecture de l’adresse aurait échoué, mais la lecture des CV aurait réussi !
    Je ferais très bientôt une nouvelle version corrigeant ce disfonctionnement...

    Thierry.

    Répondre

  • Bibliothèque DCCpp 28 novembre 2018 18:22, par engi

    bonjour

    j ai lu plusieurs fois l article, mais quelquechose m echappe.
    je ne trouve pas le fichier INO ou PDE.
    merci de m eclairer.

    Répondre

    • Bibliothèque DCCpp 28 novembre 2018 18:48, par Dominique

      C’est normal, c’est une bibliothèque : Une bibliothèque est un ensemble de fonctions qui s’ajoutent aux fonctions de base du logiciel de l’Arduino.

      Donc le .ino est dans votre programme, pas dans le bibliothèque.
      Lisez donc Installer une bibliothèque

      Répondre

    • Bibliothèque DCCpp 29 novembre 2018 09:13, par Thierry

      Comme le dit Dominique, c’est une bibliothèque, donc dans les exemples se trouvent des ... exemples, donc des fichiers ino permettant de se servir de DCCpp.

      Bonne programmation !

      Répondre

  • Bibliothèque DCCpp 26 janvier 2019 17:29, par Philippe38

    Bonjour Thierry,
    J’utilise la bibio DCCpp avec succès depuis +6 mois. Je la commande à partir d’un GUI/IHM écrit en JavaScript avec node.js. J’ai relu la doc mais je vois pas comment programmer des CV dans les décodeurs d’accessoires en dehors de la voie de programmation. Je souhaiterai programmer en POM comme pour les décodeurs de loco. Il me semble qu’il manque une commande pour y arriver ? Tout ça pour un bit : loco ou accessoire.
    Ferroviairement, Philippe38

    Répondre

    • Bibliothèque DCCpp 1er février 2019 15:54, par Thierry

      Bonjour Philippe,

      De quel bit parles tu ? Je ne le retrouve pas dans le document NMRA sur la norme DCC...

      Répondre

      • Bibliothèque DCCpp 1er février 2019 18:20, par Philippe38

        Bonjour Thierry,
        J’explique en détail : je souhaiterai programmer les CV de mes modules accessoires en POM. Mais l’adresse des accessoires (1..2048) est la même que celles des locos (1..10240). La différence d’adressage entre loco et accessoire est gérée en interne par DCCpp avec le début de l’octet 1 de la trame DCC : 0x.. = loco adresse courte, 11.. = loco adresse longue, 10.. = accessoire. Ca tient à un bit qui fait la différence.
        Comment programmer un accessoire en POM ? Il manque une commande dans TextCommand.h me semble-t-il. Est que c’est envisageable de rajouter une commande ? "A" est libre par exemple. J’ai regardé le code en profondeur mais cela ne parait pas très simple...
        Merci pour la bibliothèque, un sacré boulot.
        Ferroviairement, Philippe38

        Répondre

  • Bibliothèque DCCpp 2 février 2019 13:35, par Thierry

    Je pourrais faire les fonctions en question, mais je ne pourrais pas tester, et en particulier je ne pourrais pas tester la partie remontée d’information via une consommation ponctuelle comme le prévoit le protocole DCC, en tout cas pour les décodeurs de machine...

    Répondre

    • Bibliothèque DCCpp 2 février 2019 23:53, par Philippe38

      Bonsoir Thierry,
      mes décodeurs d’accessoires (de Paco et Arduino) ne permettent pas la lecture des CV comme beaucoup d’autres, que ce soit en POM ou en voie de programmation. D’ailleurs on ne peut relire les locos que sur la voie de programmation, donc il faut s’en contenter. Pour le test, utilisons un analyseur de trame sur Arduino qui monitore tout ce qui passe en DCC. La fonction programmation des CV accessoires en POM reste intéressante si cela ne demande pas un trop gros effort d’écriture. On pourrait se limiter de 512 accessoires pour simplifier. Voir la page Internet de mon ami Michel. Par comparaison avec une trame loco, dans la trame 6 octets pour 512 accessoires, un bit change dans l’octet 1 et seul l’octet 2 est différent, les autres sont identiques. Par contre je ne connais pas la trame 2048 accessoires.
      Ferroviairement, Philippe38

      Voir en ligne : PROGRAMMATION de 510 DÉCODEURS

      Répondre

  • Bibliothèque DCCpp 13 mars 2019 14:54, par dlal

    Bonjour à tous,
    J ai juste commencé à utiliser cette bibliothèque, avec le premier example autotest, tout était comme prévu. Dans le seconde example, minidcc, je reçois erreur 1 durant la compilation carte mega’.La seule chose sue j ai changé était l adresse de la loco, 13 au lieu de 3.....
    Merci pour votre réponses

    Répondre

  • Bibliothèque DCCpp 13 mars 2019 15:33, par Thierry

    Bonjour

    Pouvez vous préciser la nature de l’erreur ? Pendant la compilation, ou l’envoi vers le Mega ? A quelle ligne ? Tout ça est dit dans la fenêtre du bas de l’IDE... Sinon je ne peux pas faire grand chose avec juste un ’Ça marche pas !’...

    Répondre

  • Bibliothèque DCCpp 13 mars 2019 16:00, par dlal

    Bonjour Thierry, merci pour votre réponse. L erreur apparaît pendant la premiere phase de vérification ( notée par v sur arduino).le message exact que je reçois est apparu à la fenetre en bas, est exit status 1, erreur pendant la compilation pour la carte arduino mega.
    Merci pour encore une fois.
    Denis

    Répondre

    • Bibliothèque DCCpp 13 mars 2019 17:26, par Jean-Luc

      Les informations pertinentes sont autour de ce exit status 1. Pouvez vous copier-coller tout ce qui est affiché en rouge en cliquant sur le bouton « Recopier les messages d’erreur » ?

      Répondre

    • Bibliothèque DCCpp 13 mars 2019 17:31, par Thierry

      Ce que vous me dites ne me sert à rien, c’est tout le reste du texte qui est utile.... Bref si vous compilez comme je le crois, vous devez avoir un texte qui ressemble à

      Arduino : 1.8.7 (Windows 10), Carte : "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

      MiniDcc:7:24 : error : Commanders.h : No such file or directory

      compilation terminated.

      exit status 1
      Commanders.h : No such file or directory

      "No such file or directory" signifie qu’il vous manque un fichier, ici Commanders.h, ce qui est probablement le cas si vous n’avez pas installé la bibliothèque Commanders utilisée dans cet exemple. C’est ce que je dis dans l’article associé à DCCpp que je vous enjoins de lire attentivement.

      Répondre

  • Bibliothèque DCCpp 13 mars 2019 17:34, par dlal

    Bonsoir Thierry,
    Voila ce que je recoie,
    merci ,
    Denis
    Arduino:1.8.8 (Windows 10), Scheda :"Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

    In file included from C :\Users\anton\Documents\Arduino\MiniDcc\MiniDcc.ino:7:0 :

    C :\Users\anton\Documents\Arduino\libraries\Commanders\src/Commanders.h:470:18 : fatal error : DIO2.h : No such file or directory

    compilation terminated.

    exit status 1
    Errore durante la compilazione per la scheda Arduino/Genuino Mega or Mega 2560.

    Questo report potrebbe essere più ricco di informazioni abilitando l’opzione
    "Mostra un output dettagliato durante la compilazione"
    in "File -> Impostazioni"

    Répondre

  • Bibliothèque DCCpp 13 mars 2019 17:41, par dlal

    merci Thierry,resolu il manque DIO2
    Denis

    Répondre

  • Bibliothèque DCCpp 24 avril 2019 22:28, par Philippe38

    Hi Trusty,
    Tu as laissé trainer 2 fichiers de chez Atani dans DCCpp.zip. Ils n’ont rien à faire là, je croyais que j’avais déplacé ces fichiers par erreur mais ils sont bien dans ton zip. Est ce qu’il est envisageable de séparer la gestion du courant entre Main et Prog pour éviter de couper inutilement la voie de programmation en cas de court-circuit sur Main ? Dans le même esprit, je souhaiterai ajouter 3 boosters contrôlés indépendamment mais je n’ose pas modifier le soft parce je ne le connais pas assez bien. Et il me faudrait le modifier à chaque release.
    Ferroviairement, Philippe38

    Répondre

    • Bibliothèque DCCpp 4 juin 2019 18:02, par Thierry

      Tu as raison pour les deux fichiers, mais je dois m’attaquer à la version ESP32 incessamment, je vais les laisser en attendant. J’ai ajouté des arguments à powerOn() et powerOff() pour couper/restaurer le courant sur les deux voies séparément. Mais en fait c’est une vraie gestion de boosters qu’il faudrait, avec une classe dédiée qui s’occuperai de la gestion du courant. En attendant, j’ai fait une version spécifique de la classe CurrentMonitor pour mieux gérer les court-circuits indépendamment. Cette version permettrai aussi d’ajouter des moniteurs sur chaque booster :

      /**********************************************************************
      
      CurrentMonitor.h
      COPYRIGHT (c) 2013-2016 Gregg E. Berman
      
      Part of DCC   BASE STATION for the Arduino
      
      **********************************************************************/
      
      #ifdef ARDUINO_ARCH_AVR
      #ifndef CurrentMonitor_h
      #define CurrentMonitor_h
      
      /** Factor to smooth the result...*/
      #define  CURRENT_SAMPLE_SMOOTHING   0.01
      
      /** Time between two measurements.
      @remark Millis() uses TIMER-0.  For UNO, we change the scale on Timer-0.  For MEGA we do not.  This means CURRENT_SAMPLE_TIME is different for UNO then MEGA.
      */
      #if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_NANO)      // Configuration for UNO
      	#define  CURRENT_SAMPLE_TIME        10
      #else                                         // Configuration for MEGA    
      	#define  CURRENT_SAMPLE_TIME        1
      #endif
      
      /** This structure/class describes a current monitor.*/
      
      struct CurrentMonitor{
        static long int sampleTime; /**< time elapsed since last measurement. This delay is common to all monitors. */
      	int pin;	/**< Attached check pin.*/
      	int signalPin;	/**< signal pin.*/
        float currentSampleMax;	/**< Value of the maximum current accepted without problem.*/
        float current; /**< Value of the last measured current.*/
        const char *msg;	/**< Message to send when excessive current is measured.*/
        /** begin function.
      	@param pin	Attached pin. UNEFINED_PIN to inactivate this monitor.
      	@param inSignalPin	Pin to set LOW if a shortcut is detectexd.
        @param msg	Message to send to console when a smoothed current value greater than maximum is detected.
        @param inSampleMax	Maximum value of the current. Default is 300.
        */
        void begin(int pin, int inSignalPin, const char *msg, float inSampleMax = 300);
        /** Checks if sufficient time has elapsed since last update. Common to all monitors.
        */
        static boolean checkTime();
        /** Checks the current on this monitor.
        */
        void check();
      };
      
      #endif
      #endif

      Noter le signalPin apparu dans la classe et le begin(), qui correspond à la broche à mettre à LOW si un problème intervient. Et

      /**********************************************************************
      
      CurrentMonitor.cpp
      COPYRIGHT (c) 2013-2016 Gregg E. Berman
      
      Part of DCC   BASE STATION for the Arduino
      
      **********************************************************************/
      
      #include "Arduino.h"
      
      #ifdef ARDUINO_ARCH_AVR
      
      #include "DCCpp_Uno.h"
      #include "CurrentMonitor.h"
      #include "Comm.h"
      
      ///////////////////////////////////////////////////////////////////////////////
      
      void CurrentMonitor::begin(int pin, int inSignalPin, const char *msg, float inSampleMax)
      {
      	this->pin = pin;
      	this->signalPin = inSignalPin;
      	this->msg = msg;
      	this->current = 0;
      	this->currentSampleMax = inSampleMax;
      } // CurrentMonitor::begin
        
      boolean CurrentMonitor::checkTime()
      {
      	if(millis( ) - sampleTime < CURRENT_SAMPLE_TIME)            // no need to check current yet
      		return(false);
      	sampleTime = millis();                                   // note millis() uses TIMER-0.  For UNO, we change the scale on Timer-0.  For MEGA we do not.  This means CURENT_SAMPLE_TIME is different for UNO then MEGA
      	return(true);  
      } // CurrentMonitor::checkTime
        
      void CurrentMonitor::check()
      {
      	if (this->pin == UNDEFINED_PIN)
      		return;
      
      	this->current = (float)(analogRead(this->pin) * CURRENT_SAMPLE_SMOOTHING   + this->current * (1.0 - CURRENT_SAMPLE_SMOOTHING));      // compute new exponentially-smoothed current
      
      	// current overload and Programming Signal is on (or could have checked Main Signal, since both are always on or off together)
      	if (this->current > this->currentSampleMax && digitalRead(this->signalPin) == HIGH)
      	{
      		digitalWrite(this->signalPin, LOW);
      		DCCPP_INTERFACE.print(this->msg);                                     // print corresponding error message
      #if !defined(USE_ETHERNET)
      		DCCPP_INTERFACE.println("");
      #endif
      	}
      } // CurrentMonitor::check  
      
      long int CurrentMonitor::sampleTime=0;
      
      #endif

      Noter la fonction check() qui utilise maintenant cette signalPin pour couper le courant. Il faut aussi modifier DCCpp.cpp pour ajouter l’argument manquant du begin.

      void DCCpp::beginMain(uint8_t inOptionalDirectionMotor, uint8_t inSignalPin, uint8_t inSignalEnable, uint8_t inCurrentMonitor)
      {
      	...
      	mainMonitor.begin(DCCppConfig::CurrentMonitorMain, DCCppConfig::SignalEnablePinMain, (char *) "<p2>");
      
      	...
      }
      
      void DCCpp::beginProg(uint8_t inOptionalDirectionMotor, uint8_t inSignalPin, uint8_t inSignalEnable, uint8_t inCurrentMonitor)
      {
      	...
      
      	progMonitor.begin(DCCppConfig::CurrentMonitorProg, DCCppConfig::SignalEnablePinProg, (char *) "<p3>");
      
      	...
      }
      
      void DCCpp::begin()
      {
      	...
      
      	mainMonitor.begin(UNDEFINED_PIN, UNDEFINED_PIN, "");
      	progMonitor.begin(UNDEFINED_PIN, UNDEFINED_PIN, "");
      
      	...
      }

      Ajouter des boosters reviendrait à ajouter de nouvelles instances de la classe avec les pins qui vont bien pour couper le courant juste chez eux si un problème survient.
      Je n’ai pas poussé ces modifications dans la bibliothèque officielle d’aujourd’hui parce que je n’ai pas pu tester. Si tu peux le faire, dis moi si ça marche...

      Répondre

  • Bibliothèque DCCpp 7 juin 2019 22:32, par Philippe38

    Bravo et bon début, ça fonctionne bien pour la voie principale qui se coupe sans action sur la voie de programmation. En cas de court-circuit sur la voie principale, elle seule est interrompue par l’Arduino.
    Cependant je n’ai pas réussi à couper le DCC en faisant un court-circuit sur la voie de programmation ! Je vais voir pourquoi.
    Maintenant vient la gestion du PowerOff() avec qui nécessite un nouveau paramètre pour couper individuellement le DCC d’une voie sans couper le DCC des autres voies. Et la même chose pour PowerOn(). C’est en pratiquant qu’on se rend compte du besoin.
    Il faut pouvoir régler l’intensité maxi admise sur chaque circuit mais on peut se satisfaire de 2 valeurs : une pour les voies principales et une pour la voie de programmation. Encore quelques changements et ça sera parfait pour pouvoir ajouter d’autres districts. Je propose de ne pas toucher P0 à P3 mais d’individualiser en ajoutant P4 et P5, et ainsi de suite. Ce serait des options neutres si inutilisées et le tout reste compatible avec ce qui existe déjà. Pour la déclaration, on a juste besoin d’une pin Enable par nouveau district. Je continue les tests.

    Répondre

  • Bibliothèque DCCpp 8 juin 2019 15:01, par Philippe38

    Dans CurrentMonitor.cpp au milieu de la ligne 42, il me semble qu’un + à disparu.

    Répondre

    • Bibliothèque DCCpp 8 juin 2019 17:15, par Thierry

      Oui, exact, mais mon code est bon. C’est l’afficheur du forum qui doit l’avoir interprété comme autre chose... En tout cas, il y a bien un ’+’, et s’il n’y est pas, il faut l’ajouter. J’ai corrigé mon post précédent.

      Répondre

  • Bibliothèque DCCpp 11 juin 2019 18:00, par Lormedy

    DCCpp intègre le bus S88 dans l’Arduino :

    Comme la rétro-signalisation manquait dans la bibliothèque DCCpp de Thierry, j’ai ajouté le code qui gère la rétro-signalisation S88 et j’ai nommé le tout : DCCpp_S88. J’ai intégré la lecture directe du simplissime bus S88 sans qu’il soit nécessaire de passer par un quelconque boitier d’interface supplémentaire. Un seul Arduino suffit pour générer le DCC, piloter les aiguillages et les feux, et maintenant lire jusqu’à 512 capteurs grâce au bus S88. Naturellement j’ai rendu cette interface logicielle du bus S88 compatible avec les logiciels libres comme CDM-Rail, CDT30, JMRI et Rocrail. Je n’ai pas testé avec d’autres logiciels mais j’ai testé 2 types de cartes de rétro-signalisation différentes.

    Cette extension offre 2 ports S88 distincts pour faciliter son utilisation avec les grands réseaux. Chaque fois qu’un capteur change d’état, les données du bus S88 sont envoyées vers le PC qui contrôle les trains. La lecture permanente en temps réel du bus S88 se fait en moins de 60ms et les données sont envoyées vers le PC en moins de 15ms par USB, sans que l’Arduino MEGA ne soit ni perturbé ni ralenti dans son fonctionnement.

    Adieu aux forêts de fils qui partent de l’Arduino, un simple câble RJ45 suffit. Les infos des capteurs sont rassemblées sur place par une carte de rétro-signalisation puis transmises par le câble RJ45 vers la carte suivante et ainsi de suite le long du réseau jusqu’à l’Arduino. Le câble RJ45 du bus S88-N télé-alimente aussi les cartes, donc pas besoin d’alimenter séparément les cartes de rétro-signalisation. Sur le bus S88-N, ce logiciel permet le mélange des cartes à 8 entrées avec celles à 16 entrées.

    Les explications et le code DCCpp_S88 pour Arduino que j’utilise se trouvent sur mon site Internet indiqué ci dessous

    Voir en ligne : Le générateur DCCpp ++ bus S88

    Répondre

  • Bibliothèque DCCpp 18 juin 2019 11:56, par Didier44

    Bonjour » Thierry,

    Je reviens vers DCCpp avec Ethernet et l’exemple EthernetDcc.ino.
    J’utilise :

    #define USE_ETHERNET_WIZNET_5100

    et

        DCCpp::beginMainMotorShield();
        DCCpp::beginProgMotorShield();

    A la compilation, j’ai cette erreur :

    ..libraries\DCCpp\src\DCCpp_Uno.h:29:27: error: 'eServer' was not declared in this scope

    #define DCCPP_INTERFACE eServer

    J’imagine que tu as développé un serveur quelque part pour tes essais.
    En remplaçant eServer par Serial cela ne passe pas non plus un peu plus loin : DCCpp.cpp ligne 345

    DCCPP_INTERFACE.begin();

    Je ne retrouve pas trace de cette fonction ?
    Si je supprime cette ligne alors RAS pour la compilation !

    Avec DCC++ j’utilise régulièrement pour mes essais une connexion Ethernet via un programme en C++ sur mon PC et tout va bien.
    Avec DCCpp mon programme me renvoie :

    Error:  "Socket operation timed out"

    Et plus rien bien sur.

    Répondre

  • Bibliothèque DCCpp 19 juin 2019 18:04, par Thierry

    Oui, c’est corrigé dans la 1.3.5 que je viens de mettre en ligne.
    Ça vient de la volonté d’utiliser une macro pour savoir à qui envoyer les messages texte. En mode normal, c’est ’Serial’ qui est utilisé, mais en configuration Ethernet, c’est une variable globale ’eServer’ déclarée dans les sources de DCCpp. Pour que cette variable soit utilisable partout, il faut la déclarer ’extern’, et c’est ce qui est fait dans comm.h . Pourtant, dans les dernières modifs qui ont vu INTERFACE être remplacé par DCCPP_INTERFACE pour un problème de compilation ESP32 (ou VisualStudio, je ne sais plus...), j’ai précisément oublié cette ligne ’extern’. D’où la variable inconnue...

    Répondre

  • Bibliothèque DCCpp 19 juin 2019 19:07, par Didier44

    Merci Thierry pour a réponse mais j’ai toujours une erreur. Je précise que j’essaie simplement de compiler ton exemple EthernetDcc.ino avec ArduinoIDE. J’ai la même erreur avec Visual Studio Code !

    ...\Temp\ccVIMcJT.ltrans0.ltrans.o : In function main': <artificial>:(.text.startup+0x330): undefined reference toeServer’

    Répondre

  • Bibliothèque DCCpp 19 juin 2019 21:03, par Thierry

    Je savais bien que j’avais oublié quelque chose, la première chose que j’ai vue, en fait !
    Dans l’exemple il faut remplacer

    EthernetServer INTERFACE(2560) ;

    par

    EthernetServer DCCPP_INTERFACE(2560) ;

    Je repousserai une version corrigée sur le Git bientôt...

    Répondre

    • Bibliothèque DCCpp 20 juin 2019 10:31, par Didier44

      Merci pour ta rapidité la compilation se fait correctement maintenant.

      Répondre

    • Bibliothèque DCCpp 20 juin 2019 23:14, par Lormedy

      Suggestion : ce serait bien de créer une constante ou un #define pour déclarer ce port dans un fichier.h global afin de pouvoir le changer facilement sans avoir à parcourir tous les fichiers à la recherche de variables disséminées dans les différents fichiers du projet. C’est valable pour toute variable de configuration.

      Répondre

      • Bibliothèque DCCpp 21 juin 2019 11:43, par Jean-Luc

        Oui,

        Ça serait intéressant de pouvoir paramétrer une bibliothèque de cette façon. Malheureusement, et sauf erreur de ma part, lors de la compilation d’une bibliothèque, le répertoire du sketch n’est pas dans les chemins d’inclusion. Il y a d’ailleurs une issue à ce propos qui est ouverte depuis presque 4 ans.

        Répondre

  • Bibliothèque DCCpp et écran LCD 27 juin 2019 13:17, par Juan

    Bonjour, Thierry,
    Je commence avec l’Arduino et il est clair pour moi que je vais construire ma central sur la base de votre fantastique bibliothèque DCCpp.
    J’ai déjà fait quelques progrès et j’ai un premier prototype qui fonctionne parfaitement. Mais maintenant j’ai un doute : j’aime beaucoup l’écran LCD décrit par Dominique dans "Comment piloter trains et accessoires en DCC avec un Arduino (4).
    La question est : comment puis-je implémenter cet écran et ses fonctionnalités avec la bibliothèque DCCpp ?

    Merci beaucoup,
    Juan.

    Traduit avec www.DeepL.com/Translator

    Répondre

  • Bibliothèque DCCpp 27 juin 2019 19:10, par msport

    Bonjour,
    si vous voulez mettre en œuvre un écran LCD 16x02, vous avez au moins deux réalisations qui fonctionnent très bien en autonome (mais pas seulement) :
    http://locoduino.org/spip.php?article224
    et
    http://locoduino.org/spip.php?article232

    Répondre

    • Bibliothèque DCCpp 28 juin 2019 09:00, par Juan

      Merci beaucoup, je vais étudier attentivement ces deux montages.

      Salutations,
      Juan.

      Répondre

  • Bibliothèque DCCpp 17 juillet 2019 19:05, par Juan

    Bonsoir Thierry,
    J’ai un problème "sérieux" : je ne peux pas installer la bibliothèque DCCpp sur mon Mega arduino, j’obtiens un message d’erreur. Les lignes rouges de l’erreur sont les suivantes (je ne sais pas comment inclure un fichier avec le message complet) :
    C :\Users\Juan\AppData\Local\Temp\cc0MK6Hl.ltrans0.ltrans.o : In function main': <artificial>:(.text.startup+0x628): undefined reference toeServer’

     :(.text.startup+0x62a) : undefined reference to eServer' <artificial>:(.text.startup+0x840): undefined reference toeServer’

     :(.text.startup+0x842) : undefined reference to eServer' <artificial>:(.text.startup+0x1700): undefined reference toeServer’

    C :\Users\Juan\AppData\Local\Temp\cc0MK6Hl.ltrans0.ltrans.o : :(.text.startup+0x1702) : more undefined references to `eServer’ follow

    collect2.exe : error : ld returned 1 exit status

    Usando librería DCCpp con versión 1.3.5 en la carpeta : C :\Users\Juan\Documents\Arduino\libraries\DCCpp
    Usando librería Ethernet con versión 2.0.0 en la carpeta : C :\Program Files (x86)\Arduino\libraries\Ethernet
    Usando librería EEPROM con versión 2.0 en la carpeta : C :\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM
    Usando librería SPI con versión 1.0 en la carpeta : C :\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SPI
    exit status 1
    Error compilando para la tarjeta Arduino/Genuino Mega or Mega 2560.

    Merci par votre temps.
    Juan.

    Répondre

    • Bibliothèque DCCpp 17 juillet 2019 21:27

      Bonjour. c’est un problème que j’ai déjà corrigé. Récupérez le dernière version de la bibliothèque, cela devrait résoudre le problème.

      Répondre

      • Bibliothèque DCCpp 17 juillet 2019 21:46, par Juan

        Mais je pense que c’est précisément la dernière version que j’utilise, que je viens de télécharger depuis le depôt Locoduino.

        Répondre

  • Bibliothèque DCCpp 23 juillet 2019 09:56

    Dans ce cas, c’est que #define NO_ETHERNET n’est pas en remarque alors qu’il devrait... Désolé pour le délai, mais je suis en vacances loin de mon pc ...

    Répondre

  • Bibliothèque DCCpp 24 juillet 2019 18:05, par Juan

    Bonjour, Thierry,
    Pas de problème, je suis désolé de vous déranger en vacances.
    La bibliothèque de DCCpp se porte si bien que ça. Et j’ai beaucoup d’autres questions sur la Commanders, mais nous ferions mieux de les laisser pour votre retour.
    Profitez des vacances et "oubliez" le PC.
    Juan

    Répondre

  • Bibliothèque DCCpp 8 août 2019 19:16, par Juan

    Bonjour, Tiherry,
    Une question sur ton retour de vacances. J’essaie de contrôler DCC+++ via Bluetooth avec le module HC-06.
    Pas de problème si je connecte le module aux broches 0 et 1 du Uno ou du Mega. Mais bien sûr, je perds la connexion par le moniteur sérial. J’essaie d’utiliser d’autres pies, mais ça ne marche pas pour moi. Comment faire cette connexion sans perdre l’USB ?

    Je vous remercie beaucoup,

    Juan

    Répondre

  • Bibliothèque DCCpp 8 août 2019 20:23, par Thierry

    Le Nano ne possède qu’une seule interface série effectivement utilisée par l’USB, mais il est possible d’en créer une de toutes pièces par logiciel avec les bibliothèques SoftwareSerial, AltSoftSerial ou NeoSWSerial. Attention toutefois à l’usage des timers et des interruptions par ces bib, alors que DCC++ en utilise aussi. Il ne faut pas qu’il y ai de collision...
    Pour plus de sécurité, il reste la possibilité d’utiliser un circuit extérieur raccordé en SPI ou en I2C à l’Arduino. Je n’en ai pas trouvé chez mes marchands habituels, mais je ne cherche peut être pas avec les bons mots clés...

    Répondre

    • Bibliothèque DCCpp 8 août 2019 20:33, par Juan

      Merci beaucoup pour votre réponse rapide. Le Nano et Uno n’ont qu’une seule interface série, mais j’utilise le Mega, qui je pense a quatre interfaces. Et il n’y a aucune chance que ça marche, vu mes courtes lumières sur le sujet, bien sûr.

      Répondre

      • Bibliothèque DCCpp 8 août 2019 23:41, par Juan

        Dernières nouvelles : J’ai fait que cela fonctionne parfaitement dans la Mega.
        Mais avec Uno, ça ne marche toujours pas.
        Il sera nécessaire de continuer les recherches.
        Bonne nuit.
        Juan.

        Répondre

  • Bibliothèque DCCpp 30 octobre 2019 12:16, par Juan

    Bonjour, Thierry.

    J’ai terminé la première étape de mon modèle d’essai, qui consiste en un circuit simple avec deux aiguillages, plus plusieurs lumières et du son.
    Ce que je propose dans un deuxième stade, c’est de monter les détecteurs de présence, pour pouvoir gérer le modèle automatiquement. Le circuit est déjà préparé avec les cantons correspondants. Et j’ai différents types de détecteurs d’occupation, mais ce dont je n’ai aucune idée, c’est du logiciel que je dois implémenter.

    Mais je ne sais pas par où commencer. Que me conseillez-vous ? quel logiciel dois-je ajouter pour travailler avec votre bibliothèque DCCpp ?

    Merci bien,
    Juan

    Répondre

  • Bibliothèque DCCpp 14 novembre 2019 19:41, par Juan

    Bonne nuit, Thierry,
    Une petite question : comment puis-je lire l’état, d’un aiguilage particulier, ?
    Je vous remercie beaucoup,
    Juan.

    Répondre

  • Bibliothèque DCCpp 16 novembre 2019 10:52, par thierry

    Bonjour. Si on parle d’une instance de la classe Turnout, il y a une méthode ’isActivated()’ qui renvoie true ou false selon le sens de l’aiguille. Je n’ai pas contre rien trouvé dans la syntaxe texte de DCC++ qui permette de connaitre l’état d’un turnout. Du coup dans la prochaine version de DCCpp il y aura une syntaxe où n est le numéro du turnout à interroger, ce qui renverra ou selon le sens.

    Répondre

    • Bibliothèque DCCpp 16 novembre 2019 10:59, par thierry

      oups, la syntaxe DCC++n n’est pas passée... Donc la nouvelle commande serait "t n -1" (remplacer les guillemets par les caractères inférieur et supérieur), et le retour "H n 0" ou "H n 1".

      Répondre

  • Bibliothèque DCCpp 16 novembre 2019 11:32, par Juan

    Bonjour, Thierry,
    Et merci beaucoup pour votre réponse. Permettez-moi d’expliquer mon problème : dans ma centrale, avec votre bibliothèque DCC++ je fais un TCO graphique, dans un autre arduino connecté en série et chargé de gérer un écran TFT 3.5". J’ai branché des détecteurs de courant comme inputs, qui agissent comme des senseurs qui me disent quel canton est occupé.
    Tout cela fonctionne parfaitement (à ma grande surprise), ce qui me manque, c’est de manipuler les aiguilages. C’est-à-dire, savoir si une aiguilage est ouverte ou fermée, pour envoyer l’ordre correspondant à l’arduino eslave.

    Merci beaucoup pour votre aide,

    Juan.

    Répondre

    • Bibliothèque DCCpp 16 novembre 2019 13:39, par Thierry

      Mais c’est DCC++ qui change la position des aiguillages ou c’est autre chose ?

      Répondre

      • Bibliothèque DCCpp 16 novembre 2019 18:06, par Juan

        C’est vrai, nous devons être précis. La centrale est géré avec le sketch SerialDcc.ino de votre bibliothèque DCCpp, et les aiguillages sont gérés avec des commandes série de manière standard : , par exemple. Ce dernier "1" est l’état de la aiguilage, précisément celui que je veux récupérer.
        Je ne sais pas si je m’explique bien.

        Répondre

        • Bibliothèque DCCpp 16 novembre 2019 18:09, par Juan

          Erreur, la commande série est de la forme "T 12, 1", voilà ce que je voulais dire.

          Répondre

      • Bibliothèque DCCpp 16 novembre 2019 18:12, par Juan

        Ou pour faciliter les choses, supposons que les aiguillages soient traités par Rocrail.

        Répondre

        • Bibliothèque DCCpp 18 novembre 2019 10:25, par thierry

          Donc c’est bien DCCpp qui change la position des aiguillages parce que quelqu’un donne un ordre texte pour ça. Dans ce cas, je reviens sur ma précédente réponse : il n’y a rien de prévu par DCC++ pour retourner l’état courant d’un aiguillage. La prochaine version de DCCpp améliorera ça, mais elle risque de ne pas arriver très vite...

          Répondre

          • Bibliothèque DCCpp 19 novembre 2019 21:54, par Juan

            Bonne nuit.
            Merci pour votre message, mais je ne suis pas d’accord avec le contenu : je pense qu’il est possible de retrouver l’état d’une aiguillage. En fait, je l’ai déjà fait, bien que partiellement. Je continue mes recherches, quand j’aurai perfectionné la méthode, je vous le ferai savoir, si vous êtes intéressé.
            Salutations,
            Juan.

            Répondre

  • Bibliothèque DCCpp 2 décembre 2019 17:33, par Juan

    Bonjour, Thierry,
    J’ai été occupé et je n’ai pas pu répondre à ces messages.
    Pour revenir au dernier sujet, je vous envoie ici la petite modification que j’ai faite dans "Tounout.cpp" :
    #ifdef USE_TEXTCOMMAND
    DCCPP_INTERFACE.print(" DCCPP_INTERFACE.print(data.id) ;
    #ifdef USE_BLUETOOTH
    BLUETOOTH.print(" BLUETOOTH.print(data.id);
    #endif
    if (data.tStatus == 0){
    DCCPP_INTERFACE.print(" 0>") ;
    // Serial3.write(’x’) ; // Prueba para la TFT
    #ifdef USE_BLUETOOTH
    BLUETOOTH.print(" 0>") ;
    #endif
    else
    DCCPP_INTERFACE.print(" 1>") ;
    // Serial3.write(’z’) ; // Prueba para la TFT
    #ifdef USE_BLUETOOTH
    BLUETOOTH.print(" 1>") ;
    #endif

    Avec cette modification, quand j’active ou désactive l’aiguillage, le caractère "x" ou "z" est envoyé à Serial3, pour que je puisse obtenir quelque chose comme ceci :
    "Tournout 1 = open", or "Tournout 1 = closed".
    Comme je l’ai dit, ça marche parfaitement dans mon cas, où il n’y a qu’une seul aiguillage.
    Ce que je ne sais pas encore faire, c’est faire plusieurs aiguillages.
    Salutations
    Juan.

    Répondre

  • Bibliothèque DCCpp 3 décembre 2019 20:30

    Oui, on est donc d’accord. Il n’y a rien dans DCC++ qui retourne l’état d’un aiguillage. Il faut modifier le code pour y arriver.

    Répondre

  • Bibliothèque DCCpp 18 janvier 2020 17:23, par CLB89

    Bonjour Thierry,
    Nouveau sur le site Locoduino et ses multiples applications, je suis très intéressé par Votre article sur DCCpp et sa mise en oeuvre. Je l’ai donc lu et relu et ai décidé de me lancer dans une expérimentation aussi simple que possible.Matériel : JMRI sur W10 en liaison USB/série avec un Arduino Mega 2560. Je me suis limité à USE_TURNOUT, USE_TEXTCOMMAND et j’ai utilisé votre exemple Série en le simplifiant à l’extrême, c’est à dire :

    # include "DCCpp.h"
    
    void setup()
    {
         Serial.begin(115200)
    }
    
    void loop()
    {
         DCCpp::loop()
    }

    La compilation de l’DE Arduino bloque rapidement m’indiquant " Erreur de compilation pour la carte Arduino Mega". Quelle serait votre recommandation pour aller plus loin ?
    Merci par avance !

    Répondre

    • Bibliothèque DCCpp 18 janvier 2020 22:40, par Jean-Luc

      Bonsoir,

      si c’est bien le code que vous avez tenté de compiler, il manque les points virgule à la fin des lignes 5 et 10.

      cordialement.

      Répondre

      • Bibliothèque DCCpp 19 janvier 2020 09:13, par CLB89

        Merci de votre réponse !
        Nouveau sur Locoduino, je ne sais pas envoyer en ligne une copie d’écran ! Apparemment l’editeur d’envoi des messages supprime les caractères du type ALTGr 123 (), AltGr 125 () et autres signes de ponctuation comme le point virgule. Ces catactères font bien partie de mon script.
        Cordialement

        Répondre

  • Bibliothèque DCCpp 18 janvier 2020 18:46

    Bonsoir
    Il y a d’autres messages avant celui ci. Pouvez vous les donner ? Ce qui est souvent le plus important est la première erreur. Les autres n’en sont qu’une conséquence...

    Répondre

    • Bibliothèque DCCpp 19 janvier 2020 09:19, par CLB89

      Bonjour,
      Non pas d’autre message ! Ceci arrive durant la compilation de l’IDE et s’inscrit en bas et en rouge dans la fenêtre de l’IDE.

      Cordialement

      Répondre

  • Bibliothèque DCCpp 19 janvier 2020 09:53, par msport

    Bonjour,
    il y a un ascenseur à droite et qui plus est, la fenêtre est redimensionnable ...
    Cordialement

    Répondre

  • Bibliothèque DCCpp 19 janvier 2020 10:00

    A la fin de la compilation, lorsque des erreurs apparaissent, un bouton ’recopier les messages d’erreur’ apparaît tout à droite de la zone orange entre le code et ces messages. Appuyez sur ce bouton puis coller cela ici... C’est impossible de diagnostiquer quoi que ce soit sans ça.
    Autre possibilité : le message ’CANNOT COMPILE - DCC++ ONLY WORKS WITH AN ARDUINO UNO OR AN ARDUINO MEGA 1280/2560’ qui apparaît lorsque l’IDE est paramétré pour compiler pour autre chose qu’un Uno ou un Mega...

    Répondre

  • Bibliothèque DCCpp 17 février 2020 16:59, par CLB89

    Bonjour
    J’ai toujours beaucoup de problèmes dans la mise en oeuvre de DCCpp. Je suis passé à une connexion Ethernet. Mon croquis est le suivant :

    /*************************************************************
    project: <Dc/Dcc Controller>
    author: <Thierry PARIS>
    description: <Dcc Ethernet Controller sample>
    *************************************************************/
    
    #include "DCCpp.h"
    
    #if !defined(USE_TEXTCOMMAND) || !defined(USE_ETHERNET)
    #error To be able to compile this sample,the lines #define USE_TEXTCOMMAND and #define USE_ETHERNET must be uncommented in DCCpp.h
    #endif
    
    // the media access control (ethernet hardware) address for the shield:
    uint8_t mac[] = { 0xA8, 0x61, 0x0A, 0xAE, 0x76, 0xB6 };
    //the IP address for the shield:
    uint8_t ip[] = { 192, 168, 1, 14 };
    
    EthernetServer DCCPP_INTERFACE(2560);                  // Create and instance of an EthernetServer
    
    void setup()
    {
    	pinMode(53, OUTPUT);
      digitalWrite(53, HIGH);
      pinMode(4, OUTPUT);
      digitalWrite(4, HIGH);
    	
    	Serial.begin(9600);
    
    	DCCpp::begin();
    	// Configuration for my LMD18200. See the page 'Configuration lines' in the documentation for other samples.
    	// DCCpp::beginMain(UNDEFINED_PIN, DCC_SIGNAL_PIN_MAIN, 3, A0);
    	DCCpp::beginEthernet(mac, ip, EthernetProtocol::TCP);
     Serial.print("DCCpp démarre et Internet est supposé lancé");
     Serial.println();
    }
    
    void loop()
    {
    	DCCpp::loop();
    }

    Je reçois le message suivant à la compilation :

    Arduino : 1.8.13 Hourly Build 2020/02/14 03:33 (Windows 10), Carte : "Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:30:6: error: 'Output' has not been declared
    
     void Output::begin(int id, int pin, int iFlag) {
    
          ^~~~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp: In function 'void begin(int, int, int)':
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:37:6: error: 'firstOutput' was not declared in this scope
    
      if (firstOutput == NULL) {
    
          ^~~~~~~~~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:38:17: error: invalid use of 'this' in non-member function
    
       firstOutput = this;
    
                     ^~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:40:12: error: 'get' was not declared in this scope
    
      else if ((get(id)) == NULL) {
    
                ^~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:40:12: note: suggested alternative: 'gets'
    
      else if ((get(id)) == NULL) {
    
                ^~~
    
                gets
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:41:3: error: 'Output' was not declared in this scope
    
       Output *tt = firstOutput;
    
       ^~~~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:41:3: note: suggested alternative: 'Outputs_h'
    
       Output *tt = firstOutput;
    
       ^~~~~~
    
       Outputs_h
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:41:11: error: 'tt' was not declared in this scope
    
       Output *tt = firstOutput;
    
               ^~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:44:20: error: invalid use of 'this' in non-member function
    
       tt->nextOutput = this;
    
                        ^~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:48:2: error: invalid use of 'this' in non-member function
    
      this->set(id, pin, iFlag);
    
      ^~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp: At global scope:
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:60:6: error: 'Output' has not been declared
    
     void Output::set(int id, int pin, int iFlag) {
    
          ^~~~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp: In function 'void set(int, int, int)':
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:61:2: error: invalid use of 'this' in non-member function
    
      this->data.id = id;
    
      ^~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:62:2: error: invalid use of 'this' in non-member function
    
      this->data.pin = pin;
    
      ^~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:63:2: error: invalid use of 'this' in non-member function
    
      this->data.iFlag = iFlag;
    
      ^~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:64:2: error: invalid use of 'this' in non-member function
    
      this->data.oStatus = 0;
    
      ^~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:67:2: error: invalid use of 'this' in non-member function
    
      this->data.oStatus = bitRead(this->data.iFlag, 1) ? bitRead(this->data.iFlag, 2) : 0;
    
      ^~~~
    
    In file included from C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:9:0:
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:67:31: error: invalid use of 'this' in non-member function
    
      this->data.oStatus = bitRead(this->data.iFlag, 1) ? bitRead(this->data.iFlag, 2) : 0;
    
                                   ^
    
    C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:111:32: note: in definition of macro 'bitRead'
    
     #define bitRead(value, bit) (((value) >> (bit)) & 0x01)
    
                                    ^~~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:67:62: error: invalid use of 'this' in non-member function
    
      this->data.oStatus = bitRead(this->data.iFlag, 1) ? bitRead(this->data.iFlag, 2) : 0;
    
                                                                  ^
    
    C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:111:32: note: in definition of macro 'bitRead'
    
     #define bitRead(value, bit) (((value) >> (bit)) & 0x01)
    
                                    ^~~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:71:15: error: invalid use of 'this' in non-member function
    
      digitalWrite(this->data.pin, this->data.oStatus ^ bitRead(this->data.iFlag, 0));
    
                   ^~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:71:31: error: invalid use of 'this' in non-member function
    
      digitalWrite(this->data.pin, this->data.oStatus ^ bitRead(this->data.iFlag, 0));
    
                                   ^~~~
    
    In file included from C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:9:0:
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:71:60: error: invalid use of 'this' in non-member function
    
      digitalWrite(this->data.pin, this->data.oStatus ^ bitRead(this->data.iFlag, 0));
    
                                                                ^
    
    C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:111:32: note: in definition of macro 'bitRead'
    
     #define bitRead(value, bit) (((value) >> (bit)) & 0x01)
    
                                    ^~~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:75:10: error: invalid use of 'this' in non-member function
    
      pinMode(this->data.pin, OUTPUT);
    
              ^~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp: At global scope:
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:80:6: error: 'Output' has not been declared
    
     void Output::activate(int s){
    
          ^~~~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp: In function 'void activate(int)':
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:81:3: error: 'data' was not declared in this scope
    
       data.oStatus=(s>0);                                               // if s>0, set status to active, else inactive
    
       ^~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:81:3: note: suggested alternative: 'atan'
    
       data.oStatus=(s>0);                                               // if s>0, set status to active, else inactive
    
       ^~~~
    
       atan
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp: At global scope:
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:107:1: error: 'Output' does not name a type; did you mean 'Outputs_h'?
    
     Output* Output::get(int n){
    
     ^~~~~~
    
     Outputs_h
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:114:6: error: 'Output' has not been declared
    
     void Output::remove(int n){
    
          ^~~~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp: In function 'void remove(int)':
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:115:3: error: 'Output' was not declared in this scope
    
       Output *tt,*pp;
    
       ^~~~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:115:3: note: suggested alternative: 'Outputs_h'
    
       Output *tt,*pp;
    
       ^~~~~~
    
       Outputs_h
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:115:11: error: 'tt' was not declared in this scope
    
       Output *tt,*pp;
    
               ^~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:115:15: error: 'pp' was not declared in this scope
    
       Output *tt,*pp;
    
                   ^~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:117:10: error: 'firstOutput' was not declared in this scope
    
       for(tt=firstOutput, pp = NULL;tt!=NULL && tt->data.id!=n;pp=tt,tt=tt->nextOutput);
    
              ^~~~~~~~~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:129:10: error: 'firstOutput' was not declared in this scope
    
       if(tt==firstOutput)
    
              ^~~~~~~~~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp: At global scope:
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:146:5: error: 'Output' has not been declared
    
     int Output::count() {
    
         ^~~~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp: In function 'int count()':
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:148:2: error: 'Output' was not declared in this scope
    
      Output *tt;
    
      ^~~~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:148:2: note: suggested alternative: 'Outputs_h'
    
      Output *tt;
    
      ^~~~~~
    
      Outputs_h
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:148:10: error: 'tt' was not declared in this scope
    
      Output *tt;
    
              ^~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:149:12: error: 'firstOutput' was not declared in this scope
    
      for (tt = firstOutput; tt != NULL; tt = tt->nextOutput)
    
                ^~~~~~~~~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp: At global scope:
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:220:6: error: 'Output' has not been declared
    
     void Output::parse(char *c){
    
          ^~~~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp: In function 'void parse(char*)':
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:222:3: error: 'Output' was not declared in this scope
    
       Output *t;
    
       ^~~~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:222:3: note: suggested alternative: 'Outputs_h'
    
       Output *t;
    
       ^~~~~~
    
       Outputs_h
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:222:11: error: 't' was not declared in this scope
    
       Output *t;
    
               ^
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:227:9: error: 'get' was not declared in this scope
    
           t=get(n);
    
             ^~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:227:9: note: suggested alternative: 'set'
    
           t=get(n);
    
             ^~~
    
             set
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:240:7: error: 'create' was not declared in this scope
    
           create(n,s,m);
    
           ^~~~~~
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:240:7: note: suggested alternative: 'rename'
    
           create(n,s,m);
    
           ^~~~~~
    
           rename
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp: At global scope:
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:257:1: error: 'Output' does not name a type; did you mean 'Outputs_h'?
    
     Output *Output::create(int id, int pin, int iFlag){
    
     ^~~~~~
    
     Outputs_h
    
    C:\Users\claud\OneDrive\Documents\Arduino\libraries\DCCpp\src\Outputs.cpp:312:1: error: 'Output' does not name a type; did you mean 'Outputs_h'?
    
     Output *Output::firstOutput=NULL;
    
     ^~~~~~
    
     Outputs_h
    
    exit status 1
    Erreur de compilation pour la carte Arduino Mega or Mega 2560
    
    Ce rapport pourrait être plus détaillé avec
    l'option "Afficher les résultats détaillés de la compilation"
    activée dans Fichier -> Préférences.

    J’ai sorti "les résultats détaillés de la compilation", mais cela 39 KO de texte ! Je peux les rendre disponibles si nécessaire.
    Ma sélection DCCpp.h est la suivante :

    //  Inclusion area
    //
    
    #define USE_TURNOUT
    //#define USE_EEPROM
    //#define USE_OUTPUT
    #define USE_SENSOR
    #define USE_TEXTCOMMAND
    //#define USE_ETHERNET_WIZNET_5100
    #define USE_ETHERNET_WIZNET_5500
    //#define USE_ETHERNET_WIZNET_5200
    //#define USE_ETHERNET_ENC28J60»

    Merci par avance de votre assistance
    Claude

    Répondre

  • Bibliothèque DCCpp 17 février 2020 20:52, par Thierry

    Oui, je suis d’accord, il y a une erreur. Dans la bibliothèque, au début du fichier Outputs.cpp, remplacez ligne 13 le USE_TURNOUT par USE_OUTPUT et ça devrait beaucoup mieux marcher...
    D’autre part, je vois que vous utilisez la version ’Hourly Build’ de l’IDE, je ne vous le conseille pas. Cette version est une version de travail pour l’équipe de développement. Ce n’est pas stable et peut planter et redevenir correcte à chaque heure... Et croyez moi, je développe tous les jours, c’est bien plus facile de faire une erreur que de ne pas en faire... Surtout lorsque les développeurs ne parlent pas la même langue et ne sont pas dans a même pièce ! La version officiuelle est la 1.8.12, et elle fonctionne bien pour l’instant...

    Répondre

    • Bibliothèque DCCpp 18 février 2020 21:34, par CLB89

      Merci pour votre prompte réponse et pour la clé qui m’a permis de rentrer dans le monde DCCpp ! Je compile désormais sans difficulté.
      Quant à votre remarque sur l’utilisation de versions "beta", je suis tout à fait d’accord avec vous et je rentre dans le rang. La seule raison pour laquelle j’ai téléchargée la dernière "hourly build" est qu’il faut passer dans mon cas pour la version "officielle" par Microsoft Store, lequel en profite pour fabriquer un salmigondis d’exécutables de type "package" dans lequel on a beaucoup de difficultés à retrouver ses petits, en particulier en terme d’éléments de librairie.

      Répondre

  • Bibliothèque DCCpp 25 février 2020 18:17, par CLB89

    Bonjour,
    Je reviens vers vous car j’ai toujours problème pour faire fonctionner JMRI avec mon sketch !
    Mon sketch est le suivant :
    « /*************************************************************
    project :
    author :
    description :
    *************************************************************/

    #include "DCCpp.h"

    #if !defined(USE_TEXTCOMMAND) || !defined(USE_ETHERNET)
    #error To be able to compile this sample,the lines #define USE_TEXTCOMMAND and #define USE_ETHERNET must be uncommented in DCCpp.h
    #endif

    // the media access control (ethernet hardware) address for the shield :
    uint8_t mac[] = 0xA8, 0x61, 0x0A, 0xAE, 0x76, 0xB6  ;
    //the IP address for the shield :
    // uint8_t ip[] = 192, 168, 1, 200  ;

    EthernetServer DCCPP_INTERFACE(2560) ; // Create and instance of an EthernetServer

    void setup()

    // Set pins 53 & 4 as required with last Arduino Ethernet library + Ethernet V2 shield on Mega 2560
    pinMode(53, OUTPUT) ;
    digitalWrite(53, HIGH) ;
    pinMode(4, OUTPUT) ;
    digitalWrite(4, HIGH) ;

    Serial.begin(115200) ;

    DCCpp::begin() ;
    // Configuration for my "void Main". See the page ’Configuration lines’ in the documentation for other samples.
    DCCpp::beginMain(UNDEFINED_PIN, UNDEFINED_PIN, UNDEFINED_PIN, UNDEFINED_PIN) ;
    DCCpp::beginEthernet(mac, NULL, EthernetProtocol::TCP) ;
    // Print the local IP address :
    Serial.print("My IP address : ") ;
    for (byte thisByte = 0 ; thisByte < 4 ; thisByte++)
    // print the value of each byte of the IP address :
    Serial.print(Ethernet.localIP()[thisByte], DEC) ;
    Serial.print(".") ;

    Serial.println() ;
    Serial.println("DCCpp démarre et Ethernet est supposé opérationnel !") ;

    void loop()

    DCCpp::loop() ;
     »

    DHCP fonctionne et mon router voit bien Arduino et son Shield Ethernet V2. Après mise en route de JMRI et le chargement d’un panel très simple avec un circuit et 2 aiguillages, je retrouve dans le log session de JMRI l’information suivante :

    « 2020-02-25 17:48:50,050 util.Log4JUtil INFO - ****** JMRI log ******* [main]
    2020-02-25 17:48:50,061 util.Log4JUtil INFO - This log is appended to file : C :\Users\claud\JMRI\log\messages.log [main]
    2020-02-25 17:48:50,061 util.Log4JUtil INFO - This log is stored in file : C :\Users\claud\JMRI\log\session.log [main]
    2020-02-25 17:48:50,068 apps.Apps INFO - PanelPro version 4.18+R37ad3d0 starts under Java 1.8.0_241 on Windows 10 x86 v10.0 at Tue Feb 25 17:48:50 CET 2020 [main]
    2020-02-25 17:48:50,293 apps.Apps INFO - Starting with profile CMBNewProfile.3e2b4aad [main]
    2020-02-25 17:48:50,477 node.NodeIdentity INFO - Using 22ba0102-4f78-4270-a19c-71ebe7f6cd6b as the JMRI storage identity for profile id 3e2b4aad [AWT-EventQueue-0]
    2020-02-25 17:48:50,667 dccpp.DCCppReply ERROR - DCCppReply value index too big. idx = 1 msg = iDCCpp LIBRARY BASE STATION FOR ARDUINO : V-2.0.0 / Feb 25 2020 17:35:02 [AWT-EventQueue-0]
    2020-02-25 17:48:50,668 dccpp.DCCppReply ERROR - DCCppReply value index too big. idx = 2 msg = iDCCpp LIBRARY BASE STATION FOR ARDUINO : V-2.0.0 / Feb 25 2020 17:35:02 [AWT-EventQueue-0]
    2020-02-25 17:49:01,018 util.FileUtilSupport INFO - File path program : is C :\Program Files (x86)\JMRI\ [main]
    2020-02-25 17:49:01,018 util.FileUtilSupport INFO - File path preference : is C :\Users\claud\JMRI\CMBNewProfile.jmri\ [main]
    2020-02-25 17:49:01,018 util.FileUtilSupport INFO - File path profile : is C :\Users\claud\JMRI\CMBNewProfile.jmri\ [main]
    2020-02-25 17:49:01,019 util.FileUtilSupport INFO - File path settings : is C :\Users\claud\JMRI\ [main]
    2020-02-25 17:49:01,019 util.FileUtilSupport INFO - File path home : is C :\Users\claud\ [main]
    2020-02-25 17:49:01,019 util.FileUtilSupport INFO - File path scripts : is C :\Program Files (x86)\JMRI\jython\ [main]
    2020-02-25 17:49:01,618 PanelPro.PanelPro INFO - Main initialization done [main]
    2020-02-25 17:49:51,464 audio.JoalAudioFactory INFO - Initialised JOAL using OpenAL : vendor - OpenAL Community version - 1.1 ALSOFT 1.15.1 [Listed Table Generation]
    2020-02-25 17:59:07,074 audio.DefaultAudioManager INFO - Shutting down active AudioFactory [AWT-EventQueue-0]
    2020-02-25 17:59:07,188 managers.DefaultShutDownManager INFO - Normal termination complete [AWT-EventQueue-0] »

    Merci de votre aide,
    Claude

    Répondre

  • Bibliothèque DCCpp 29 février 2020 21:35, par CLB89

    Bonsoir Thiéry,
    Juste une mise à jour après de nouveaux essais :
    1. Environnement : croquis inchangé, Arduino IDE 1.8.12, JMRI 4.18, Arduino Mega 2560 + Shield Ethernet V2, Configuration DCCpp.h :
    « #define USE_EEPROM
    //#define USE_OUTPUT
    //#define USE_SENSOR
    #define USE_TEXTCOMMAND
    //#define USE_ETHERNET_WIZNET_5100
    #define USE_ETHERNET_WIZNET_5500
    //#define USE_ETHERNET_WIZNET_5200
    //#define USE_ETHERNET_ENC28J60 ».

    2. Durant la compilation du croquis j’ai le message suivant :
    « C :\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.33.0_x86__mdqgnx93n4wtt\libraries\Ethernet\src\utility/w5100.h:457:25 : warning : result of ’(256 << 8)’ requires 18 bits to represent, but ’int’ only has 16 bits [-Wshift-overflow=]
    #define htons(x) ( (((x)<<8)&0xFF00) | (((x)>>8)&0xFF) )
     ^ »

    3. Le log session de JMRI contient les informations suivantes :

    « 2020-02-29 15:41:41,208 util.Log4JUtil INFO - ****** JMRI log ******* [main]
    2020-02-29 15:41:41,219 util.Log4JUtil INFO - This log is appended to file : C :\Users\claud\JMRI\log\messages.log [main]
    2020-02-29 15:41:41,220 util.Log4JUtil INFO - This log is stored in file : C :\Users\claud\JMRI\log\session.log [main]
    2020-02-29 15:41:41,227 apps.Apps INFO - PanelPro version 4.18+R37ad3d0 starts under Java 1.8.0_241 on Windows 10 x86 v10.0 at Sat Feb 29 15:41:41 CET 2020 [main]
    2020-02-29 15:41:41,448 apps.Apps INFO - Starting with profile Mon_Réseau_JMRI.3e952548 [main]
    2020-02-29 15:41:41,632 node.NodeIdentity INFO - Using 6fee769e-e147-4c16-8ee9-9d4a32c78f9c as the JMRI storage identity for profile id 3e952548 [AWT-EventQueue-0]
    2020-02-29 15:41:41,817 dccpp.DCCppReply ERROR - DCCppReply value index too big. idx = 1 msg = iDCCpp LIBRARY BASE STATION FOR ARDUINO : V-2.0.0 / Feb 29 2020 15:39:56 [AWT-EventQueue-0]
    2020-02-29 15:41:41,818 dccpp.DCCppReply ERROR - DCCppReply value index too big. idx = 2 msg = iDCCpp LIBRARY BASE STATION FOR ARDUINO : V-2.0.0 / Feb 29 2020 15:39:56 [AWT-EventQueue-0]
    2020-02-29 15:41:52,082 util.FileUtilSupport INFO - File path program : is C :\Program Files (x86)\JMRI\ [main]
    2020-02-29 15:41:52,082 util.FileUtilSupport INFO - File path preference : is C :\Users\claud\JMRI\Mon_Réseau_JMRI.jmri\ [main]
    2020-02-29 15:41:52,083 util.FileUtilSupport INFO - File path profile : is C :\Users\claud\JMRI\Mon_Réseau_JMRI.jmri\ [main]
    2020-02-29 15:41:52,083 util.FileUtilSupport INFO - File path settings : is C :\Users\claud\JMRI\ [main]
    2020-02-29 15:41:52,083 util.FileUtilSupport INFO - File path home : is C :\Users\claud\ [main]
    2020-02-29 15:41:52,083 util.FileUtilSupport INFO - File path scripts : is C :\Program Files (x86)\JMRI\jython\ [main]
    2020-02-29 15:41:52,693 PanelPro.PanelPro INFO - Main initialization done [main]
    2020-02-29 15:42:29,356 audio.JoalAudioFactory INFO - Initialised JOAL using OpenAL : vendor - OpenAL Community version - 1.1 ALSOFT 1.15.1 [Listed Table Generation]
    2020-02-29 15:43:13,831 jmrix.AbstractMRTrafficController WARN - Timeout on reply to message : T consecutive timeouts = 0 in network.DCCppEthernetPacketizer [network.DCCppEthernetPacketizer Transmit thread]
    2020-02-29 15:43:18,832 jmrix.AbstractMRTrafficController WARN - Timeout on reply to message : Z consecutive timeouts = 1 in network.DCCppEthernetPacketizer [network.DCCppEthernetPacketizer Transmit thread]
    2020-02-29 15:51:28,411 jmrix.AbstractMRTrafficController WARN - Timeout on reply to message : T consecutive timeouts = 0 in network.DCCppEthernetPacketizer [network.DCCppEthernetPacketizer Transmit thread]
    2020-02-29 15:54:24,323 log.LogPanel ERROR - ---Send T command --- [AWT-EventQueue-0]
    2020-02-29 15:54:26,842 log.LogPanel ERROR - ---Send T command --- [AWT-EventQueue-0]
    2020-02-29 15:55:46,291 jmrix.AbstractMRTrafficController WARN - Timeout on reply to message : T consecutive timeouts = 0 in network.DCCppEthernetPacketizer [network.DCCppEthernetPacketizer Transmit thread]
    2020-02-29 16:01:05,370 jmrix.AbstractMRTrafficController WARN - Timeout on reply to message : Z consecutive timeouts = 0 in network.DCCppEthernetPacketizer [network.DCCppEthernetPacketizer Transmit thread]
    2020-02-29 16:02:46,099 audio.DefaultAudioManager INFO - Shutting down active AudioFactory [AWT-EventQueue-0]
    2020-02-29 16:02:46,204 managers.DefaultShutDownManager INFO - Normal termination complete [AWT-EventQueue-0]
     »

    Merci de votre aide,
    Claude

    Répondre

  • Bibliothèque DCCpp < p3 > 23 mai 2020 16:33, par Lormedy

    Bonjour Thierry,

    Suite à notre discussion de l’an dernier qui a conduit à séparer la détection des court-circuits entre MAIN et PROG, un aménagement vers la surveillance de plusieurs secteurs DCC (District in USA) sur un réseau s’avère nécessaire.

    Avec DDCpp, lors d’un court-circuit sur la voie de programmation (Prog), la centrale DCCpp renvoie maintenant < p3 > vers le PC.
    Cependant il serait plus judicieux de renvoyer < p4 > puisque logiquement DCCpp retourne < p0 > pour indiquer que le DCC est Offline et retourne < p2 > quand un court-circuit est détecté sur la voie principale ou sur activation du bouton panicStop.

    Il serait plus logique que les feedbacks de DCCpp qui commencent par < p suivi_d’un_nombre_pair > soient des indications d’arrêt du DCC.

    Tous les feedbacks qui commencent par < p suivi_d’un_nombre_impair > seraient des indications de mise sous tension du DCC sur leur secteur de voies concernées.

    Cela ouvrira la porte à la gestion future des différents secteurs qui composent un réseau, comme à la SNCF.

    En résumé :
    Seule la commande <0> avec son feedback < p0 > indiquerait un arrêt général du DCC sur tout le réseau à la demande du PC.
    De même la commande <1> avec son feedback < p1 > indiquerait une mise sous tension générale du DCC sur tout le réseau à la demande du PC.
    On peut donc envisager d’utiliser <3> pour mettre sous tension la voie de programmation seule, réponse < p3 >, et ainsi de suite avec un pas de 2.
    Les autres commandes et feedbacks permettront de gérer d’autres secteurs de façon autonome, que les futurs logiciels prendront en compte.

    Merci de l’intégrer dans la prochaine release, < p4 > remplacerait < p3 > dans DCCpp.cpp vers la ligne 200.

    Ferroviairement

    Répondre

  • Bibliothèque DCCpp 24 mai 2020 12:21, par souris verte

    Bonjour,

    Ça veut dire que « le chef du réseau » commande plusieurs secteurs, via le CAN par exemple ?
    Il envoie <1> et tous reçoivent l’ordre d’activer DCC puis lui répondent < p1>.
    Le chef du réseau envoie <7>, le secteur 7 active DCC. Il réalise <1> et renvoie, via le CAN, < p7> au chef du réseau ?

    Pas simple cette affaire !?! Mais effectivement intéressant pour les grands réseaux 🤔
    Le chef de réseau saura quels secteurs sont actifs et pourra réaliser les itinéraires en conséquence... bon courage M. le chef.
    Bon dimanche
    Yannick

    Répondre

  • Bibliothèque DCCpp 4 octobre 2020 17:41, par Lionel

    Bonjour,

    Tout d’abord un grand merci pour votre fabuleux travail et cette bibliothèque.

    Je viens de mettre à jour celle-ci depuis la version 1.3.7 vers la dernière en date (la 1.4.1) et depuis, j’ai les erreurs de compilation ci-dessous (je n’ai pas changé mon programme entre temps), et du coup, impossible de l’utiliser.

    /home/lmollard/Arduino/libraries/DCCpp/src/Locomotives/Locomotive.cpp:10:1 : error : ’Locomotive’ does not name a type
    Locomotive::Locomotive(const char* inName, uint8_t inSpeedRegister, uint16_t inAddress, uint8_t inSpeedMax)

    /home/lmollard/Arduino/libraries/DCCpp/src/Locomotives/Locomotive.cpp:25:1 : error : ’Locomotive’ does not name a type
    Locomotive::Locomotive(const char* inName, uint8_t inSpeedRegister, uint8_t inFunctionRegister, uint16_t inAddress, uint8_t inSpeedMax)

    /home/lmollard/Arduino/libraries/DCCpp/src/Locomotives/Locomotives.cpp:10:1 : error : ’Locomotive’ does not name a type
    Locomotive* Locomotives::pFirstLocomotive = NULL ;

    /home/lmollard/Arduino/libraries/DCCpp/src/Locomotives/Locomotives.cpp:11:6 : error : ’Locomotives’ has not been declared
    bool Locomotives::useFunctionRegister = false ;

    /home/lmollard/Arduino/libraries/DCCpp/src/Locomotives/Locomotives.cpp:13:1 : error : ’Locomotive’ does not name a type
    Locomotive* Locomotives::get(uint16_t inAddress)

    /home/lmollard/Arduino/libraries/DCCpp/src/Locomotives/Locomotives.cpp:29:1 : error : ’Locomotive’ does not name a type
    Locomotive* Locomotives::get(const char* inName)

    /home/lmollard/Arduino/libraries/DCCpp/src/Locomotives/Locomotives.cpp:45:6 : error : ’Locomotives’ has not been declared
    void Locomotives::remove(uint16_t inAddress)

    /home/lmollard/Arduino/libraries/DCCpp/src/Locomotives/Locomotives.cpp:49:6 : error : ’Locomotives’ has not been declared
    void Locomotives::remove(const char* inName)

    /home/lmollard/Arduino/libraries/DCCpp/src/Locomotives/Locomotives.cpp : In function ’void remove(const char*)’ :
    /home/lmollard/Arduino/libraries/DCCpp/src/Locomotives/Locomotives.cpp:49:6 : error : ambiguating new declaration of ’void remove(const char*)’
    In file included from /home/lmollard/ArduinoIDE/hardware/arduino/avr/cores/arduino/Print.h:24:0,
    from /home/lmollard/ArduinoIDE/hardware/arduino/avr/cores/arduino/Stream.h:26,
    from /home/lmollard/ArduinoIDE/hardware/arduino/avr/cores/arduino/HardwareSerial.h:29,
    from /home/lmollard/ArduinoIDE/hardware/arduino/avr/cores/arduino/Arduino.h:233,
    from /home/lmollard/Arduino/libraries/DCCpp/src/Locomotives/Locomotives.cpp:7 :
    /home/lmollard/ArduinoIDE/hardware/tools/avr/avr/include/stdio.h:960:12 : note : old declaration ’int remove(const char*)’
    extern int remove(const char *pathname) ;

    /home/lmollard/Arduino/libraries/DCCpp/src/Locomotives/Locomotives.cpp : At global scope :
    /home/lmollard/Arduino/libraries/DCCpp/src/Locomotives/Locomotives.cpp:53:5 : error : ’Locomotives’ has not been declared
    int Locomotives::count()

    /home/lmollard/Arduino/libraries/DCCpp/src/Locomotives/Locomotives.cpp : In function ’int count()’ :
    /home/lmollard/Arduino/libraries/DCCpp/src/Locomotives/Locomotives.cpp:57:2 : error : ’Locomotive’ was not declared in this scope
    Locomotive* pCurr = pFirstLocomotive ;

    /home/lmollard/Arduino/libraries/DCCpp/src/Locomotives/Locomotives.cpp:57:14 : error : ’pCurr’ was not declared in this scope
    Locomotive* pCurr = pFirstLocomotive ;

    /home/lmollard/Arduino/libraries/DCCpp/src/Locomotives/Locomotives.cpp:57:14 : note : suggested alternative : ’perror’
    Locomotive* pCurr = pFirstLocomotive ;

    perror
    /home/lmollard/Arduino/libraries/DCCpp/src/Locomotives/Locomotives.cpp:57:22 : error : ’pFirstLocomotive’ was not declared in this scope
    Locomotive* pCurr = pFirstLocomotive ;

    Auriez-vous une piste à me donner pour faire de nouveau fonctionner mon programme ?

    Par avance, un grand merci pour votre aide.

    Bonne journée,
    Lionel

    Répondre

  • Bibliothèque DCCpp 5 octobre 2020 08:31, par Thierry

    Bonjour.

    C’est une erreur déjà corrigée, les fichiers Locomotive doivent être supprimés. Mais peut être que la dernière mise à jour n’a pas retiré les fichiers qui sont maintenant en trop...

    Répondre

  • Bibliothèque DCCpp 17 octobre 2020 11:50, par Dominique

    Bonjour,

    Est-ce que DCCpp::loop() peut détecter des commandes texte arrivant via une liaison SotwareSerial sur un Nano ?

    Cordialement,
    Dominique

    Répondre

  • Bibliothèque DCCpp 17 octobre 2020 16:32, par Thierry

    Bonjour

    DCCpp fonctionne, comme DCC++, avec Serial par défaut, sans possibilité de facilement changer.
    Par contre il est tout à fait envisageable de récolter des commandes sur une autre interface dans le loop() du croquis, à côté de DCCpp::loop(), et ensuite de demander le traitement de la commande avec TextCommand::parse(commande_recue) ; .

    Répondre

  • Bibliothèque DCCpp 24 janvier 2021 12:39, par Denis

    Bonjour
    Je fais mes premiers pas dans votre biblioteque que je la trouve extrement utile a mes projets malgre le fait que je suis un neothyte, pourtant j’ espere...
    Pour ce weekend je me suis implique sur le projet MiniDcc. Pour cette raison je voudrais savoir si le schema de branchement pour ce projet est disponible .
    Je vous remercie d avance,
    Denis

    Répondre

  • Bibliothèque DCCpp 7 juin 2021 21:59, par Carlos

    Salut ! je m’appelle Carlos, je travaille actuellement chez DCCppCab et j’aimerais entrer en contact avec quelqu’un du projet de bibliothèque DCCpp, pouvez-vous répondre à l’email d’inscription ? Merci !!!

    Répondre

  • Bibliothèque DCCpp 5 avril 2022 11:18, par CLB89

    Toujours néophyte et utilisateur de DCCpp que j’utilise simultanément à une centrale Lenz pour la commande des locomotives, je voudrais aller un pas plus loin. Est-il possible d’interfacer une appli comme Z21 avec DCCpp ? Je précise que j’utilise DCCpp en liaison internet avec JMRI.
    Merci de vos conseils

    Répondre

  • Bibliothèque DCCpp 4 mars 2023 09:36, par Jean Jacques

    Bonjour.
    Je souhaite monter une petite station et j’apprécie les fonctionnalités de cette bibliothèque.
    J’ai deux question :
    est-il possible de ne pas afficher les ligne ci-dessous dans le moniteur série, pour mes extension j’utilise des PCF8574 et PCF8575 et avec le flux d’information c’est plus compliqué pour faire la mise au point.J’ai tenté des de dévalider des lignes dans DCCpp.h mais sans succès.
    T1 3 0 0
    T1 3 44 0
    T1 3 56 0

    Ma deuxième question peut-on utiliser cette bibliothèque avec Rocrail.
    Par avance merci pour les raiponces.
    Cordialement.

    Répondre

    • Bibliothèque DCCpp 12 mars 2023 09:19, par Jean Jacques

      Bonjour.
      Pour l’affichage des données dans le moniteur série je n’avais pas commenté la bonne ligne donc ce problème là est résolu.
      cordialement.

      Répondre

  • DCCpp library turnouts 26 septembre 20:43, par Per-Åke Jansson

    Im running both trains an d turnouts successfully from an Arduino with a booster added.
    But Im a bit confused how the set up of turnout addresses are calculated from the C code instruction

    turn1.begin(1, 24, 3) ; // DCC adr. 96
    turn2.begin(1, 25, 4) ; // DCC adr. 97

    How do the algoritm look like to get address 96 an 97 from the numbers set in the C code
    I use a DCC sniffer to see the addresses and bit pattern

    /Per-Åke

    Répondre

Réagissez à « Bibliothèque DCCpp »

Qui êtes-vous ?
Votre message

Pour créer des paragraphes, laissez simplement des lignes vides.

Lien hypertexte

(Si votre message se réfère à un article publié sur le Web, ou à une page fournissant plus d’informations, vous pouvez indiquer ci-après le titre de la page et son adresse.)

Rubrique « Bibliothèques »

Les derniers articles

Les articles les plus lus