MBED, Arduino , STN1110 & BT

priusfan

darwiniste
Prius Touring Club
Inscrit
22 Oct. 2005
messages
7,041
Score de réaction
10,252
Localisation
Challans
Véhicule
RZ450e
Bonjour,

je me lance dans un nouveau projet basé sur Arduino & STN1110.

j'ai déja un arduino qui traine à la maison,(et je sais bricoler dessus)
j'ai contacté un gars qui a développé un shield stn1110

mon idée est de solliciter, collecter et traiter localement les données pour envoyer uniquement la synthèse en BT (cette idée me trotte dans la tête depuis un moment et rejoint la remarque de planétaire afin de bypasser les limites du BT).

intérêt du système: meilleur débit, utilisable toutes plateformes...

@suivre

edit: changement de fusil d'épaule.
plateforme retenue: mbed, accompagné d'un transceiver mcp2551 et d'un module BT.
 
Dernière modification par un modérateur:
Super.

je commence alors par un Kb de questions:

As-tu une idée du débit à soutenir du stn vers l'arduino ?
L'arduino a un buffer en entrée sur le port série ? Autre manière de poser la question: de quel temps disposes-tu pour faire autre chose entre 2 réceptions venant du stn ?
Quel format pour l'émission ? Elm ? ...

Comment va être définissable le(s) filtre(s) ? L'idéal étant bien sûr que le pc (ou la tablette) puisse envoyer à l'arduino la liste de ce qu'il souhaite.
Mémorisé ou pas ce serait alors au début de chaque trajet.
A priori tu vas gérer les pid sollicités par l'arduino. Aussi les passifs ? ;-)
 
Génial. Quelle équipe vous faites tous les 3.
 
salut les zartistes...

content d'avoir éveillé votre intérêt.
en ce qui concerne le type d'interface, le machin de sparkfun ne m’intéresse pas: beaucoup trop bas niveau, il faudrait passer un temps fou à stabiliser le machin en bricolant les registres;
le stn1110 je le pratique et connais ses limites. d'un point de vue coût, ce n'est pas moins cher... cf réponse en pj.

en ce qui concerne le débit, j'imagine de marcher à 500kbps.
le mode de fonctionnement, j'imagine de le paramétrer dans le programme (le programme se charge en usb).

le type de données fournies:
j'imagine qqc assez basique : pas de XML ni de JSON car l'enveloppe pèse beaucoup plus lourd que le contenu.
j'imagine des messages du genre:
<XYZ:99999.999>
ou XYZ est l'identifiant de la donnée, ce qui suit le : étant la valeur.

le système serait alimenté et démarrerait dès que le contact est mis; pas de conso lorsque l'on est pas sous tension.

pj réponse du fabricant du shield:
Hello,

Thank you for your interest.

The cost for the shield is 40euro + 6euro for airmail shipping to France.

I have use it for OBDuino project with good results.

http://code.google.com/p/opengauge/wiki/OBDuino



You will also need a cable like this… or you can make your own following the same pinout.

http://www.sparkfun.com/products/10087



My paypal account is kostas@sigal-tech.com if you want to buy it please send me also your shipping address.



Regards,

Kostas

@suivre, je commande le shield maintenant...
 
vite, vite,...
 
+ 1 000 000 :-d
 
j'ai commandé chez lextronic un pseudo arduino, c'est un chipkit uno 32.
avantage par rapport à l'original: beaucoup plus rapide avec une horloge à 80MHz au lieu de 16, donc théoriquement plus de latitude pour "bricoler".
pour info, il existe un module max32 qui intègre 2 interfaces CAN mais dont la programmation est largement en dehors de mes capacités...
j'ai également commandé en Grèce le shield stn1110.
j'ai par ailleurs commandé, il y a déja 3 semaines, un module BT.
je vais récupérer la prise diag sur le dongle brické qui traine chez moi et y raccorder un cable.
et maintenant, je vais replonger dans les sources de Attila ou plutôt ceux de astrand , qui en sont une adaptation au monde linux, pour étudier la programmation en C (++?) pour communiquer avec le module.
 
Quelle était la différence qui t'a fait renoncer à prendre le deuxième ?

Desires-tu juste des encouragements et applaudissements, ou est-ce que cela te serait utile que nous travaillions à plusieurs, à commencer par moi, sur ce projet ? (après le rallye)
 
par rapprt au UNO32, le max32 est plus grand, donc plus encombrant, ce qui n'est pas bon pour les boitiers dont je dispose,
il n'est pas + rapide,
il apporte plus d' IO et 2 ports CAN.
je n'ai pas l'usage de plus d'IO et pour le CAN, je vais utiliser le STN1110.

je vais utiliser un port série pour communiquer avec le STN

un écran LCD 4 lignes pendant la phase de mise au point

puis un deuxième port série pour renvoyer en BT le flux de résultats (à moins que ce soit en SPI ou I2C si cela est plus simple).

en ce qui concerne le dev, je serais content de le partager....
 
Petite parenthèse.

Avec les 2 ports can, tu as possibilité d'évoluer: cela peut devenir un bridge sur le bus can. C'est par exemple un bms+ ! Voire le graal des plugineurs : un bridge entre l'ecm et les autres ecu.

C'est plus le même but. C'est sûrement bien plus de boulot. Et cela ne se branche pas au même niveau. Là il faut être vraiment sur le bus, pas via une interface comme c'est le cas avec la prise diag.

Un bridge permet de savoir dans quel sens circulent les pid, si connecté entre les ecu, ce qui est plus compliqué que juste la prise diag.

Fin de la patenthèse.

Pourquoi n'utilises-tu pas un des 2 ports can sans utiliser un stn ?
Pour des questions de temps de réponse vis-à-vis du bus can ?
Parce que ce sera plus simple à programmer ?
 
des news
exit le UNO32, car comme les plateformes ARDUINO, la gestion des UART est ingérable à haute vitesse (libraries non finalisées).

maintenant, c'est au tour du mbed. j' en avais un dans un fond de tiroir (acheté à 秋葉原 avec le grand Yoshi, alias ken1784).

j'ai reçu un interface à base de STN1110.

avantage du mbed: il y a 3 ports série. cela permettra d'en connecter un au STN1110, le second en usb pour la mise au point avec un PC et le 3ème pour alimenter un truc en BT.

le mbed intègre également 2 ports CAN, mais leur programmation dépasse mes compétences et le temps que je suis prêt à passer sur ces tests.

mon objectif est simplement de voir combien de PIDs sollicités je peux obtenir par seconde en bypassant les interfaces BT et USB qui amènent toutes les 2 des délais que je trouve trop importants.

la partie séquenceur de demande des PIDs a été réécrite en C et je pense qu"elle est à peu prés au point.

si je n' obtiens rien de mieux que mon truc actuel en BT sous android, je recyclerai ces microcontroleurs pour des robots de type hexapod...
@suivre
 
finalement, je vais utiliser seulement le MBED avec un transceiver CAN.
voici qqs photos de ma maquette:
14f6467506257f.jpg

le transceiver:
14f64675052784.jpg

la prise:
14f64679e0c466.jpg


ce système permettrait de gérer à la fois les trames passives et les trames sollicitées (y compris réponses multitrames).
il y a la possibilité de mettre en place jusqu' à 512 filtres d'acceptance, ce qui soulagerait pas mal le programme (qui ne traiterait que les trames utiles).
j'ai trouvé des bouts de code à gauche et à droite pour m'éviter de réinventer l'eau tiède.
pour le moment, je vais tester les résultats avec un PC connecté en USB.
il est théoriquement possible de loguer ce que l'on souhaite sur carte SD.
il est assez simple d'intégrer un écran LCD; l'idéal étant 4 lignes de 20 caractères si on désire se fabriquer un scangauge plus complet..
ici, une carte (un peu grande) intégrant un lecteur de carte SD et l'interface CAN.
@kinetic: si le C++ est dans des cordes, voila un super projet pour toi....
 
je continue mon monologue :-D

le grand Yoshi (ken1784) réattaque le projet avec moi :-D

il m'a envoyé un mode opératoire du filtrage qu'il a testé et validé.

il s'est acheté un scangauge et bricole également avec un can232, mais il ne sait pas gérer le multitrame et il est paumé dans le décodage des trames.

je l'ai convaincu d'utiliser son mbed avec un LCD 4x20 pour remplacer son scangauge. son projet initial était de simplement logger tout le trafic passif sur SDCcard.

pour info, voici son programme de test; une fois isolée la fonction de filtrage, c'est plutot simple...:
Code:
// CAN_MONITOR with filtering  2012/03/21 ym1784

#include "mbed.h"
#include "CAN.h"

Serial pc(USBTX, USBRX); // tx, rx
DigitalOut led2(LED2);

// CAN2 on mbed pins 29(CAN_TXD) and 30(CAN_RXD) using MCP2551.
CAN can2(p30, p29);

/*--------------------------------------------
  setup acceptance filter for CAN controller 2
  original http://www.dragonwake.com/download/LPC1768/Example/CAN/CAN.c
  simplified for CAN2 interface and std id (11 bit) only
 *--------------------------------------------*/
void CAN2_wrFilter (uint32_t id)  {
    static int CAN_std_cnt = 0;
    uint32_t buf0, buf1;
    int cnt1, cnt2, bound1;

    /* Acceptance Filter Memory full */
    if (((CAN_std_cnt + 1) >> 1) >= 512)
        return;                                       /* error: objects full */

    /* Setup Acceptance Filter Configuration
      Acceptance Filter Mode Register = Off  */
    LPC_CANAF->AFMR = 0x00000001;

    id |= 1 << 13;                        /* Add controller number(2) */
    id &= 0x0000F7FF;                            /* Mask out 16-bits of ID */

    if (CAN_std_cnt == 0)  {                     /* For entering first  ID */
        LPC_CANAF_RAM->mask[0] = 0x0000FFFF | (id << 16);
    }  else if (CAN_std_cnt == 1)  {             /* For entering second ID */
        if ((LPC_CANAF_RAM->mask[0] >> 16) > id)
            LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] >> 16) | (id << 16);
        else
            LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] & 0xFFFF0000) | id;
    }  else  {
        /* Find where to insert new ID */
        cnt1 = 0;
        cnt2 = CAN_std_cnt;
        bound1 = (CAN_std_cnt - 1) >> 1;
        while (cnt1 <= bound1)  {                  /* Loop through standard existing IDs */
            if ((LPC_CANAF_RAM->mask[cnt1] >> 16) > id)  {
                cnt2 = cnt1 * 2;
                break;
            }
            if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000FFFF) > id)  {
                cnt2 = cnt1 * 2 + 1;
                break;
            }
            cnt1++;                                  /* cnt1 = U32 where to insert new ID */
        }                                          /* cnt2 = U16 where to insert new ID */

        if (cnt1 > bound1)  {                      /* Adding ID as last entry */
            if ((CAN_std_cnt & 0x0001) == 0)         /* Even number of IDs exists */
                LPC_CANAF_RAM->mask[cnt1]  = 0x0000FFFF | (id << 16);
            else                                     /* Odd  number of IDs exists */
                LPC_CANAF_RAM->mask[cnt1]  = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | id;
        }  else  {
            buf0 = LPC_CANAF_RAM->mask[cnt1];        /* Remember current entry */
            if ((cnt2 & 0x0001) == 0)                /* Insert new mask to even address */
                buf1 = (id << 16) | (buf0 >> 16);
            else                                     /* Insert new mask to odd  address */
                buf1 = (buf0 & 0xFFFF0000) | id;

            LPC_CANAF_RAM->mask[cnt1] = buf1;        /* Insert mask */

            bound1 = CAN_std_cnt >> 1;
            /* Move all remaining standard mask entries one place up */
            while (cnt1 < bound1)  {
                cnt1++;
                buf1  = LPC_CANAF_RAM->mask[cnt1];
                LPC_CANAF_RAM->mask[cnt1] = (buf1 >> 16) | (buf0 << 16);
                buf0  = buf1;
            }

            if ((CAN_std_cnt & 0x0001) == 0)         /* Even number of IDs exists */
                LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | (0x0000FFFF);
        }
    }
    CAN_std_cnt++;

    /* Calculate std ID start address (buf0) and ext ID start address <- none (buf1) */
    buf0 = ((CAN_std_cnt + 1) >> 1) << 2;
    buf1 = buf0;

    /* Setup acceptance filter pointers */
    LPC_CANAF->SFF_sa     = 0;
    LPC_CANAF->SFF_GRP_sa = buf0;
    LPC_CANAF->EFF_sa     = buf0;
    LPC_CANAF->EFF_GRP_sa = buf1;
    LPC_CANAF->ENDofTable = buf1;

    LPC_CANAF->AFMR = 0x00000000;                  /* Use acceptance filter */
} // CAN2_wrFilter

int main() {
    pc.baud(921600);
    pc.printf("CAN_MONITOR 921600 bps\r\n");

    // 500kbit/s
    can2.frequency(500000);
    CANMessage can_MsgRx;

    CAN2_wrFilter(0x0B4);
    CAN2_wrFilter(0x1C4);
    CAN2_wrFilter(0x245);
    CAN2_wrFilter(0x3D3);
    CAN2_wrFilter(0x498);
    CAN2_wrFilter(0x4A6);

    while (1) {
        // send received messages to the pc via serial line
        if (can2.read(can_MsgRx)) {
            pc.printf("t%03X%d", can_MsgRx.id, can_MsgRx.len);
            for (char i=0; i<can_MsgRx.len; i++) {
                pc.printf("%02X", can_MsgRx.data[i]);
            } // for
            pc.printf("\r\n");
            // toggle led2
            led2 = !led2;
        } // if
    } // while
} // main
 
Continue ton monologue, Priusfan, on te suit. Intrinsèquement, l'arduino uno semble capable de causer USB très vite. J'ai adoré la page d'introduction à la programmation arduino sous eclipse, qui vise à causer avec Android : http://android.serverbox.ch/?p=427 Et ça marche à tous les coups, contrairement à l'IDE arduino (sous Ubuntu 11.10). Les pages suivantes (427 et 549) traitent de l'USB. Je n'ai pas encore testé.
 
moi aussi j'écoute.
 
Moi aussi ... mais je ne suis pas certain de bien comprendre.
Enfin, si un peu quand même. :-D
 
Moi aussi, j'écoute et je lis....:cool:
 
des news:
cette semaine, lors de tests, le vieux PC que j'utilisais a eu un "burnout" et a cramé la partie USB de mon mbed....

moralité, j'en ai commandé un autre ainsi qu'un ensemble pour communiquer en BT; il s'agit d'un BluetoothBee et d'un UartSBee; j'ai choisi ces modules pour leur interfaçage en 3.3V.

Yoshi continue également ses tests et devrait me communiquer les résultats d'un programme de séquenceur que je lui ai envoyé...
il a attiré mon attention sur le fait qu'utiliser un afficheur LCD est très pénalisant en timing:
Code:
---------
However, it takes more than 160 usec to display a character on the LCD.

Code:
---------
void TextLCD::writeByte(int value) {
     _d = value >> 4;
     wait(0.000040f); // most instructions take 40us
     _e = 0;
     wait(0.000040f);
     _e = 1;
     _d = value >> 0;
     wait(0.000040f);
     _e = 0;
     wait(0.000040f);  // most instructions take 40us
     _e = 1; }
---------
So, we will miss a lot of CAN messages during the LCD access.

donc dans le cas où l'on désire utiliser un LCD, il est probablement préférable d' en utiliser un qui communique en port série (avec un buffer suffisant)...

@ suivre
 
[Les risques du métier]
Hier je faisais des tests avec mon pc sur lequel j'avais un convertisseur usb-rs232, pour mettre au point le contrôle de charge sur le chargeur que j'ai enfin reçu.
A un moment le pc s'est trouvé planté et j'ai dû le rebooter avec le bouton power.
Pourtant entre le convertisseur et le chargeur c'est un optocoupleur.
[/Les risques du métier]
 
en attendant mon nouveau mbed, voici des nouvelles, que je considère encourageantes, de Yoshi:
Hi frenchie,

I tested your CANUSB32.
The filtering function worked as expected.
But, the 0x7Ex messages never received, and a lot of space characters (0x20: total approx 4k bytes) sent to the terminal a several seconds later.
Then, my Prius got "Hybrid System Error" and an explanation mark "!" with a triangle displayed on the panel.

I power-cycled my Prius several times, the error was gone.

Anyway, regarding to the passive messages, I got one byte shorter than expected.
Your source code says...
Code:
for (char i=0; i<msg.len-1; i++) {
I changed it as follows, then it worked as expected.
Code:
for (char i=0; i<msg.len; i++) {
By the way, I also tried the Moon Light's CANUSB30 code.
It also caused the "Hybrid System Error", and the error never cleared by Prius power-cycle.
I use ScanGauge to clear the error, then Prius was back to normal.

Regards,
Yoshi
techniquement, je crois savoir d'où vient le pb des messages sollicités:
un pb de *pointer dans une structure d'arrays external, qui fait que l'on balance n'importe quoi n'importe où...
comme je suis une bille en C++, je vais tout recentrer dans le corps du programme principal et je suis persuadé que cela ira beaucoup mieux....
j'attends avec impatience mon nouveau mbed...
 
Très encourageant en effet. Il arrive à effacer les dtc

Frenchie est très joueur, il me semble :ouioui:
 
très joueur en effet...

mais il ne gagne pas à tous les coups: ma prise diag ne répond plus...

Thierry m' a ramené l'interface obdlink et elle est également muette...

je n'ai pas les schémas sous la main, (ils sont à mon bureau à paris) et je les regarderai vendredi pour pister les équipements qui sont défectueux.

une première hypothèse: à force d'enquiller des trucs d'origine + ou - douteuse dans cette prise diag, il n'est pas impossible que un ou plusieurs connecteurs soient sortis de leur logement (en reculant).
ce qui me fait écrire cela: je trouve qu'il y a énormément de jeux quand je branche qqc dedans, y compris le gros Y qui comprend les 16 pins...

je vais donc consulter la doc, puis voir comment démonter cette prise diag; il faudra jouer au contorsionniste...

@ suivre

ps: la watture marche normalement et consomme même moins que d'habitude :-D
 
Tu as aussi essayé le moongose ?
Autre idée mais j'y crois pas trop : débrancher la 12v.
 
Pages vues depuis le 20 Oct 2005: 308,335,467
Retour
Haut Bas