• 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
@2009Prius
the typo is exactly what ken1784 told me 2 weeks ago...
He was right, and I forgot to change in the program 😳

Anyway, I found a bug on your code (from moonlight's one).
If "reqTbl" size is 100, the index number should be from 0 to 99, not to 100.
It looks moonlight's code goes to 100 on above case.
Code:
msg_ReqIdx++; if (msg_ReqIdx > req_NumTbl) { msg_ReqIdx = 0; }
I believe it should be...
Code:
msg_ReqIdx++; if (msg_ReqIdx >= req_NumTbl) { msg_ReqIdx = 0; }
about the sequencer, you are right the name "freq" is not a good choice, but maybe in japanese that means "periodicity" 😉, I will change the name...

And now, as you have nothing to do but waiting for your mbed 8)...
what do you think about map, bitset and mask ?
the idea would be, for passive frames, to transmit only interesting bytes to improve the qty of transferred data.
I imagine to store in filters.txt something like:
//id "mask stored as hex"
0B4 06 // 06 is '00000110' so we could send id + 2 interesting bytes instead of id + 8 bytes

I know how to fill the map from the file,
I know how to get the value for the map when working with an id,
but I feel a bit stupid how to convert this char to an 8 bit mask...
 
If I understand correctly you will read from the filter.txt file a hex integer value "map" and use it to transmit only interested bytes from mbed to PC. (Mbed still receive and temporarily store each filtered complete passive CAN message to check the checksum first, then decide whether to transmit to PC.) I think this will do: (convert to mbed language of course)

Code:
#include <iostream>
#include <cstdlib>
#include <bitset>

using namespace std;

/*
 test map and mask to transmit from mbed to PC only selected bytes
 */
int main(int argc, char** argv) {
    
    int map = 0xE6; // will be read from filter.txt
    bitset<8> mask(map);
    
    for (int j=0; j<8; j++){
        if (mask[7-j]){
            cout<<"Transmit byte "<<j<<endl;
        } else {
            cout<<"Don't transmit byte "<<j<<endl;
        }
    }
    return 0;
}
Please check the order of bits on the mbed. On my PC I need
Code:
mask[7-j]
but on mbed maybe just
Code:
mask[j]
.
 
Hello my teacher :-D:jap:
here is the original code I would like to adjust:
where w_data is : char w_data[8];
if (w_id < 0x700) { // passive frame ,
msg_ReqFrameW--;

pc.printf("%03X",w_id);
for (int i=0; i<w_len; i++) {
pc.printf("%02X",w_data);
} // for
pc.printf("\r\n");.......
/*
so I started something like:
if (w_id < 0x700) { // passive frame ,
msg_ReqFrameW--;

// trying to use the mask for this Id...
char tmask;
// first get the mask associated to this id
tmask=id_mask[w_id]; // id_mask is a map, w_id is the key, we get a char

// and now, we will try convert w_data to y_data using tmask as a mask
// where y_data is also : char y_data[8];
// y_data should contain only the usefull bytes
// if w_data contains a0 a1 a2 a3 a4 a5 a6 a7
// and the mask contains x06 that means '00000110'
// y_data should contain only a5 a6
just help me to fill the blanks.........

pc.printf("%03X",w_id);
for (int i=0; i<w_len; i++) {
pc.printf("%02X",w_data);
} // for

for (int i=0; i<y_data.size; i++) {
pc.printf("%02X",y_data);
} // for


pc.printf("\r\n");



edit: I think i understood your approach, it is easier than using valarrays :jap:
 
Dernière édition:
....just help me to fill the blanks.........

Well this is the first time that one of my students asks me to do his homework for him. 😢

I tested something straightforward - not clever nor elegant, just to get the job done. In the common.h I added a simple class for the list of filters to be read from file:
Code:
class filterClass{
public:
    int id; // CAN ID
    int map; // as a mask to select bytes to transmit to PC
    filterClass();
};
filterClass::filterClass(){
    map = 0xFF; // default to transmit all 8 bytes to PC
}

extern vector<filterClass> filters;

I then expanded the install_filters function to fill the content of the filters vector:
Code:
int install_filters(vector<filterClass>& filters){
    const int maxlinelen=128; // max line length in filters.txt file; 128 should be plenty for things like "0B4 // comment for 0B4 ....... " etc.
    char str[maxlinelen];
    filterClass filter;
    ifstream infile("/local/filters.txt"); // hard coded pathname for filter specification file
    if (infile.is_open()){
        while(infile.good()){
            infile.getline(str,maxlinelen);
            if (str[0]=='/' && str[1]=='/'){
                cout<<str<<", skip commented line."<<endl; // skip commented line
            } else {
                sscanf(str,"%x %x",&(filter.id),&(filter.map));
                cout<<str<<", install filter "<<hex<<filter.id<<" with map "<<filter.map<<endl; // to be replaced with CAN2_wrFilter(hex);
                filters.push_back(filter);
            }
        }
        infile.close();
        return 0;
    } else {
        cout<<"Unable to open filter spec file";
        return -1;
    }
}

I added a function to return the map of the filter given the filter ID:
Code:
int filter_map_fn(int id, vector<filterClass>& filters){
    for(int j=0; j<(int)filters.size(); j++){
        if(id==filters[j].id){
            return(filters[j].map);
        }
    }
    return(0xFF); // default to transmit all 8 bytes to PC
}
If for some reason the id is not in the list of filters then it defaults to select all 8 bytes.

Now in the main function the test code looks like this
Code:
    int filterresult = install_filters(filters);    
    int data[][9]={
        {0x025,0,1,2,3,4,5,6,7},
        {0x039,0,1,2,3,4,5,6,7},
        {0x230,0,1,2,3,4,5,6,7},
        {0x020,0,1,2,3,4,5,6,7},
        {0x540,0,1,2,3,4,5,6,7}
    };
    
    for (int i=0; i<5; i++){
        int id = data[i][0];
        int map = filter_map_fn(id, filters);
        bitset<8> mask(map);
        cout<<"id="<<hex<<id<<", map="<<map<<", data to transmit=";
        for (int j=0; j<8; j++){
            if (mask[7-j]){
                cout<<" "<<data[i][j+1];
            }
        }
        cout<<endl;
    }
Note I lumped the id and data together in the test so the indexing may be off one from your implementation. Also remember to check the actual bit order on the mbed and make adjustments to the indexing of mask (mask[7-j] or mask[j]).

For the test filter.txt file
Code:
// CANID, Map(of selected bytes to transmit to PC); max line length 128
025 06 // comments can be added to note what this filter (025) is for
039 2C
// 03A // comment out this line so this filter (03A) will not be installed
230 AD
540 F1
5A4 80
I got this output:
Code:
id=25, map=6, data to transmit= 5 6
id=39, map=2c, data to transmit= 2 4 5
id=230, map=ad, data to transmit= 0 2 4 5 7
id=20, map=ff, data to transmit= 0 1 2 3 4 5 6 7
id=540, map=f1, data to transmit= 0 1 2 3 7
 
@2009Prius, I am sorry, I was not asking for such a big thing 😳.

here is was I wrote yesterday and will test today:

Code:
            if (w_id < 0x700) {   // passive  frame ,
                msg_ReqFrameW--;

                char tmask=id_mask[w_id];   // trying to get the mask from the map id_mask using w_id as key...
                int imask = tmask;          // convert the mask  from char to integer

                bitset<8> mask(imask);      // trick fom 2009Prius ; if it works, he will get Champagne

                pc.printf("%03X",w_id);

                for (int i=0; i<w_len ; i++) {      // loop  from 0 to 7
                    if (mask[i]) {              // interesting Y/N
                        pc.printf("%02X",w_data[i]);
                    } // if (mask[i])
                } // for
                pc.printf("\r\n");
when you write about actual bit order, it does not matter mbed or not;
we are dealing with plain can messages, we just have to agree on byte numbering when we put them in arrays.
when applying masks on passive frames, it is easy because the "load"'s len is 8 bytes or less,
so we calculate an hex mask using standard right to left convention for 8 bits;
when applying the mask, we do it "as usual" from left to right.....
for multiframe, it would be really tricky because length is variable ....
 
excellent news.

masks are working...
sorry for 2009Prius, but what you said in post 103 was enough for me to adapt a working solution (of course it is not optimal 8) )

I corrected the bug regarding last byte in case of multiframe.

program is in the ftp, the name is CAN_hsd_bt_004.zip

ready for tests on a gen2

there is also a short capture made with this program and realterm capture70.zip
 
See I wasn't lying when I said I was just an amateur - I didn't know about std::map and thank you for teaching me. :jap:

I compared code 004 and 003 and found you reverted back to hex freq (period). Was that intentional or accidental?
 
ready for tests on a gen2

ok, you need my list of parameters, and my car.
we can arrange a meeting this week.
Probably on Wednesday. Around 4 pm. Are you ok?

Can you give me a file model for passive and active pids?
 
@2009Prius
to be honest about std::map , I have no idea how & why it works, but I am used to find promising recipes with google :grin:.

about reverting to hex between 4 & 3, this is a stupid mistake, in fact I started to work on 4 before finsihing 3.

@thierryb ok for friday; could you send me the log we took together, so I could prepare something.

now, I will switch the bps to 115200 and check if everything is ok,
so we will be ready for BT.
 
I said wednesday, but if you can't, it will be Friday. See you soon.
 
Could you guys try gen 2 request table like this:

Code:
// freq specified in decimal
7E2  1 04 21 C3 C4 42 00 00 00
7E0  5 03 01 0E 04 00 00 00 00
7E0  5 02 21 CD 00 00 00 00 00
7E0  5 05 21 3C 3E 2E 32 00 00
7E3  5 04 21 D0 CE CF 00 00 00
7E0 15 02 01 05 00 00 00 00 00
7E0 15 03 21 33 F5 00 00 00 00
7E3 15 02 21 31 00 00 00 00 00

and see how many requests per second you can push through?

Thanks!

Also I found it is important to initialize the counter fcnt individually for each item in order to make the higher frequency requests distributed more uniformly. In other words we should put the initial fcnt values back in the request.txt file and read them in.
 
@2009Prius
we will test your seq request, (so we will open the filter for 7e3 & 7ec)

it will be interesting also to compare sending individual requests specially, for the first combined request. so I will do it.

@planetaire
I will make a test to check once for all if obd plug is always on, but if I remember after looking in diagrams, it is always on.


I will now start trying recording on sdcard, the example from ken1784 is really easy to implement.

I attached an sdcard adapter to mbed (delicate soldering):
14f8bc28a22062.jpg




the dark side of the moon:
14f8bc28a4108e.jpg


mbed can now see the sdcard:
14f8bc28a10ef2.png
 
Dernière édition:
Joining the Group

Hello Y'All, as we say here in the south.

Thanks for the Invitation to join your project.

Hardware is my speciality and I will learn Software enough to be dangerous.
Familar with Ethernet,USB, CAN, OC-3,48,192,768,PWM, Ford EEC-V
I like dealing with Assembly Language and VHDL for CPLD/FPGA as they are closely linked to the Hardware.

I have been working with Microprocessors since I graduated from Carleton University, Ottawa, Canada in 1975..Yes I am an old Geezer but I bring a lot of experience which is not taught to the young ones.


Design Musings:

The use of BT as an uplink is a little slow and possibly causes early lockups with the STN chips.
I would suggest WiFi as it should run around 2.3Mbps, however someone will have to approach Ian Hawkins the author of Torque to see if he will modify his code to drive the WiFi Port.

Maybe we should invite him to join us as he may be interested in speed.

Yes there are 2 USB ports one is Device and the other is Host but as this is a On the Go part it may be easy to change from Host to Device.
Alternatively a USB-UART Bridge (device mode) part from FTDI or SiLabs drving a UART port should work also.

USB powered device is good as it simplifies the Power Tree but wile we can program the USB to request up to 400mA I would not use more that 150mA from the Laptop's USB Port. I would use a DC to DC Buck Converter to go from the Vehicle's 12-14v to 3.3V. There ae CAN interface chips that use 3.3V

For the Baseboard for SW development I bought 2 Blank PCBs for myself Designed by David Smart which provide connectivity for:
1. 2 CAN Ports
2. USB Host Port
3. Ethernet Port
4. MicroSD
5. Mbed

In the final phase merging the Mbed into the Baseboard we should remove the Mbed programing chip and use the Bootloader that come with the NXP 1768 and yes we will need a programing pod and Sw to convert the BIN file to Intel HEX for downloading.

The OBD2 cable aka DLC is a problem and should be eliminated as could distort the CAN Bus especially in a Prius

I received my Mbed module yesterday and I will fire it up on the Cloud tomorrow morning. The Smartbasboards are not here yet .

Winston.


I use Eagle CAD for board layouts and yes I did purchase a simple copy
 
welcome Winston

regarding BT maybe it will work, as we are only forwarding frames, there is no dialog...

Torque supports BT, USB and wifi , I will contact Ian Hawkins when we will have something operational.

FYI, I teached Ian how to deal with multiframes... I showed him also how to make combined requests.

I had a big/bad surprise with mbed : modserial is not compatible with sdcard...
so I have to revert to serial(standard) when using sdcard.

sdcard is really tricky: I tested 3 differents microsd/ sdhc: 1giga, 4 giga & 16 giga, it was necessary to use differents tricks to access each of them....
 
This is way beyond me but I wonder if you can talk to the SD card via USB, like a USB card reader does? (and still have the option of connecting to a PC via USB when needed)
 
bonsoir,
With Thierryb, we made some captures on a gen2 using the program rel 004.

on the ftp, we can find capture90.zip with thierry's parms
and capture91.zip with 2009Prius's parms

both capture were made with realterm during 200 sec.

with thierry's parms, we got 120 req/seq

with 2009Prius's parms, we got 73 req/seq ,but some of them are really heavy, for instance this one
"19/04/2011 16:23:37",7EB5061D00E000000000000000000861305861A0B1614141414141414141314141516CE73808486188618861786188617861386158617861486148613861A86178617CF888C80C54EAA0008000089D58B0E8A03
with a payload of 80 bytes corresponding to the request : 7E3 04 21 D0 CE CF 00 00 00


it seems we didnt loose passive frames... thx ken1784's ring buffer :jap:

we were using the same filters.
030 FF
039 FF
03B FF
0B4 FF
230 FF
244 FF
3C8 FF
3CB FF
3CF FF
520 FF
529 FF
52C FF
540 FF
5A4 FF
7E0 FF
7E2 FF
7E3 FF
7E8 FF
7EA FF
7EB FF
here are the parms for thierry:
Code:
// need a space after the last code, max line length 256
// 1 pos is ECU , second is period and FULL Message
7E2 1 02 21 C3 00 00 00 00 00 
7E0 1 02 21 0E 00 00 00 00 00 
7E2 1 02 21 C4 00 00 00 00 00 
7E0 1 02 21 3C 00 00 00 00 00 
7E3 1 02 21 CE 00 00 00 00 00 
7E0 1 02 21 3E 00 00 00 00 00 
7E2 1 02 21 11 00 00 00 00 00 
7E0 1 02 21 CD 00 00 00 00 00 
7E0 1 02 21 F3 00 00 00 00 00 
7E3 1 02 21 42 00 00 00 00 00 
7E0 1 02 21 EE 00 00 00 00 00 
7E0 1 02 21 06 00 00 00 00 00 
7E0 1 02 21 07 00 00 00 00 00
and here for 2009Prius
Code:
// freq specified in decimal
7E2  1 04 21 C3 C4 42 00 00 00
7E0  5 03 01 0E 04 00 00 00 00
7E0  5 02 21 CD 00 00 00 00 00
7E0  5 05 21 3C 3E 2E 32 00 00
7E3  5 04 21 D0 CE CF 00 00 00
7E0 15 02 01 05 00 00 00 00 00
7E0 15 03 21 33 F5 00 00 00 00
7E3 15 02 21 31 00 00 00 00 00
 
Great! Thank you! Could you post the filter.txt? The one on the ftp site doesn't seem to match the content of the capture file. Was this done with BT? Version 4: freq (period) was still read in as hex? Also how did you determine no lost passive frames? Count frame 030?
 
@ 2009Prius,
I edited my message above, I added the actual filter.
about periodicity, the program was modified to use dec instead of hex.
we were using USB, BT is not operational yet.

We checked with Thierry the frequency for passive frames and we think nothing was lost. see below table where the last column is the frequency for each ID (this is just count/200) :[table="head;width=60%"]ID|count|
p1​
|
p2​
|
p3​
|
p4​
|
p5​
|
p6​
|
p7​
|
p8​
|
freq​
|
030|32 873|
4_132​
|
0_255​
|
##0​
|
##0​
|
0_71​
|
32_96​
|
##0​
|
28_220​
|
164,37​
|
039|24 427|
75_86​
|
0_2​
|
0_34​
|
139_179​
|
##0​
|
##0​
|
##0​
|
##0​
|
122,14​
|
03B|25 019|
0_15​
|
0_255​
|
##0​
|
191_232​
|
0_255​
|
##0​
|
##0​
|
##0​
|
125,10​
|
0B4|16 438|
##0​
|
##0​
|
##0​
|
##0​
|
0_1​
|
0_15​
|
0_255​
|
0_255​
|
82,19​
|
230|8 220|
0_255​
|
0_255​
|
##2​
|
0_36​
|
##0​
|
0_255​
|
0_255​
|
##0​
|
41,10​
|
244|8 146|
##16​
|
##0​
|
##0​
|
##0​
|
0_255​
|
0_255​
|
0_89​
|
0_255​
|
40,73​
|
3C8|3 056|
##0​
|
##40​
|
0_49​
|
##0​
|
##0​
|
0_255​
|
##0​
|
##0​
|
15,28​
|
3CB|2 004|
##105​
|
123_125​
|
##0​
|
116_121​
|
27_28​
|
24_25​
|
98_102​
|
##0​
|
10,02​
|
3CF|1 530|
0_16​
|
10_15​
|
26_32​
|
##0​
|
0_22​
|
##0​
|
##0​
|
##0​
|
7,65​
|
520|79|
##164​
|
2_4​
|
3_239​
|
##0​
|
##0​
|
##0​
|
##0​
|
##0​
|
0,40​
|
529|207|
40_168​
|
##0​
|
##0​
|
133_141​
|
##0​
|
##0​
|
##0​
|
##0​
|
1,04​
|
52C|203|
##35​
|
151_174​
|
##0​
|
##0​
|
##0​
|
##0​
|
##0​
|
##0​
|
1,02​
|
540|212|
37_165​
|
0_128​
|
##0​
|
##0​
|
##0​
|
##0​
|
##0​
|
##0​
|
1,06​
|
5A4|66|
##99​
|
4_13​
|
##0​
|
##0​
|
##0​
|
##0​
|
##0​
|
##0​
|
0,33​
|
7E8|14 741|
3_13​
|
##97​
|
6_243​
|
0_170​
|
0_255​
|
0_120​
|
0_224​
|
##0​
|
73,71​
|
7EA|5 529|
3_39​
|
##97​
|
17_196​
|
0_128​
|
0_255​
|
0_115​
|
0_255​
|
##0​
|
27,65​
|
7EB|3 687|
4_33​
|
##97​
|
66_206​
|
53_121​
|
6_242​
|
0_255​
|
0_134​
|
##0​
|
18,44​
|
total|146 437|||||||||
732,19​
|
[/table]
 
Thank you! What program do you use to analyze the data and get the nice summary table?

There is so much for me to learn here. What are at 0B4 and 230? Maybe there is a master table/spreadsheet of all the known ID and formulas somewhere I could download?
 
I prepared an excel analyser for analysing requests.

using this tool, I discovered a small bug in case of multiframe (there is an empty byte after the last byte from the first frame).

I corrected in the ftp.

@2009Prius: in 0B4, is one of the best info regarding speed...
 
@planétaire: Thanks I have seen that one but not everything is correct in there. Also that one does not seem to have passive frames IIRC.

@priusfan: Thanks I will take a look on the ftp site.
 
Pages vues depuis le 20 Oct 2005: 316,286,169
Retour
Haut Bas