Forum Rule: Always post complete source code & details to reproduce any issue!
Page 7 of 8 FirstFirst ... 5 6 7 8 LastLast
Results 151 to 175 of 178

Thread: IFCT - Improved Flexcan Teensy Library

  1. #151
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,020
    the ones i use are the one from tindie

    https://www.tindie.com/search/?q=canbus+teensy

    all transceivers should work but some have different voltage for differential, plus you need to loose that termination resistor

  2. #152
    Ok, after work I'll give it a try removing the 120ohm resistor and if still not works I'll also try to use Can0...

    I've checked the code and I'm sending the OBD request every 5 seconds just to poll if the connection is ok... after sendig the first request I'm waiting for 15msec before call while(Can1.read()) { ... }
    Are that timing ok? 15msec is enough to get response?

    I'm sending 3 ODB requests with ID 0x7DF to get (RPM, TPC and ECT) and I expect 3 OBD responses with ID 0x7E8.... how can I configure the filters to receive just that messages?

  3. #153
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,020
    you do not need a while loop on read, if a frame is available then u can read it right away otherwise continue the rest of your code. You also dont need to read if youíre using interrupts. they goto the callback automatically. If you donít use interrupts you can poll read(), if it has something you can read it.

    i would first make sure you can operate send/receive working properly before going to filter but for filtering its simple
    mailbox mode:
    Can1.setMBFilter(MB0, 0x7DF, 0x7E8); // mailbox 0 and 2 IDs
    fifo mode:
    Can1.setFIFOFilter(0, 0x7DF, 0x7E8); // fifo filter 0, and 2 IDs

    Do not forget to block all frames before applying filters:
    Can1.setMBFilter(REJECT_ALL); //mailbox mode
    Can1.setFIFOFilter(REJECT_ALL); //fifo mode

  4. #154
    Hey tonton81, thank you so much for all you've done!
    I've removed the 120ohm resistor and now it seems to work fine!
    I'm able to read all the CAN messges and I can also send the OBD request and get the response... great!!!!

    Now I think I need some help to fine tune my code:
    I want my Datalogger to poll the ECU when startup (every 5 seconds?) and if the ECU reply (switch ing. ON on my bike) it will start acquiring "realtime" data via OBD request (RPM, ECT, TPS)...
    I'm starting using the RPM OBD request as "poll" msg every 5 seconds but maybe I can ask for the supported CAN IDs or ...
    After sending the OBD request I wait 15ms and after that I'm using the while(Can1.read(rxMsg)) but my while loop exit after just one read message... I was supposed that the while will loop for all the messages including my OBD request.
    Can you explain me the better why to send one or more OBD requests and then wait with a reasonable timeout for the response? If I can't get the response I have to manage this with retry and so on...

    I'd also like to receive only the messages I need but still not clear if would be better to use MB or FIFO or ... and how to filter in the best way.


    Thank you so much and keep up the great job!

  5. #155
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,020
    you send one you read one usually, you can set a flag when you send one and poll the read(), if you get a read unset the flag so the write can send another request again, no need to do a while loop, while loops are bad for datalogging, just replace while with if, if theres nothing there your code can continue doing other stuff but not write. you can set a timer if you want to resend again if nothing happened in like 2 seconds to request again, millis() and flags are your friend here

  6. #156
    Hi guys,
    I've made some tests but still got soem issues:
    If I just send the OBD request for RPM everithing seems to works fine but if I send also the ODB request for TPS and ECT it seems to freeze or became unresponsive..,

    Here there is the code, can you please help me?

    #include <IFCT.h>

    #define CLEAR_SCREEN F("\033[0H\033[0J")

    #define SERIAL_BAUD 115200 // Serial Monitor baud
    #define CANBUS_SPEED 500000 // 500Kpbs

    #define OBD_DIAG_ID 0x7DF
    #define OBD_DIAG_RESP_ID 0x7E8

    #define OBD_PID_SUPP 0x00 // Request for supported PIDs
    #define OBD_PID_LOAD 0x04 // ???
    #define OBD_PID_ECT 0x05
    #define OBD_PID_TPS 0x11
    #define OBD_PID_RPM 0x0C
    #define OBD_PID_VBAT 0x42

    static unsigned long previousMillis = 0;

    static float tps = 0.0;
    static uint16_t rpm = 0;
    static uint8_t ect = 0;

    static char response[32];
    static char str_temp[6];

    void setup() {

    Serial.begin(SERIAL_BAUD);
    delay(2000);

    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, HIGH);

    Can1.setBaudRate(CANBUS_SPEED);
    Can1.enableFIFO();
    Can1.setFIFOFilter(REJECT_ALL);
    Can1.setFIFOFilter(MB0, OBD_DIAG_ID, OBD_DIAG_RESP_ID, STD);
    Can0.enhanceFilter(FIFO);

    Serial.println("Starting IFTC sniffer...");
    }

    void loop() {
    CAN_message_t msg;

    // Send OBD request every 100ms
    if (millis() - previousMillis >= 100) {
    if (!sendObdRequest(OBD_PID_RPM)) {
    Serial.println("Error sending RPM ODB request!");
    }

    /////////////////////////////////////////////////////////
    // IF I UNCOMMENT THIS CODE EVERITHING GET FREEZED
    // AND NOT RESPONSIVE!!!
    // if (!sendObdRequest(OBD_PID_TPS)) {
    // Serial.println("Error sending TPS ODB request!");
    // }
    // if (!sendObdRequest(OBD_PID_ECT)) {
    // Serial.println("Error sending ECT ODB request!");
    // }

    previousMillis = millis();
    }

    if (Can1.read(msg)) canSniff(msg);

    }

    bool sendObdRequest(unsigned long id) {

    CAN_message_t reqMsg;
    reqMsg.flags.extended = 0;
    reqMsg.flags.remote = 0;
    reqMsg.len = 8;
    reqMsg.id = OBD_DIAG_ID;
    reqMsg.buf[0] = 0x02;
    reqMsg.buf[1] = 0x01;
    reqMsg.buf[2] = id;
    reqMsg.buf[3] = 0x00;
    reqMsg.buf[4] = 0x00;
    reqMsg.buf[5] = 0x00;
    reqMsg.buf[6] = 0x00;
    reqMsg.buf[7] = 0x00;
    Can1.write(reqMsg); // Need to check ret val?

    return true;
    }

    void canSniff(const CAN_message_t &rxMsg) {

    if(rxMsg.id == OBD_DIAG_RESP_ID) {
    switch (rxMsg.buf[2]) {
    case OBD_PID_RPM:
    rpm = ((256 * rxMsg.buf[3]) + rxMsg.buf[4]) / 4;
    break;
    case OBD_PID_TPS:
    tps = (100.0 / 255.0) * rxMsg.buf[3];
    break;
    case OBD_PID_ECT:
    ect = rxMsg.buf[3] - 40;
    break;
    }
    }

    Serial.print(CLEAR_SCREEN);
    /* 4 is mininum width, 2 is precision; float value is copied onto str_temp*/
    dtostrf(tps, 4, 1, str_temp);
    sprintf(response, "TPS: %s RPM: %d ECT: %d", str_temp, rpm, ect);
    Serial.println(response);

    }

  7. #157
    Senior Member+
    Join Date
    Jul 2014
    Location
    New York
    Posts
    3,347
    I am pretty sure the ECU needs some time between requests, @tonton81 can confirm. I did a little google search and came across this link: https://stackoverflow.com/questions/...simultaneously. To make a long story short
    The OBD-II default settings are responsible for this. The default waiting time, (as far as I can recognize) 200 ms. So you can only send 5 commands each second. This is somewhat slow, and some applications manage to get 20 request each second.
    You may have to play with the delay time though.

  8. #158
    Thanks for response!
    The first think Iíve tried was just add a delay of 10ms and also tried with 50ms but... 200ms itís realiy slow!!!!

    How can the diagnostic tool handle all the parameters with such slow delay between requests?

  9. #159
    Senior Member+
    Join Date
    Jul 2014
    Location
    New York
    Posts
    3,347
    Quote Originally Posted by Bullone View Post
    Thanks for response!
    The first think I’ve tried was just add a delay of 10ms and also tried with 50ms but... 200ms it’s realiy slow!!!!

    How can the diagnostic tool handle all the parameters with such slow delay between requests?
    If you read the link I posted it also said about adding another parameter to the send request for timing? Don't know much about that one but take a read. Also maybe @tonton81 can help here.

  10. #160
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,020
    the reason you can get more requests is you can ask for multiple pids, like RPM and speed, and receive them in one frame, provided they can fit in one 8-byte datafield, if not, it will come in 2 frames. Obviously you’d have to know where to parse it based on what order you requested them

  11. #161
    Quote Originally Posted by tonton81 View Post
    the reason you can get more requests is you can ask for multiple pids, like RPM and speed, and receive them in one frame, provided they can fit in one 8-byte datafield, if not, it will come in 2 frames. Obviously you’d have to know where to parse it based on what order you requested them
    Thatís really interesting!
    Can you help me to find a way to ask for RPM, TPS and ECT with just one OBD request? That would be the best approach for my datalogger but Iím not expert on CAN and/or OBD....

    Iíve also checked my test code made for Arduino Nano and MCP2515 and I was able to send 3 OBD request and get response without issue!
    I just have to wait about 10ms between every request so it seem it is not an issue related to the ECU.... mmmhhh....

  12. #162
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,020
    im curious, does it still freeze when you disable using dtostrf and sprintf and uncomment the above lines?

    ill have to check my old code for multiple PID request but I’m sure it can be found all over google

  13. #163
    yes disabling using dtostrf and sprintf doesn't fix the isssue.
    I've tryied asking every 200ms all the 3 request with a 10ms delay between each of them but it seems that I receive pnly the ECT and the serial monitor is not so responsive... seems like freezing but not sure if freeze or...

    The strange think is that with Arduino + MCP2515 I was able to send 3 request with 10ms delay and get all responses with no issue in the same ECU.
    I'll try to move to Can0 but no other idea.

    If you could let us know how to request multiple IDs and manage multiple responses it will be very usefull because for my applciation that's should be the best way to go.


    Thanks for your help!

  14. #164
    Hey guys, sorry to bother you again but I think I found my issue:
    after some more tests I saw that if I send all the 3 requests and after that I gonna read from the CAN... I just receive the response for the last request I sent!
    Don't know if this is expected behavior but I need a "snapshot" of RPM, TPS and ECT taken in the same time because just before or just after I get all the responses I can read the analog input voltage corresponding to the AFR and store all of them in a table. To be accurate I think I'll need to do this "read procedure" at least 10/20 times per sec.
    Any idea on how to solve my issue?

  15. #165
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,020
    Try to see if you receive them without using filters, try to see if you can call one at a time, to see if you catch them. only call one to see if it works, then try another, confirm you see them. Also try reposting your sketch if you changed anything

    On another note:


    The ELM327 datasheet gives the following information on page 45:

    Multiple PID Requests The SAE J1979 (ISO 15031-5) standard allows requesting multiple PIDs with one message, but only if you connect to the vehicle with CAN (ISO 15765-4). Up to six parameters may be requested at once, and the reply is one message that contains all of the responses. For example, let us say that you need to know engine load (04), engine coolant temperature (05), manifold pressure (0B), and engine rpm (0C) on a regular basis. You could send four separate requests for them (01 04, then 01 05, then 01 0B, etc.) or you could put them all into one message like this:

    01 04 05 0B 0C to which, a typical reply might be:
    0: 41 04 3F 05 44 0B
    1: 21 0C 17 B8 00 00 00
    For the above, the example shows reception of 2 frames for a single request.

  16. #166
    Junior Member
    Join Date
    Jun 2018
    Location
    Seoul in South Korea
    Posts
    7
    I think your mistake type....
    Can0.enhanceFilter(FIFO); ---------> Can1.enhanceFilter(FIFO);

  17. #167
    Hi guys,
    can you please help me understand which is the best way to configure the FIFO filter with setFIFOFilter() if I'd like to receive just 3 CAN IDs?
    I can't get it working....

  18. #168
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,020
    Can0.setFIFOFilter(0,0x01);
    Can0.setFIFOFilter(1,0x02);
    Can0.setFIFOFilter(2,0x03);

    This should allow IDs 1 2 and 3 to pass FIFO, rest blocked.
    Be sure to run Can0.setFIFOFilter(REJECT_ALL); to block everything before setting the filters above to let only those frames through

  19. #169
    Thanks for fast response!
    That means that the every time I call setFIFOFilter it will be added to the filters (+=) instead of reset and add (=), correct?
    What about the first parameter? Is that the mailbox? Can you explain me how does the mailbox works?

  20. #170
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,020
    mailboxes are not FIFO, but FIFO has 8 filters by default 0-7, if you want specific mailbox as reception in a sepearate callback you can use a mailbox for that

  21. #171
    Thank you for explanation!

  22. #172
    Quote Originally Posted by tonton81 View Post
    Can0.setFIFOFilter(0,0x01);
    Can0.setFIFOFilter(1,0x02);
    Can0.setFIFOFilter(2,0x03);

    This should allow IDs 1 2 and 3 to pass FIFO, rest blocked.
    Be sure to run Can0.setFIFOFilter(REJECT_ALL); to block everything before setting the filters above to let only those frames through
    I'm trying but I'm getting a compiler error:
    error: no matching function for call to 'IFCT::setFIFOFilter(int, int)'

    I've had a look at the lib examples but it seems there is no filtering example code... can you please add a working example code to the lib?

  23. #173
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,020
    sorry I forgot the extra frame info you need to add
    EXT for extended, STD for standard frame:

    Can0.setFIFOFilter(0, 0x05, STD);

    filter 0, ID 5, Standard frame

  24. #174
    Thanks!
    Just tested and works fine

  25. #175
    Junior Member
    Join Date
    Jun 2019
    Posts
    4
    Hey, I have a project that I am starting here shortly and don't even really know where to start. I have 1 device that I can send data over with any address as any bit length from unsigned8bit to a signed 32bit.

    I need to send values from -99.99 to 99.99 so a signed 8 bit should be perfectly fine correct?

    I am using the Teensy 3.6 and have a the Dual Can board on the way. Currently I just need to read values from it, but I see a need to send some messages out as a 1 or 0 for turning things on and off.

    1st how do I get the message to read in as a number and then can I assign that number as a variable? It will be coming in at 100hz, and I will more than likely have up to 20 addresses that I need to read.

    Does this seem doable?

    Is there a decent example of just reading a particular address?

    Thanks for the help.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •