• L'Assemblée Générale du Prius Touring Club aura lieu le 7 décembre 2024 du côté de Rennes. Si vous êtes adhérent renseignez-vous ici.

MBED, Arduino , STN1110 & BT

  • Initiateur de la discussion Initiateur de la discussion priusfan
  • Date de début Date de début
Merci priusfan, j'ai déjà une carte. Elle est bien plus compliquée d'usage et d'ailleurs voici le code qui la fait marcher de manière un peu rustique : https://docs.google.com/file/d/0B67T1kwFymSWMVVXTXUtQ0RjZmM/edit?usp=sharing.

Mais de toutes manières l'arduino 16 bits 16 MHz est trop lent pour la capture de toutes les trames vers USB.

Je vais passer à Stellaris/Tiva 32 bits. Stellaris ne peut pas écrire sur une clé USB et il est bradé à 8 $ port et taxes comprises sur le site http://www.ti.com/

La carte de luxe Tiva est vendue 13 $ chez TI https://estore.ti.com/Tiva-C-LaunchPad.aspx et 20 EUR TTC chez Farnell http://fr.farnell.com/texas-instruments/ek-tm4c123gxl/tm4c123g-launchpad-tiva-c-eval/dp/2314937

Il faut juste ajouter un transmetteur. D'ailleurs, priusfan, comment as-tu dimensionné les 3 résistances et 2 capas qui contrôlent les fronts des signaux du MCP2551 ? Si on ne met rien en dehors de la capa d'alim, on observe plein de parasites ?

Autre question, comment as-tu choisi les fils des prises RJ-45 ? J'ai l'impression que tu n'as pas pris une paire torsadée pour le signal. Je me trompe ?
 
Dernière édition:
le code que tu as mis en lien ci-dessus est prévu pour une autre carte (celle de sparkfun, beaucoup + primitive).

le cablage RJ45 n'utilise pas une paire pour les signaux CAN-H & CAN-L.
c'est effectivement une hérésie, mais c'est celle du scangauge: on m'avait demandé de pouvoir réutiliser le cordon du scangauge....

pour le mcp2551, regarde le schéma en lien.

ce n'est pas vraiment critique.

avec le mbed, j'ai utilisé ceci
 
Kinetik, tant que tu ne mets pas ma P2 en sapin de Noel, tu peux ajouter toutes les trames que tu veux.
 
Oui, très primitive la carte. Elle contient un MCP2515. Si tu as idée en jetant un coup d'oeil sur le code pourquoi si je remplace "message.header.length = 8" par "...= 3" les ECU ne répondent plus, je serai moins idiot. Mais ce n'est pas une priorité.

Je compte utiliser des RJ45 mais sans rester dans l'hérésie (sauf pour un connecteur, si je veux rester compatible). Tu as une idée s'il existe un standard ? Et pour du 0-5V voire du 0-3V sur cette même prise ?

Dans tes deux liens sparkfun, la ligne est court-circuitée par 560/2 = 280 pF. C'est grosso-modo équivalent à quelques mètres de cable de plus sur le stub. Mais fortement c'est tempéré par 2*100 = 200 ohm en série avec cette capa qui n'est pas petit devant 120 ohm.

Mais dans ton lien que je corrige en http://priusfan.info/canmonitor/mbed/Schéma Prius-1.pdf, je suis horrifié par le court-circuit de 100/2 = 50 nF = 50000 pF. C'est l'équivalent de plusieurs centaines de mètres de cable. Et les résistances en parallèle n'atténuent rien. Les mettre au + c'est d'ailleurs bizarre pour une ligne différentielle. La constante de temps 50 nF × 60 ohm vaut 3 microsecondes. C'est énorme. Si on mettait 100 circuits comme ceci sur le bus, on aurait 0,3 ms ! Il doit y avoir erreur. Ne serait-ce pas 100 pF au lieu de 100 nF ?

[edit] En remontant les posts, j'ai trouvé la confirmation de mes doutes peut-être là : http://priusfan.info/canmonitor/mbed/mbed_implant.jpg Est-ce que les 100 ohm sont bien en série avec les capas dans cette image ?
 
Dernière édition:
je ne connais pas (et ne veux pas connaitre) le MCP2515, j'ai passé l'age de jouer avec les registres...
par contre, je peux te filer mon shield à base de stn1110: on communique via un port série et basta.

en ce qui concerne le mcp2551, les 2 résistances ne vont pas au + mais à la broche VREF. cela permet, si besoin, de préciser le point milieu du signal différentiel.
d'après mes souvenirs, les capas que j'ai mises sont des 560pF.
 
Je te comprends pour la préférence envers le stn1100. Mais en terme d'efficacité avec de microcontrôleurs on peut rencontrer ses limites. Tu as quoi sur le MBED ? Tu ne peux pas récupérer ce shield ?

J'aurais dû mieux lire la doc pour VREF. Mais maintenant que je l'ai mieux lue, je ne comprends pas l'intérêt des deux résistances. VREF est sensé être une source de tension qui délivre moins de 50 µA. Pour ce courant, la tension varie déjà de 0,05V. J'en conclus que la résistance interne de la source est de 1000 ohm. Ce n'est pas négligeable devant les 1430 ohm du schéma. De plus, si jamais un des fils est en contact avec le 14V, la puce résistera au niveau des pattes CAN, mais peut-être pas au niveau de VREF, qui se trouvera monter à 7V et la doc l'interdit.

Mais si le nouveau schéma suit le modèle sparkfun, qui ne se connecte pas à VREF et qui met en série 100 ohm et 560 pF vers la masse, c'est sans problème.
 
le mbed est super:
il y a un proc puissant et rapide: 32bits @ 96MHZ,
plein d'interfaces dont 2 CAN & 3 UART, détails ici

avantages: pas besoin d'un outil de dev compliqué à paramétrer ni de programmateur.

son seul inconvénient est un prix nettement + élevé que les autres microcontrôleurs.

ce que tu fais avec tes 2 interfaces (obdlink & arduino) se fait sans pb avec 1 mbed sur un seul port CAN:

  • écouter toutes les trames qui t’intéressent (il y a un filtrage plutôt sympa).

  • lancer périodiquement des requêtes (tout en continuant à traiter les trames passives).

  • décoder ce qui t'intéresse,
et en plus:

  • faire des calculs divers (intégrations / moyennes).

  • envoyer des synthèses, soit en USB, soit en BT et éventuellement sur écran LCD.
  • tu peux même imaginer en faire un datalogger autonome en archivant sur clé USB.
et pour conclure: c'est beaucoup moins encombrant que tes montages et cela consomme également nettement moins....

ps: mon approche initiale était plutôt d'utiliser un machin type "arduino de course" et le shield stn1110 ou bien le port CAN intégré sur certains microcontroleurs, mais il n'y avait rigoureusement aucun exemple utilisable d'usage du CAN.
 
Je suis tout à fait dans ta démarche. Le Tiva que je vais évaluer est très similaire. 80 MHz au lieu de 96 MHz mais cortex M4F au lieu de M3. Il y a un DSP pour des calculs très rapides. Tout plein d'interfaces aussi mais pas ethernet. Sur la même carte à 10 EUR il y a 2 de ces merveilles. La seconde sert au déverminage du code qui s'exécute sur la première. Il n'y a qu'un port CAN, les pattes de l'autres étant prises par la communication entre les deux puces. J'imagine qu'on peut développer une bonne part du code en commun sur les deux systèmes MBED et Tiva.

J'ai fait une bétise en commandant les interfaces physiques MCP2551. Elles sont dans un format minuscule au pas de 1.27 mm.
 
Je suis très content de ma carte Tiva. La sortie USB "UART" au travers de la puce secondaire n'atteint pas les 2 Mbits/s, mais j'ai obtenu 3,5 Mbits/s en écho sur le port USB direct en mode "bulk data transfer" décrit chapitre 7 de http://processors.wiki.ti.com/index.php/Getting_Started_with_the_TIVA™_C_Series_TM4C123G_LaunchPad

Sous Linux, après un éventuel "sudo modprobe usbserial vendor=0x1cbe product=0x0003" le device apparait comme un /dev/ttyUSB sur lequel on peut lire et écrire directement sans définir de vitesse de transfert.

L'afficheur tactile 320×240 (chapitre 10 du lien ci-dessus) est un peu rustique. Il ne faut pas espérer tracer des compteurs circulaires avec. Mais on peut afficher 200 nombres de 4 chiffres rafraichis 3 fois par secondes sans problème. Bon, je doute avoir besoin de tant de données.

J'ai seulement parcouru la bibliothèque CAN. Cela ne me semble pas trop compliqué. Il y a 32 mémoires de trames. Deux pourraient suffire. Pour écrire un paquet, on écrit dans une de ces mémoires en indiquant qu'on veut transmettre. Pour lire, on écrit aussi dans une de ces mémoires mais on indique ce qu'on veut recevoir, avec un filtrage éventuel. Lorsque la trame est reçue, une interruption est declenchée dans laquelle on va mettre à 1 une variable globale vous_avez_un_message_dans_la_boite_xx avec xx = 1 à 32. C'est la boucle principale qui se charge d'aller lire la trame dans la mémoire lorsqu'elle voit cette variable à 1, et remet cette variable à 0. Cela ressemble au MBED ? Pour lire les paquets multitrames, on peut j'imagine prévoir utiliser plusieurs des 32 boites, mais ce n'est pas obligatoire. Je n'ai pas le temps de me pencher plus dessus avant 10 jours.

Je n'ai pas testé l'écriture sur clé USB. Il faut déjà que je trouve le cable OTP. Chez les marchands de tablettes on trouve cela il me semble.

Pour des affichages de luxe genre Torque, la communication avec une tablette est nécessaire. Je ne connais rien à bluetooth. Qu'utilisez-vous avec MBED ?

Pour baisser la consommation à l'arrêt sans débrancher le boitier, j'imagine une alim 12V -> 3.3 V basse consommation avec un comparateur qui hiberne le circuit lorsque la tension est inférieure à 13 V. Il faut aussi que ce comparateur déclenche ou non une alimentation 5 V. Vous avez déjà conçu quelque chose de semblable ?
 
intéressant ton truc.
Cela ressemble au MBED ?
non pas vraiment:
a) on utilise des filtres de façon à ne voir/traiter que ce qui nous intéresse.
b) pour la réception, on utilise un "ring buffer" de façon à continuer à recevoir lorsque l'on est occupé à autre chose.

Je ne connais rien à bluetooth. Qu'utilisez-vous avec MBED ?

Le BT est assez simple: tu connectes RX & TX du module BT à un UART .
il est quand même souhaitable de paramétrer un baudrate suffisant pour ton besoin.
2 exemples :
avec Torque, en BT @ 115kbps, tu peux espérer 60 requetes/sec
sur la iOn avec le module à base de STN1110 @500kbps, je reçois sans pb 405 trames/sec.
tu trouves des modules BT corrects dans le monde du multiwii.

Xavier
ps: à propos de modules BT, tu as celui-ci (en France) qui marche bien.
 
Le ring buffer, il est intégré à la puce MBED ou à la bibliothèque ? Et dans ce cas, il est géré dès l'interruption, ou bien au niveau de la boucle générale ?

J'avais oublié, dans la Tiva, il y a une assez grosse bibliothèque en ROM http://www.ti.com/lit/ug/spmu350/spmu350.pdf. C'est appréciable pour ne pas occuper de la place en Flash. La taille exacte de la ROM semble presque un secret de fabrication http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/262880.aspx

Pour le Bluetooth, bien que l'affichage consomme énormement de pattes (17), J'ai encore 3 UART. Un pour le GPS, et donc un pour le BT.

J'ai un conflit entre SPI et I2C. Les solutions que je vois :
- Je déroute au fer à souder des pattes du LCD et je recode un peu le driver.
- Je fais du "software I2C" (j'imagine que c'est du I2C sur GPIO standard et il me reste 6 pattes).
- Je n'utilise pas SPI donc pas directement de mémoire SD.
 
Le ring buffer, il est intégré à la puce MBED ou à la bibliothèque ? Et dans ce cas, il est géré dès l'interruption, ou bien au niveau de la boucle générale ?...
Il est fait à la mimine:
sur une base de Yoshi, revisité à la sauce conflanaise.
rien de tel que le sur-mesure.
 
J'en conclus que ce n'est pas 1, mais 2 ou 3. Comme je connais assez mal les problèmes liés aux interruptions, je ne sais pas si on peut oser 2 et y passer trop de temps. Mais 3 c'est sans doute le mieux.

Il y a des anneaux en prêt a porter chez Tiva. Cela ressemble à http://lumweb.googlecode.com/svn/branches/graphic-branch/Webinterface/SerialComm/ringbuf.c En fait, la boite Luminary
icro qui a créé ce code a été rachetée par TI en 2009. Le code Tiva est accessible après inscription et promesse de ne pas redistribuer à des états que n'aiment pas nos amis US. Il y a toujours écrit aussi la phrase peu claire

<<You may not combine this software with "viral" open-source software in order to form a larger program.>>

Mais ils ont supprimé

<<Any use in violation of the foregoing restrictions may subject the user to criminal sanctions under applicable laws, as well as to civil liability for the breach of the terms and conditions of this license.>>
 
si tu as des insomnies, je t'invite à analyser le code joint.
c'est le truc principal pour le mbed.
 

Pièces jointes

J'ai jeté un bref coup d'oeil. C'est la version pour la Pijot. Il ne me semble pas qu'il y ait de gestion fine du temps, c'est dommage pour le timetamp. J'imagine qu'il est possible de récupérer le 32768ème de seconde Pas non plus de conservation de l'heure exacte par hibernation du MBED ?

Si je comprends bien, "can_check" est défini ailleurs comme la fonction appelée par l'interruption CAN. C'est là dedans que les messages sont lus. Il y a même des fprintf. N'est-ce pas dangereux de charger ainsi cette fonction ? Je préfère repousser les transferts dans la boucle while(1).

Les requêtes semblent transmises toutes les 100 trames passives. C'est un choix au premier abord bizarre, j'imaginais plutôt une période de temps définie. Mais ce choix permet de ne rien demander tant que la voiture ne tourne pas. Finalement, il pourrait être opportun de faire la requête en direction de l'ECU moteur dès que le moteur a émis une trame bien précise à décider, idem etc pour les autres ECU. Cela permettrait un fonctionnement plus déterministe.
 
Si je comprends bien, "can_check" est défini ailleurs comme la fonction appelée par l'interruption CAN.
Oui et non... ce n'est pas ailleurs, mais dans la routine Init can2.attach(&can_check);

C'est là dedans que les messages sont lus. oui
Il y a même des fprintf.
non , c'était uniquement pour la phase de mise au point (loglevel=0)

Les requêtes semblent transmises toutes les 100 trames passives.
en fait, pour la iOn, il n'y a aucune requête.
pour HSD cette valeur est de 2.

 
Effectivement je n'avais pas mon éditeur favori pour trouver les chaines de caractères "can_check" et celui que j'ai utilisé ne retourne pas automatiquement au début du fichier.

Une requête toutes les 2 trames passives, cela semble monstrueux. Mais c'est après filtrage sévère j'imagine.
 
non, ce n'est pas monstrueux: il s'agit du nb de trames attendu entre la fin de la réponse d'une requête et le lancement de la suivante.
cela permet de lancer jusqu' à 110 requêtes/sec sans inconvénients ( à défaut d’intérêt).

par ailleurs, je procède à du "CAN STUFFING", il s'agit de regrouper plusieurs demandes dans une seule.
exemple:
REQUEST 7E0 10 04 01 06 07 0E 00 00 00 // STF LTF IGN_adv
est équivalent à
REQUEST 7E0 10 02 01 06 00 00 00 00 00
REQUEST 7E0 10 02 01 07 00 00 00 00 00
REQUEST 7E0 10 02 01 0E 00 00 00 00 00

ci-joint un fichier de paramètres utilisé par Thierry.
dans ce fichier, il y a, à la fin, mes requêtes pour la P3
 

Pièces jointes

C'est bien de savoir que les ECU ne sont pas surchargés par toutes ces requêtes.

Oui, c'est très bien de regrouper les requêtes. La limite est 7 il me semble. L'appel direct à l'ECU comme 7E0 c'est très bien. J'avais utilisé le broadcast 7DF avec mes premiers essais et j'ai eu la surprise de voir que plusieurs ECU se mêlaient de répondre à des questions qui ne devaient pas trop les concerner.

Je vois que dans ton fichier de paramètres il est fait allusion à quelques notions obsolètes. J'imagine que le PID 520 est multiplié par la vitesse moteur. C'est dommage. Il vaudrait mieux sommer les valeurs tout en contrôlant qu'on n'a pas laissé passé de PID : Il faut compter en parallèle le nombre de tours moteur et le 520 tombe exactement tous les 20 tours.

Le PID 5A4 fait allusion à des % alors qu'il fournit directement des L.

Je profite aussi de l'occasion pour te demander de vérifier si l'ODO 230 est calculé avec le bon modulo.
 
hello,
je ne saurais pas te répondre au sujet des trucs obsolete...

en effet, j'ai arrêté de m'amuser avec les HSD en aout 2012 à cause que la iOn monopolise mon attention ....
 
Kinetik, pour répondre à pas mal de tes questions :

Dans mon fichier, j'avais copié collé des bouts de PCM pour ne pas à avoir à chercher ailleurs. Dans PCM, et le MBED, je calcule le volume toujours de 2 façons, mais je n'utilise que la somme du PID 520, et plus le calcul avec les tours moteur. Je pense que je vais arreter d'ailleurs ce calcul inutile. Comme d'ailleurs arréter de calculer la distance à partir du pid 0B4.

Pour le PID 230 (ou tmp est la distance parcourue depuis le dernier PID230 reçu) :
tmp = pid230 - lastpid230;
if (tmp < 0) tmp += 0x10000;
Donc je suppose que je fais le bon modulo.

J'utilise depuis longtemps le contenu du réservoir en litre (5a4), donc directement la valeurs; cela évite de faire des calculs inutiles.

Les temps sont donnés à l'intérieur du MBED en 10-6 seconde.

Si on accroche une pile au MBED, il y a conservation de l'heure, mais elle shifte. Je n'ai pas mesuré de combien. Ni si le temp donné en 10-6 seconde shiftait aussi comme l'horloge.

Le ring buffer ne sert presque à rien, car quand il commence à se remplir, c"est trop tard. C'est que le code derrière utilise plus de temps qu'il lui reste compte tenu du temps nécessaire pour accumuler les trames qui arrivent.
La priorité est à l'acquisition des trames, il me semble, par un mécanisme d'interruption.
Et quand le filtre est insuffisant, alors cette acquisition déborde et ne laisse plus de temps au traitement de ce qui a été reçu.
Maintenant, quand il reste du temps, il vaut mieux eviter de faire des traitement qui prennent trop de temps, sinon buffer overflow.

J'ai du ecrire quelque part dans une des discussions quel était, compte tenu des trames "utiles" actuelles, comment le temps se répartissait entre ne rien faire, acquerir les trames et les traiter.

Je ne débranche jamais le boitier, sauf quand je veux faire des tests en étant au chaud chez moi, ou quand je suis copilote sur une voiture qui n'est pas la mienne. Je n'ai plus de pile sur le MBED (qui servait uniquement, il me semble, à conserver l'horloge). Et je n'ai pas eu de problème de panne, même quand j'avais ma batterie 12v faible. Mais j'applique la même regle qu'avec les autre boitiers, je débranche mon MBED quand je pars en vacances sans la voiture.
 
C'est parfait pour le modulo. À une époque il y manquait 1. Eh bien pour les microcontrôleurs je vais suggérer le retirer pour le remettre...

L'avantage c'est que toutes les variables sont des unsigned 16 bits. Il ne faut pas oublier le +1 à la fin.

increment = ((pid230 >= lastpid230) ? (pid230 - lastpid230) : ((0xffff - lastpid230) + pid230 + 1));
 
Le ring buffer ne sert presque à rien, car quand il commence à se remplir, c"est trop tard. C'est que le code derrière utilise plus de temps qu'il lui reste compte tenu du temps nécessaire pour accumuler les trames qui arrivent.
La priorité est à l'acquisition des trames, il me semble, par un mécanisme d'interruption.
Et quand le filtre est insuffisant, alors cette acquisition déborde et ne laisse plus de temps au traitement de ce qui a été reçu.
Maintenant, quand il reste du temps, il vaut mieux eviter de faire des traitement qui prennent trop de temps, sinon buffer overflow.

D'accord avec l'idée générale (il faut vider le seau au moins aussi vite qu'il se remplit, sinon ça déborde), mais le ring buffer permet quand même d'absorber certains pics de traitement:
par exemple:
certaines trames vont nécessiter des traitements plus lourds que d'autres.
on peut envisager des traitements de synthèse déclenchés par un timer (ie chaque seconde) .
 
C'est parfait pour le modulo. À une époque il y manquait 1. Eh bien pour les microcontrôleurs je vais suggérer le retirer pour le remettre...

L'avantage c'est que toutes les variables sont des unsigned 16 bits. Il ne faut pas oublier le +1 à la fin.

increment = ((pid230 >= lastpid230) ? (pid230 - lastpid230) : ((0xffff - lastpid230) + pid230 + 1));

Mon écriture est plus facile à comprendre, et la tienne est plus impressionnante.
 
@priusfan,
Mais je suis d'accord, je l'ai gardé ton anneau
 
Pages vues depuis le 20 Oct 2005: 316,276,809
Retour
Haut Bas