Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 9 of 9

Thread: Reading data from CAN bus volkswagen

  1. #1
    Junior Member
    Join Date
    Sep 2020
    Posts
    4

    Reading data from CAN bus volkswagen

    Hello, I am new to microcontroller programming. But I really want to create an additional monitor with information output to the car (Volkswagen Jetta 6). I have Teensy 4.0 and have already been able to connect a 240x240 display. But here's how to get information from the CAN bus of a car - I don't have enough knowledge. Perhaps someone was engaged in a similar task, I will be grateful for any advice and hint. Sincerely.

  2. #2
    Senior Member
    Join Date
    Oct 2019
    Posts
    148
    I have experience with the MQB platform, but as your Jetta is on the PQ35 platform, I can't provide you with my request response sample as it's not the same.
    What kind of data do you want to display on your tft?

    What I suggest you do is purchase a VCDS HEX-CAN V2 from Aliexpress and do some can sniffing using the T4 hooked up to the OBD port with a Y splitter (don't forget to use a CAN transceiver between the T4 and the OBD port)
    Set VCDS to poll a single parameter and catch the messages with the Teensy vis Serial monitor to see what a request looks like and what a response looks like.
    Here is what it looks like:
    Click image for larger version. 

Name:	IMG_5070.jpg 
Views:	27 
Size:	365.1 KB 
ID:	21720

    But you really need to learn how the CAN bus application layer works, and how UDS works.
    Here are some links that will help you:
    https://en.wikipedia.org/wiki/Unifie...ostic_Services
    https://en.wikipedia.org/wiki/OBD-II_PIDs

    I built a data monitor that does exactly what you are looking for


    I can try help you out more once you've gotten the basic knowledge to pull the data from the car.

  3. #3
    Junior Member
    Join Date
    Sep 2020
    Posts
    4
    Rezo, you have a good project and it looks like this is exactly what I need! I want to display coolant temperature, transmission oil temperature and possibly a few more parameters. My dashboard doesn't display this information
    The principle of working with a CAN bus through a getway is roughly clear to me, a request for a certain parameter is made and a response is obtained with data on it.
    But I still can't find examples of the implementation of reading for T4.
    Which transceiver should you use?
    How to connect it to T4 and how to programmatically receive data?
    I would be very grateful to you for such information and an example of your implementation of the code and connecting the transceiver to T4 and to the CAN bus. As for the difference in car platforms (on my Jetta PQ25, unfortunately), I think there should be no problems. PIDs must be the same.

  4. #4
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,463
    standard pids are fine, but not OEM specific. each car and year can be different. Some data is already in stream while you have the option to request them. But not all requested pids are available, and require reverse engineering the stream or using UDS, which are manufacturer specific. Breakout boards are available for T4, you'll likely use 2 busses anyways (comfort bus and high speed bus) so you may look into those since theyre 12v ready to plug and play. Rezo may be using different hardware, but they all should work the same. Some transceivers have been shown to not be compatible though

  5. #5
    Senior Member
    Join Date
    Oct 2019
    Posts
    148
    As Tony mentioned, UDS is not easy to understand and it's not documented anywhere but it's got more enhanced data than standard OBD2 PIDs - that's why can sniffing individual PID's is the best option IMO to find what you are looking for over UDS.

    This is my setup to do CAN sniffing:
    Click image for larger version. 

Name:	canSniff_setup.jpg 
Views:	12 
Size:	86.4 KB 
ID:	21730
    1. HEX V2 used with VCDS to send requests and see realtime data
    2. Teensy 3.2 + TI sn65hvd230 CAN transceiver placed in an OBD2 connector
    3. Y splitter that connects to both devices to the cars OBD port

    I use a simple sketch on the Teensy that print's every CAN frame it see's (from either end: car or VCDS) onto the Arduino serial monitor. I then log each frame (request/response) and value.

    I must note, on the PQ25 you most probably have a Bosch MED ECU and it's not as fast as the MQBs Continental Simos, so request poll speed might have to be lower in your case.
    I know for a fact that the MQB UDS requests don't work with the PQ35 platform as I have plugged my device into a VW Scirocco and it failed to return any positive UDS responses.


    For the Teensy 4 I used the TI sn65hvd230 CAN transceiver on CAN1 (pins 22 and 23).
    Here is a simple sketch that will request engine coolant temp and save it into a variable and print it out in your serial monitor:
    Code:
    #include <FlexCAN_T4.h>
    FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> Can0;
    
    int engineCoolantTemp = 0; // Save the data here
    
    void setup(){
      while (!Serial && millis() < 5000);
      Serial.begin(115200);
      Can0.begin();
      Can0.setBaudRate(500000);
      Can0.setMBFilter(REJECT_ALL);
      Can0.setMBFilter(MB1, 0x7E8);
      Can0.enableMBInterrupt(MB1);
      Can0.onReceive(canSniff);
    
    }
    
    const long loopDelay1 = 500; // Make a request every 500ms
    unsigned long timeNow1 = 0;
    void loop(){
      Can0.events();
      if (millis() > timeNow1 + loopDelay1)
        {
          timeNow1 = millis();
          canTx_OBD(); // Query data from CAN BUS via OBD
          //canTx_UDS(); // Query data from CAN BUS via UDS
    
        }
    }
    
    
    void canSniff (const CAN_message_t &msg){ // Global callback to catch any CAN frame coming in
      Serial.println(" ");
      Serial.print("MB: ");
      Serial.print(msg.mb);
      Serial.print("  ID: 0x");
      Serial.print(msg.id, HEX);
      Serial.print("  EXT: ");
      Serial.print(msg.flags.extended);
      Serial.print("  LEN: ");
      Serial.print(msg.len);
      Serial.print(" DATA: ");
      for (uint8_t i = 0; i < 8; i++)
        {
          Serial.print(msg.buf[i], HEX);
          Serial.print(" ");
        }
        if (msg.buf[1] == 0x01 && msg.buf[2] == 0x05){
            engineCoolantTemp = msg.buf[3] - 40;
            Serial.println(" ");
            Serial.printf("OBD: Engine Coolant Temp: %d c", engineCoolantTemp);
        }
    
        if (msg.buf[1] == 0x22 && msg.buf[2] == 0xf4 && msg.buf[3] == 0x05){
            engineCoolantTemp = msg.buf[4] - 40;
            Serial.println(" ");
            Serial.printf("UDS: Engine Coolant Temp: %d c", engineCoolantTemp);
        }
    
    }
    
    
    void canTx_OBD(){ // Request function to ask for Engine Coolant Temp via OBD request
      CAN_message_t msgTx, msgRx;
        msgTx.buf[0] = 0x02; 
        msgTx.buf[1] = 0x01;
        msgTx.buf[2] = 0x05;
        msgTx.buf[3] = 0; 
        msgTx.buf[4] = 0;
        msgTx.buf[5] = 0; 
        msgTx.buf[6] = 0;
        msgTx.buf[7] = 0;
        msgTx.len = 8;            // number of bytes in request
        msgTx.flags.extended = 0; // 11 bit header, not 29 bit
        msgTx.flags.remote = 0;
        msgTx.id = 0x7E0; // request header for OBD
        Can0.write(msgTx);
        Serial.println("canTx_OBD REQ sent"); 
      }
    
     void canTx_UDS(){ // Request function to ask for Engine Coolant Temp via UDS request
      CAN_message_t msgTx, msgRx;
        msgTx.buf[0] = 0x03; 
        msgTx.buf[1] = 0x22;
        msgTx.buf[2] = 0xf4;
        msgTx.buf[3] = 0x05; 
        msgTx.buf[4] = 0;
        msgTx.buf[5] = 0; 
        msgTx.buf[6] = 0; 
        msgTx.buf[7] = 0;
        msgTx.len = 8;            // number of bytes in request
        msgTx.flags.extended = 0; // 11 bit header, not 29 bit
        msgTx.flags.remote = 0;
        msgTx.id = 0x7E0; // request header for OBD
        Can0.write(msgTx); 
        Serial.println("canTx_UDS REQ sent"); 
      }
    You can try first the OBD method of request, then you can try the UDS method by commenting out the OBD request and uncommenting the UDS request in the main loop.

  6. #6
    Junior Member
    Join Date
    Sep 2020
    Posts
    4
    Rezo, thank you very much for the information, fortunately I have this transceiver. Today I will try to connect according to your example.

  7. #7
    Senior Member
    Join Date
    Oct 2019
    Posts
    148
    By the way, I plug into the OBD port, not directly to any of the available busses in the car. I was after true P&P

  8. #8
    Junior Member
    Join Date
    Sep 2020
    Posts
    4
    Rezo, thanks for the hints and code, this works and I'm glad it does!
    Well, I'm continuing to work on the project.
    Click image for larger version. 

Name:	IMG_5868.jpg 
Views:	25 
Size:	45.6 KB 
ID:	21733
    Click image for larger version. 

Name:	IMG_5871.jpg 
Views:	16 
Size:	361.0 KB 
ID:	21734
    Click image for larger version. 

Name:	IMG_5873.jpg 
Views:	19 
Size:	284.4 KB 
ID:	21735

  9. #9
    Senior Member
    Join Date
    Oct 2019
    Posts
    148
    vgopaitsa I'm really glad it's working for you!

    If you want to make a nice GUI, I can suggest the following:
    Ring gauge - this is fairly easy to adapt to your current display library, and looks cool with little effort
    LVGL - this is complex to set up but looks really great, I've just started to port my own project to this graphics library


    Show us the progress as you move along!

Posting Permissions

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