J’avais déjà présenté de manière superficielle ce dispositif qui permet de lire l’état de capteurs dans Rocrail, le seul que logiciel j’ai testé, mais aussi sans doute pour d’autres logiciels. Ce dispositif peut se substituer au bus S88 « classique » et fonctionner au travers d’un bus CAN rapide à 1 Mbits/s. Je précise qu’il n’y a pas de compatibilité avec un bus S88 existant (sauf pour les capteurs ce qui est déja beaucoup).
Je crée ce fil pour apporter les précisions qui m’ont été demandées à ce sujet.
L’ensemble se compose d’un ou plusieurs décodeurs (à droite sur la photo) reliés entre eux avec du câble RJ45 (Ethernet) de préférence catégorie 5 c’est-à-dire sans blindage. L’alimentation électrique est également assurée au travers du câble Ethernet.
Les décodeurs sont réalisés à base de Raspberry Pi Pico et disposent de 16 entrées pour n’importe quels dispositifs de détection « tout ou rien » (1 / 0). Conformément au dispositifs Marklin, l’état est actif lorsque l’entrée reçoit un signal de masse. Elle est inactive quand elle ne reçoit rien (signal coupé) mais jamais un signal positif.
Une carte passerelle (à gauche sur la photo) assure la remontée des informations des différents capteurs dans Rocrail, soit au travers d’une liaison Ethernet (câble RJ45 relié à la box domestique) soit en WiFi. C’est à partir de cette carte qu’est également réalisée l’alimentation électrique de tous les décodeurs.
On choisit le protocole mbus en TCP. L’adresse IP est celle de la passerelle CAN/TCP. Le port est également celui qui est renseigné dans la passerelle.
Le moniteur série relié au port USB de l’ESP32 (passerelle) nous renseigne sur l’adresse IP à renseigner pour le controller de Rocrail (voir post ci-dessus)
S’assurer que l’option sensor (en bas à gauche) est bien activée.
1° - Choisir le controller pour communiquer avec la carte gateway
2° - Choisir le décodeur concerné. Ici, il s’agit du premier, il a donc l’adresse 0.
3° - Choisir l’entrée concernée du décodeur, il s’agit de l’entrée 6, l’adresse est donc 5. En effet, l’entrée 1 correspond à l’adresse 0, l’entrée 2 à l’adresse 1 etc…
Comme tu les sais, j’aimerais bien pouvoir tester tous les éléments de la chaine un par un avant de les relier. J’ai compilé et chargé ton code sur le Pico sans encombre, mais rien n’apparait dans le Serial Monitor. Peux-tu confirmer que le fonctionnement du décodeur Pico peut se tester (cad vérifier l’état des capteurs de détection d’occupation) via le “Serial Monitor” de l’Arduino IDE sans que le décodeur soit relié a la passerelle ? (le décodeur Pico étant bien sur alimenté de facon autonome en 5v via micro USB)
Tu recommandes une alimentation extérieure de 9v a 36v DC - les prises en micro USD alimentent le décodeur Pico ou la passerelle ESP32 en 5v DC seulement. Le choix du voltage est-il une fonction du nombre d’éléments dans la chaine et/ou du régulateur de tension retenu ? Mon régulateur en l’occurence, est celui-ci:
Non le code comme il est écrit n’affiche que les données CAN envoyées. Or, s’il n’y a aucun dispositif pour réceptionner et confirmer la réception, l’envoi des messages stoppe aprés 17 tentatives !!!
Mais le petit ajout de code suivant va te permettre de vérifier le fonctionnement
Serial.println(state, BIN); // Affichage de l'état des capteurs sous forme binaire
Voici sa position dans l’ensemble du loop :
void loop()
{
//--- MAJ des capteurs
uint16_t state = 0;
for (byte i = 0; i < nbSensors; i++)
{
if (!digitalRead(sensorInPin[i]))
state |= 1 << i;
}
Serial.println(state, BIN); // Affichage de l'état des capteurs sous forme binaire
//--- MAJ des datas de la frame et envoi
frame.data16[0] = state;
const bool ok = gSat.can.tryToSend(frame);
if (ok)
Serial.printf("Sent: %d\n", frame.data16[0]);
else
Serial.println("Send failure\n");
delay(100); // Toutes les 100ms
}
Le régulateur que tu montres est parfait. Il permet de convertir une tension de 9 à 36 volts en 5 volts ce qui est parfait pour alimenter un Pico ou un ESP.
Quand on a un peu de longueur dans les fils d’alimentation, il vaut mieux alimenter avec une tension supérieure car il y a des pertes en lignes et ramener le courant sur chaque carte à 5 volts.
Pour l’alimentation en USB, c’est différent car il y a assez peu de longueur donc le 5 volts suffit.
Au plaisir de t’aider à mettre en place ce type de solutions
Carte décodeur et passerelle étant alimentées via le bornier en 12v DC.
J’ai bien utilisé les dernieres versions du code que tu indiques plus haut. Ca compile et j’ai donc pu le téléverser sur le Pico et l’ESP32 sans probleme.
J’ai également pu tester le fonctionnement du Pico avec ton petit rajout de code, qui est bien pratique. On obtient des infos binaires de ce genre dans le Serial Monitor de l’Arduino IDE (ici pour l’entrée #4 de carte):
J’ai donc pu vérifier, en simulant une occupation, le changement d’état sur les 16 entrées de la carte décodeur: tout est bon.
Concernant la passerelle ESP32, le Serial Monitor me rapporte ceci:
Un peu avare en information et c’est la que les choses se compliquent pour moi. Quoique je fasse sur les 16 entrée de la carte décodeur Pico, rien ne se passe dans le Serial Monitor de la passerelle ESP32. Donc, en l’absence d’accusé d’émission et/ou de réception je ne sais pas si le décodeur a envoyé ou non le message, ou si la passerelle a recu ou non le message du décodeur.
J’ai aussi crée un “controller” dans RocRail comme tu nous le montres plus haut. Le log de Rocrail m’indique qu’il est bien connecté a la passerelle…mais, apres quelques minutes, Rocrail me dit ensuite que le connexion est perdue. Je dois alors rebooter l’ESP32 de la passerelle (bouton Reset) et la connexion se ré-établie. Puis Rocrail reperd la connexion, et ainsi de suite, c’est systématique. De plus, quoique je fasse avec les 16 entrées de la carte décodeur, il n’y aucune information qui remonte a RocRail.
La perte de connexion est peut etre en rapport avec ce que tu disais plus:
Je ne suis pas certain de ce que je peux conclure de ces tests. La carte décodeur ne transmet rien a la passerelle et cette derniere, du coup, se met en veille ? Ou bien est-ce la passerelle qui ne fait pas son job ? Mon souci est que l’on ne peut pas vraiment “monitorer” la transmission de message sur le bus CAN depuis le Serial Monitor de l’IDE, donc il m’est difficile de d’identifier un coupable.
Pour finir, j’ai également testé par continuité la connexion entre le MPC2562 (puce CAN) du décodeur et de la passerelle. C’est tout bon pour le “high” et le “low”, ce n’est donc pas une bete histoire de cable RJ45 foireux.
J’espere avoir été clair dans mes explications.
Par avance, je te remercie pour ton support sur le sujet. On se rapproche du but, je le sens !
Pour vérifier que la carte passerelle reçoit bien des informations CAN, tu peux ajouter un Serial.print(). En l’occurence, je vais utiliser ici un Serial.printf() qui permet, sur une même ligne de code, d’afficher du texte et une ou plusieurs valeurs
Serial.printf("Received from the node %d value %d", idModule, frameIn.data16[0]);
En utilisation normale, il est préférable de ne pas laisser ces Serial.print() car il ralentissent l’exécution. Le bon moyen de les désactiver est de les placer en commentaire avec “//” en début de ligne
Pour ce qui concerne la déconnexion intempestive, il s’agit très probablement d’un timeout quelque part, probablement sur ta box. J’ai dans le code un système de reconnexion automatique, mais cela ne doit servir qu’exceptionnellement .
Dans le programme, j’ai prévu que les données en provenance des capteurs ne sont transmises à Rocrail que dans le cas où, pour chaque module, la nouvelle donnée (un ou plusieurs des capteurs d’un module qui arrive toutes les 100 ms) est différente de la précédente. Un module envoi en effet en un seul bloc, l’état de ses 16 capteurs sur 16 bits (ex 0001000000100000). Ceci pour éviter à Rocrail une activité inutile.
Pour les tests, tu peux commenter les lignes de code qui activent ce mécanisme ce qui adressera à Rocrail un message en TCP toutes les 100ms (x par le nombre de modules). Si c’est bien une question de timeout comme je pense, cela devrait résoudre le problème.
Si, en faisant cela, on constate que ça solutionne le problème, je mettrait en place un mécanisme qui envoie régulièrement des données (ex toutes les 10, 30 secondes) même s’il n’y a pas de changement. Cela servira à maintenir la connexion.
En liaison filaire (Ethernet) tu ne devrais pas avoir le problème.
Il faut que tu remplaces le morceau de programme qui doit démarrer chez toi à la ligne 220 par celui-ci
void CANReceiveTask(void *pvParameters)
{
CANMessage frameIn;
Message message;
while (true)
{
if (ACAN_ESP32::can.receive(frameIn))
{
byte idModule = frameIn.id;
Serial.printf("Received from the node %d value %d", idModule, frameIn.data16[0]);
// if (module[idModule].value != frameIn.data16[0])
// {
message.module = idModule;
for (byte i = 0; i < 16; i++)
{
message.sensor = i;
message.value = ((frameIn.data16[0] & (1 << i)) >> i);
xQueueSend(canToTcpQueue, &message, portMAX_DELAY);
}
module[idModule].value = frameIn.data16[0];
//}
}
vTaskDelay(10 / portTICK_PERIOD_MS);
}
} // end CANReceiveTask
Ca va fonctionner car chez moi c’est nickel. Mais je n’ai testé que la liaison filaire préfèrable comme nous en avons parlé.
J’ai enfin trouvé un peu de temps pour avancer sur ce montage. Je me suis fait un banc de test qui reproduit ma configuration future, a savoir une chaine de 2 décodeurs Pico (qui permettent a eux deux jusqu’a 32 contacts) et la passerelle ESP32 CAN<->TCP en liaison Ethernet vers la box (via courant porteur de ligne en ce qui me concerne, ma box est assez éloignée de la piece).
La solution Wifi est a écarter, Christophe a passé beaucoup de temps à essayer de la faire fonctionner, sans succès. Je ne pense pas que la fonctionnalité Wifi des ESP32 soit d’une qualité/fiabilité suffisante pour ce genre d’application…
Donc, en Ethernet, cela fonctionne, à un “détail” près qu’il va me falloir résoudre: lorsqu’on coupe l’alimentation et rallume, les décodeurs et la passerelle ne se synchronisent pas automatiquement. Les LED vertes des Pico clignotent. La seule “solution” que j’ai trouvé - qui ne fonctionne que 2x sur 3, et qui n’est pas viable une fois tout cela monté sur le réseau - est de connecter chaque décodeur Pico a l’Aduino IDE avec le cable micro-USB - il suffit juste de les connecter en choisissant le port COM et le type de carte, pas besoin de re-téléverser le code. Les LED vertes des Pico restent alors allumées (mais pas toujours…la LED peut parfois s’eteindre et cela fonctionne quand meme) et on peut alors débrancher le cable micro-USB. Presser le bouton “reboot” de la passerelle de change rien au problème.
En ne suivant pas cette étrange procédure, rien ne se passe dans Rocrail car la passerelle n’a pas d’infos a remonter (Rocrail me confirme par ailleurs qu’il est bien connecté a la passerelle). Je note également qu’il faut recommencer cette bidouille a chaque fois que l’on ferme/réouvre RocRail. Bref, un probleme de synchronisation de toute évidence. Christophe, si tu as une idée, je prends !
Par ailleurs, l’insertion des serial.print est effectivement tres utile pour analyser la transmission/réception des messages CAN le long de la chaine. Mais, comme le souligne Christophe plus haut, il faut impérativement les neutraliser lors des tests avec RocRail car cela surcharge l’ESP32 a mort et les temps de réaction pour la détection augmentent exponentiellement.
Je suis admiratif de ta persévérance et de la volonté que tu as de comprendre et réaliser toi-même.
Je suis heureux de voir que le principe général fonctionne. C’est vrai que ça a quelque chose d’un peu magique quand tu vois les capteurs changer de couleur dans Rocrail.
Il y a effectivement des choses à perfectionner d’autant que tu es parti des versions qui n’étaient souvent que des ébauches, même pas des Beta.
Effectivement, le problème que tu rencontres est une non-synchronisation.
Il y a plusieurs solutions que je vais tester une fois rentré chez moi. On peut par exemple placer une boucle dans le setup de chaque programme qui émet un message et attend une confirmation des deux autres programmes avant de sortir du setup.
Ce programme pouvant conduire au reboot si rien ne se passe après x tentatives
Pour documenter quelques infos utiles pour l’utilisation des Raspberry Pico dans le contexte du montage de détection présenté plus haut…
J’ai opté pour la version la plus basique du Pico qui soit: Raspberry Pi 2MB SC0917 Pico H 32 bit. Il existe des versions plus sophistiquées (avec Wifi, BlueTooth etc) mais c’est inutile pour le montage décrit plus haut. Le prix de la version basique est vraiment modique: £4 la pièce, disons €5 ! Disponibles via de nombreux marchands en ligne ou sur le site de Raspberry directement.
En branchant le Pico au PC pour la 1ere fois avec un câble micro-USB, il est reconnu comme un périphérique par Win11 (avec la notification sonore caractéristique) mais il n’apparait pas dans l’explorateur pour autant (comme apparaitrait une clé USB par exemple). Il y a un certain nombre de choses a savoir et à faire avant de pouvoir lui téléverser un code a exécuter.
Ce site m’a été très utile pour comprendre ces étapes préliminaires:
Replying to my own post again (sorry). Still continuing the saga, trying to get Debian on Raspberry Pi v3 to load the Linux package that gets the Arduino IDE to support Raspberry Pico development.
Donc, en suivant ces instructions, on installera ce package pour Windows mis a disposition par la fondation Raspberry:
Puis, on suivra les étapes décrites pour que l’Arduino IDE puisse reconnaitre le Pico. Il faut notamment installer le package “Raspberry Pi Pico/RP2040/RP2350” de Earle F. Philhower via le “Board Manager” de l’Arduino IDE. Une fois ce package installé, avec le Pico branché sur le cable micro-USB, on pourra sélectionner le port COM et la bonne carte dans l’Arduino IDE pour y téléverser quelque chose.
Mais attention ! Il est important de savoir que pour le 1er téléversement sur le Pico, il faut au préalable le brancher via la prise micro-USB tout en maintenant le bouton “BOOT SEL” appuyé. Un disque USB nommé RPI-RP2 se “monte” - et est donc visible dans l’explorateur Windows - et le fichier résultant de la compilation, un fichier “.uf2” est copié sur le disque du Pico. C’est comme cela que le flashage s’effectue. Il n’est nécessaire de faire cette manip que pour le 1er flashage (téléversement du code). Ce n’est plus requis ensuite, on peut téléverser directement. Si on ne sait pas cela, on peut passer pas mal de temps a tourner en rond…oui, j’ai pas mal tourné en rond et je ne pense pas être le seul
Pour les microcontrôleurs type ESP32, même logique: il sera également nécessaire d’installer au préalable un pilote adéquat et de télécharger les packages “Arduino ESP32 Boards” et “esp32” via le “Board Manager” de l’Arduino IDE avant que celui-ci ne puisse reconnaisse la carte et y téléverser quelque chose. J’ai téléchargé mes pilotes ici:
Attention: il faut aussi savoir que les microcontrôleurs ESP32 existent en version 30 ou 38 broches (“broches”=“pins”). Les différents montages proposés par Christophe emploient tantôt les uns, tantôt les autres. Et il peut également y avoir des variations dans les broches de sorties selon les fabricants (donc 2 ESP 38 broches, apparemment identiques, ne le seront pas forcemment). Cela importe pour l’allocation des broches dans le code pour les flux entrants/sortants…je recommande de se procurer le schéma complet des broches pour les microcontrôleurs que l’on a acheté, ce qui permettra de vérifier les allocations définies dans le code, si besoin. Cela peut etre une source de non-fonctionnement d’un montage.
Enfin, pour que le code de communication CAN crée par Christophe puisse être compilé correctement, il faudra au préalable télécharger les bibliothèques CAN disponibles dans le “Library manager” de l’Arduino IDE. Notamment la bibliothèque ACAN2515 de Pierre Molinaro. Dans l’Arduino IDE, j’ai téléchargé plus de bibliothèques CAN que nécessaires je pense. Elles sont disponibles gratuitement, et se télechargent en quelques secondes.
Voilà, j’espère que ces petites infos feront gagner du temps a ceux qui veulent explorer la chose comme moi. Probablement une succession d’évidences pour les pro de l’Arduino, mais certainement pas évident pour ceux qui partent de 0. Il ne faut pas se voiler la face, c’est une “logique très informatique”: je jette la pierre a celui qui n’a pas souri devant cette logique implacable de devoir appuyer sur le bouton “Démarrer” pour “Arrêter” son PC sous Windows ! Et, soyons clair, “l’a peu près” n’est pas toléré dans ce genre de projet.
Mais tous ces préliminaires logistiques ne sont qu’à effectuer qu’une fois. Dès que l’Arduino IDE est équipé pour interagir avec les Pico et ESP32, et que toutes les bibliothèques CAN nécessaires sont chargées dans l’Arduino IDE, là, cela devient réellement passionnant : on pénètre dans les entrailles du système CAN de Märklin et les possibilités semblent infinies ! Lorsque je trouve un peu de temps, je vais recommencer à 0 avec ce fil didactique qu’a proposé Christophe:
J’ai pris le train en marche avec le CAN, ce qui n’est pas la bonne approche, j’ai l’impression d’apprendre à rebours.
Enfin, il faut insister sur cette chance inouï d’avoir Christophe parmis nous, un passionné incroyablement compétent, pointu et efficace. “Les chercheurs qui cherchent, on en trouve, les chercheurs qui trouvent, on en cherche”. Je peux l’affirmer, il est dans la 2ieme catégorie et on ne l’a meme pas cherché: il est venu vers nous !
Je suis vraiment très touché par ton message et je te remercie.
Je te remercie aussi car tu as fait un gros travail de pédagogie en documentant ce que tu as réalisé. J’avoue que ce n’est pas ce qui m’intéresse le plus et cela sera je l’espère précieux pour d’autres.
J’apprécie de travailler à plusieurs sur un sujet car le pense que les intelligences ne s’additionnent pas mais se multiplient. C’est ce que je fais également avec Alain sur un autre sujet.
Il est vrai que ce type de démarche que tu as entrepris n’est pas le chemin facile. L’objectif, tu l’as déjà souvent dit, n’est pas d’avoir un « truc » tout cuit mais quelque chose que l’on comprend, que l’on maîtrise et au final, qui nous est propre et dont on est heureux, intellectuellement en particulier, d’avoir réalisé le job. T quand en plus, cela peut être source d’économie ça n’est que mieux.
Y avait-il un commencement que tu aurais « loupé » ? Oui et non. Il y a bien sûr les bases mais je crois qu’il faut surtout acquérir tous les fondamentaux, les comprendre bien sûr et puis un moment donné on arrive à avoir une vue globale et comprendre pourquoi ça ne fonctionne pas.
Dans le fil « Table de commande pour 6 locomotives (ou plus) », je suis « descendu » aussi pas mal dans les arcanes du CAN ! Mais pour ce projet, je vais maintenant proposer d’utiliser la bibliothèque Railuino pour laquelle j’avais réalisé l’an dernier un gros travail de mise à niveau en c++ (moderne). Dans ce projet qui vise plutôt des utilisateurs, cette belle bibliothèque sera plus aisée à utiliser.
Bonne continuation et j’essayerai de t’aider au mieux.
Bonjour Christophe, je viens de voir que tes modules de rétrosignalisations sont finalisés, c’est génial. Je suis toujours en attente de modules de ce genre pour basculer définitivement sous Rocrail. Envisages tu d’en commercialiser ? je serai preneur . Tiens moi au courant en MP si tu veux.
Je ne cherche pas à commercialiser. Quand j’ai pu fournir des cartes, je l’ai fait à quasi prix coutant, plus pour rendre service.
Alors, dans ces conditions, oui, je peux te fournir des cartes avec les composants, assemblées ou non.
Pour les entrées devant être reliées aux rails pour la détection de présence par rail contact, je préconise d’ajouter une isolation galvanique. Ce sont les petites cartes que l’on voit sur le montage de Jérôme plus haut dans ce post.
N’hésites pas à m’appeler pour plus de précisions.