LOCODUINO
Parlons Arduino => Composants => Discussion démarrée par: bobyAndCo le août 16, 2024, 09:19:23 am
-
Bonjour à tous,
Je cherche de l’aide concernant l’utilisation du Rasbperry PI Pico suite à l’article de Jean-Luc : https://www.locoduino.org/spip.php?article319
Tout d’abord, j’ai un problème avec l’utilisation de Serial. Problème qui était intermittent mais maintenant permanent et qui me pose de sérieuses difficultés car je n’ai pas de debugge via cette interface ce qui est tout de même gênant. Je précise bien ce point car c’est assez déroutant. J’ai eu des problèmes assez vite au début puis j’ai fait un programme complet avec un module CAN et des Serial.ptin() pour le débug et ça a fonctionné. Puis maintenant avec un bête programme « Blink + Serial» ça ne fonctionne plus
Pour faire simple, le même programme sans Serial fonctionne alors qu’avec Serial il ne fonctionne plus.
Sur les conseils de Jean-Luc j’ai ajouté
while (!Serial)
{
delay(50);
}
Mais rien n’y fait
Il est ensuite impossible de faire un nouveau téléversement, le port est déclaré comme « busy ». Même mon utilitaire CollTerm qui fonctionne à merveille depuis des années fini par planter. Le seul moyen (heureusement) de récupérer mon RP est d’effacer totalement la carte, appui sur « bootsel » en même temps que de brancher le câble USB. Il faut alors formater le volume mais cela ne règle pas le problème de fond.
Voici avec le simple programme de blink qui fonctionne sans serial et ne fonctionne plus avec Serial !!!
void setup() {
Serial.begin(115200);
while (!Serial)
{
delay(50);
}
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
Serial.print("ok ");
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000);
J'avoue que de l'aide serait bienvenue car je suis assez désespéré.
Je suis sur Mac M2 avec Sonoma 14.6
J’ai le problème sur l’IDE Arduino 2.3.2 mais c’est exactement la même chose avec PlateformIO.
Christophe
-
Salut Christophe
Ça va pas beaucoup t'aider mais j'ai copié-collé ton code et :
MacBook Air M1 sous Sonoma 14.6.1.
IDE 1.8.19 -> OK
IDE 2.3.2 -> OK
Coolterm 2.0.0 -> OK
-
Oui config similaire à la mienne. Sonoma est à jour.
Et j'ai le problème avec tous mes Pico qui viennent de deux fournisseurs différents. Gotronic et TME ???
J'ai aussi essayé sur un Pico, wifi, ça a débloqué l'utilisation des "non" wifi !!! Pour combien de temps ?
-
Avec l'exemple LoopBackDemo
Les pins sont celles provenant du montage avec MCP2515 + MCP2562 que tu m'as (@Jean-Luc) communiquées pour ton propre montage. Pas de reset ni OSC1 pour l'instant je veux juste tester l'exemple.
static const byte MCP2515_SCK = 10 ; // SCK input of MCP2515
static const byte MCP2515_MOSI = 11 ; // SDI input of MCP2515
static const byte MCP2515_MISO = 12 ; // SDO output of MCP2515
static const byte MCP2515_CS = 13 ; // CS input of MCP2515 (adapt to your design)
static const byte MCP2515_INT = 9 ; // INT output of MCP2515 (adapt to your design)
Mais voilà :
-
« No drive to deploy. »
Le chargement d'un sketch ne se fait pas par la ligne série sur Pico.
Quand tu branches le Pico, un disque USB nommé RPI-RP2 se monte et le fichier résultant de la compilation, un .uf2 est copié sur le disque du Pico. C'est comme ça que le flashage s'effectue.
De base, il faut que BOOTSEL soit enfoncé quand le Pico est mis sous tension. C'est ce qu'on doit faire la première fois que l'on flash le Pico avec le logiciel Arduino-Pico. Une fois chargé un sketch Arduino, ça se fait tout seul normalement.
J'ai le même phénomène que toi si coolterm est connecté au Pico. Essaye de le quitter pour voir ?
-
Est-ce que tu es en train de me dire qu'à chaque fois que je modifie mon sketch, il faut que je débranche l'USB, que j'appuie sur BOOTSEL ?
C'est juste là a première utilisation, non ? Ensuite on peut téléverser avec le bouton qui a une flèche j'espère ?
-
Non, je te disais que la première fois seulement il faut appuyer sur BOOTSEL. Ensuite il suffit de télécharger normalement.
-
Bon, j'avance. En fait, je n'ai le problème que lorsque j'affecte les pins qu'il me semble que tu as choisies sur ton montage :
static const byte MCP2515_INT = 9; // INT output of MCP2515
static const byte MCP2515_SCK = 10; // SCK input of MCP2515
static const byte MCP2515_MOSI = 11; // SI input of MCP2515
static const byte MCP2515_MISO = 12; // SO output of MCP2515
static const byte MCP2515_CS = 13; // CS input of MCP2515
Quand je joue le sketch de démo loopBackDemoRaspberryPicoPi (non modifié) je n'ai pas de problème. Mais si je met cette affectation de pins, ça plante :
//——————————————————————————————————————————————————————————————————————————————
// ACAN2515 Demo in loopback mode, for the Raspberry Pi Pico
// Thanks to Duncan Greenwood for providing this sample sketch
//——————————————————————————————————————————————————————————————————————————————
#ifndef ARDUINO_ARCH_RP2040
#error "Select a Raspberry Pi Pico board"
#endif
//——————————————————————————————————————————————————————————————————————————————
#include <ACAN2515.h>
//——————————————————————————————————————————————————————————————————————————————
// The Pico has two SPI peripherals, SPI and SPI1. Either (or both) can be used.
// The are no default pin assignments so they must be set explicitly.
// Testing was done with Earle Philhower's arduino-pico core:
// https://github.com/earlephilhower/arduino-pico
//——————————————————————————————————————————————————————————————————————————————
static const byte MCP2515_INT = 9; // INT output of MCP2515
static const byte MCP2515_SCK = 10; // SCK input of MCP2515
static const byte MCP2515_MOSI = 11; // SI input of MCP2515
static const byte MCP2515_MISO = 12; // SO output of MCP2515
static const byte MCP2515_CS = 13; // CS input of MCP2515
//——————————————————————————————————————————————————————————————————————————————
// MCP2515 Driver object
//——————————————————————————————————————————————————————————————————————————————
ACAN2515 can (MCP2515_CS, SPI, MCP2515_INT) ;
//——————————————————————————————————————————————————————————————————————————————
// MCP2515 Quartz: adapt to your design
//——————————————————————————————————————————————————————————————————————————————
static const uint32_t QUARTZ_FREQUENCY = 20UL * 1000UL * 1000UL ; // 20 MHz
//——————————————————————————————————————————————————————————————————————————————
// SETUP
//——————————————————————————————————————————————————————————————————————————————
void setup () {
//--- Switch on builtin led
pinMode (LED_BUILTIN, OUTPUT) ;
digitalWrite (LED_BUILTIN, HIGH) ;
//--- Start serial
Serial.begin (115200) ;
//--- Wait for serial (blink led at 10 Hz during waiting)
while (!Serial) {
delay (50) ;
digitalWrite (LED_BUILTIN, !digitalRead (LED_BUILTIN)) ;
}
//--- There are no default SPI pins so they must be explicitly assigned
SPI.setSCK(MCP2515_SCK);
SPI.setTX(MCP2515_MOSI);
SPI.setRX(MCP2515_MISO);
SPI.setCS(MCP2515_CS);
//--- Begin SPI
SPI.begin () ;
//--- Configure ACAN2515
Serial.println ("Configure ACAN2515") ;
ACAN2515Settings settings (QUARTZ_FREQUENCY, 125UL * 1000UL) ; // CAN bit rate 125 kb/s
settings.mRequestedMode = ACAN2515Settings::LoopBackMode ; // Select loopback mode
const uint16_t errorCode = can.begin (settings, [] { can.isr () ; }) ;
if (errorCode == 0) {
Serial.print ("Bit Rate prescaler: ") ;
Serial.println (settings.mBitRatePrescaler) ;
Serial.print ("Propagation Segment: ") ;
Serial.println (settings.mPropagationSegment) ;
Serial.print ("Phase segment 1: ") ;
Serial.println (settings.mPhaseSegment1) ;
Serial.print ("Phase segment 2: ") ;
Serial.println (settings.mPhaseSegment2) ;
Serial.print ("SJW: ") ;
Serial.println (settings.mSJW) ;
Serial.print ("Triple Sampling: ") ;
Serial.println (settings.mTripleSampling ? "yes" : "no") ;
Serial.print ("Actual bit rate: ") ;
Serial.print (settings.actualBitRate ()) ;
Serial.println (" bit/s") ;
Serial.print ("Exact bit rate ? ") ;
Serial.println (settings.exactBitRate () ? "yes" : "no") ;
Serial.print ("Sample point: ") ;
Serial.print (settings.samplePointFromBitStart ()) ;
Serial.println ("%") ;
} else {
Serial.print ("Configuration error 0x") ;
Serial.println (errorCode, HEX) ;
}
}
//----------------------------------------------------------------------------------------------------------------------
static uint32_t gBlinkLedDate = 0 ;
static uint32_t gReceivedFrameCount = 0 ;
static uint32_t gSentFrameCount = 0 ;
//——————————————————————————————————————————————————————————————————————————————
void loop () {
CANMessage frame ;
if (gBlinkLedDate < millis ()) {
gBlinkLedDate += 2000 ;
digitalWrite (LED_BUILTIN, !digitalRead (LED_BUILTIN)) ;
const bool ok = can.tryToSend (frame) ;
if (ok) {
gSentFrameCount += 1 ;
Serial.print ("Sent: ") ;
Serial.println (gSentFrameCount) ;
} else {
Serial.println ("Send failure") ;
}
}
if (can.available ()) {
can.receive (frame) ;
gReceivedFrameCount ++ ;
Serial.print ("Received: ") ;
Serial.println (gReceivedFrameCount) ;
}
}
//——————————————————————————————————————————————————————————————————————————————
-
Ouais
10, 11, 12, 13 c'est SPI1, pas SPI.
-
Ouais, ça marche comme cela. Mais je suis habitué à avoir des messages d'erreur à la compilation !
Tu ne voudrais pas publier ton code pour que je galère moins, parce que là je n'ai testé qu'à vide. Je ne sais pas encore si ça fonctionne vraiment une fois relié aux composants !!!
-
Je lis ça avec attention, car j’ai commandé 5 picos chez TME !
Merci les gars ;D
-
Tu ne voudrais pas publier ton code pour que je galère moins, parce que là je n'ai testé qu'à vide. Je ne sais pas encore si ça fonctionne vraiment une fois relié aux composants !!!
Voici.
Pour mon réseau j'ai fait un module qui regroupe un Pico, un 2515/2562, ma connectique CAN et une alimentation. Ça peut encore évoluer. Notamment je voudrais exposer les 5 broches GPIO du 2515. Je compte utiliser ce module sur toutes les cartes (aiguilles, signaux, remises, etc).
Qui dit module, dit bibliothèque, que voici (c'est du WIP) :
-
Merci Jean-Luc,
Ca devrait mieux marcher en effet. Je teste et je te redis !
-
Jean-Luc,
Un grand, grand, grand merci ! Bon ce qu'il faut surtout retenir, c'est de ne pas se melanger entre SPI et SPI1 car il n'y a aucune alerte, aucune erreur de compilation mais j'ai réussi à chaque fois à mettre en vrac mon port USB et l'impossibilité de faire un nouveau téléversement sans effacer la carte : Débrancher, appuyer sur BOOTSEL et rebrancher. Pénible à la fin.
Mon montage comporte donc un MCP 2515 et un MCP2562 ce qui va me permettre d'intégrer tout cela proprement sur un PCB. Mieux tout de même que le module Niren qui se ballade. Et cerise sur le gateau, Jean-Luc a prévu que l'horloge du MCP2515 soit alimenté par une PWM à 16Mhz générée directement pas le Pico. C'est ce que j'ai fait et cela fonctionne !
La programmation de la PWM sur le Pïco est très différente de ce que l'on utilise sur un Arduino, et je craignais d'avoir là aussi à passer beaucoup de temps.
Je n'ai pas seulement testé le loopback mais bien un envoi sur un bus CAN et j'ai un ESP sur le bus qui me dit bien qu'il reçoit des messages CAN de mon Pico.
Du coup, mon montage fonctionne, je vais pouvoir envoyer mes PCB en fabrication.
C'est beau la technique quand ça fonctionne.
Merci, merci encore !
-
Et cerise sur le gateau, Jean-Luc a prévu que l'horloge du MCP2515 soit alimenté par une PWM à 16Mhz générée directement pas le Pico. C'est ce que j'ai fait et cela fonctionne !
J'ai piqué le code à Pierre Molinaro ;)
La programmation de la PWM sur le Pïco est très différente de ce que l'on utilise sur un Arduino, et je craignais d'avoir là aussi à passer beaucoup de temps.
En fait côté Arduino, elle n'est pas différente. On a analogWrite comme d'habitude. C'est juste qu'ils y a quelques limitations par choix de conception. Le logiciel Arduino-Pico repose sur le SDK de Raspberry Pi mais comme il est plus simple, il est aussi moins riche que le SDK .
Côté Arduino, la fréquence est réglable via analogWriteFreq mais la fréquence est limitée à 1MHz maximum (bizarrement j'ai regardé le code et c'est 10MHz, je vais signaler la divergence). En effet, plus on monte en fréquence et plus la résolution de la PWM diminue. À 1MHz on a 64 pas d'après la doc et je suppose que Earle a préférer garder un nombre de pas suffisant pour la majorité des applications.
De ce que je comprends dans le code, analogWriteFreq sert à régler la fréquence mais seulement pour les analogWrite futurs. Les PWM déjà actives ne sont pas touchées. Autrement dit, la fréquence demandée est juste stockée dans une variable. C'est analogWrite qui programme la fréquence demandée en même temps qu'il règle le rapport cyclique. On peut donc avoir des PWM à des fréquences différents à conditions qu'elles soient sur des lices différentes.
Le Pico a 8 slices avec 1 compteur 16 bits et 2 PWM par slice. Le GPIO 22 est sur le slice 3A. Sur le slice 3B on a le GPIO 23. Donc sur le GPIO 23 on a potentiellement aussi une PWM à 16 MHz (si on le programme comme étant une PWM). Sur le Pico, le GPIO23 n'est pas exposé et sert à choisir le mode de fonctionnement de l'alimentation. Il n'y a donc pas lieu de mettre une PWM dessus.
Autrement dit, si on ne touche pas au GPIO22 et au 23, on peut faire ce que l'on veut avec les autres PWM sans affecter la fréquence du MCP2515 mais ça reste à vérifier.
Merci, merci encore !
C'est avec plaisir ! :)
-
Bonsoir à tous,
Je publierai le projet quand j'aurai reçu les PCB et assemblé les composants. Il faut aussi que je mette un peu d'ordre dans mon code.
Mais si certains parmi vous souhaitent avoir des informations ou même le code pour réaliser ces petites cartes Raspberry Pico - CAN plus rapidement, n'hésitez pas à vous rapprocher de moi.
Christophe
-
Je suis d’emblée intéressé. J’attend mon lot de chez TME. Et je potasse la doc en attendant.
Merci à vous deux.
Je pense qu’un article sur le pico sera à faire prochainement et j’y participerai.
-
Bonjour Dominique,
Le projet sur lequel je travaille est un système de rétro signalisation comparable au s88 de Marklin et se compose d’une part :
- D’un ou plusieurs décodeurs à 16 entrées reliées à des capteurs sur la voie. Les décodeurs envoient toutes les 100ms l’état des capteurs au travers d’un bus CAN.
- D’autre part, d’une passerelle qui reçoit l’état des capteurs pour chaque satellite et qui transmet cette information au gestionnaire (Rocrail, JMRI…) en TCP selon le protocole Marklin (mbus pour Rocrail).
Le code général pour les décodeurs et la passerelle sont ok que tu peux trouver ici :
Décodeurs : https://github.com/BOBILLEChristophe/picoDecoder/tree/main/src (https://github.com/BOBILLEChristophe/picoDecoder/tree/main/src)
Passerelle : https://github.com/BOBILLEChristophe/picoDecoder_to_rocrail_GW/tree/main/src (https://github.com/BOBILLEChristophe/picoDecoder_to_rocrail_GW/tree/main/src)
Christophe
-
Merci beaucoup Christophe et Jean-Luc ;D
J'ai installé la carte RPi Pico dans l'IDE Arduino et compilé avec succès la passerelle de Christophe (inspirée de SatellitePico de Jean-Luc).
Il faut bien utiliser la bibliothèque des cartes de earlephilhower qui permet de choisir la fréquence de 128MHz, contrairement à celle d'Arduino qui ne permet aucun réglage.
Mes cartes arrivent Mardi donc un peu impatient.
-
Bonjour ,
je confirme tout ce qui a été dit à propos du pwm du rp2040
(je ferais même remarquer ceci : ◦ Wrap and level registers are double buffered and can be changed race-free while PWM is running ; cad que ce mcu se prête bien à une génération de trames dcc avec des timing nickels , y compris pour le railcom ... donc pas comme l'esp32)
-
Il y a ici une preuve de concept de génération de signal DCC avec le PIO, comme ça aucun problème de timings :
https://github.com/pico-cs/firmware
-
oui , mais avec le pwm , je sais faire ; le pio , j'avoue ne pas m'être donné la peine de creuser le sujet ; car amha , il vaut mieux réaliser le dcc avec le pwm , et réserver le pio pour d'autres interfaces , notamment s'il y des signaux à traiter en entrée (can , loconet , sniffer ...)
c'est d'ailleurs pour cela que je suis adepte du stm32 : dcc , loconet , sniffer , fastoche avec les timers , et pour le can il y a un périphérique dédié