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

Thread: Teensy 3.2 and canbus connections

  1. #1

    Teensy 3.2 and canbus connections

    Hello all

    Been playing around with my new Teensy 3.2 (had it a while.... never used it).
    Was planning to add a MCP2515 Can-bus breakout board to it, so that I could decode the Can-bus signals from my truck (only want to read them).
    Then.... I notice the Can-bus pins on the Teensy itself....

    Can I connect these directly to the trucks Can-bus? I cannot find connections for this anywhere on the net, but in theory it would work.... right?
    I imagine I may need a termination resistor or something (120R)?

    Looking at the Can-bus plug in the truck, I can see Can-bus High and Can-bus low, but how do they relate to Canbus RX/TX on the Teensy?

    Any help would be gratefully received.... been Googling for hours!

  2. #2
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,274
    Would highly recommend using a transceiver. I typically use one of these: https://www.amazon.com/SN65HVD230-CA...s%2C132&sr=1-1. Had it hooked up to my car.

    CAN RX/Tx on the T3.2 would go to the Rx/Tx on the transceiver while CANH/CANL on the transceiver goes to CANH/CANL on the vehicles connector. Make sure you hook ground to grounds up as well

  3. #3
    OK... We are up and running.....

    Biblical amount of data..... how the heck do you extract RPM, Speed etc
    Clearly it need filtering..... hmm

    Code:
    // CAN Receive Example
    //
    
    #include <mcp_can.h>
    #include <SPI.h>
    
    long unsigned int rxId;
    unsigned char len = 0;
    unsigned char rxBuf[8];
    char msgString[128];                        // Array to store serial string
    
    #define CAN0_INT 3                              // Set INT to pin 2
    MCP_CAN CAN0(14);                               // Set CS to pin 10
    
    
    void setup()
    {
      Serial.begin(115200);
    
      delay(3000);
    
      Serial.println("System starting....");
      
      // Initialize MCP2515 running at 16MHz with a baudrate of 500kb/s and the masks and filters disabled.
      if(CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_16MHZ) == CAN_OK)
        Serial.println("MCP2515 Initialized Successfully!");
      else
        Serial.println("Error Initializing MCP2515...");
      
      CAN0.setMode(MCP_NORMAL);                     // Set operation mode to normal so the MCP2515 sends acks to received data.
    
      pinMode(CAN0_INT, INPUT);                            // Configuring pin for /INT input
      
      Serial.println("MCP2515 Library Receive Example...");
    }
    
    void loop()
    {
      
      if(!digitalRead(CAN0_INT))                         // If CAN0_INT pin is low, read receive buffer
      {
        CAN0.readMsgBuf(&rxId, &len, rxBuf);      // Read data: len = data length, buf = data byte(s)
        
        if((rxId & 0x80000000) == 0x80000000)     // Determine if ID is standard (11 bits) or extended (29 bits)
          sprintf(msgString, "Extended ID: 0x%.8lX  DLC: %1d  Data:", (rxId & 0x1FFFFFFF), len);
        else
          sprintf(msgString, "Standard ID: 0x%.3lX       DLC: %1d  Data:", rxId, len);
      
        Serial.print(msgString);
      
        if((rxId & 0x40000000) == 0x40000000){    // Determine if message is a remote request frame.
          sprintf(msgString, " REMOTE REQUEST FRAME");
          Serial.print(msgString);
        } else {
          for(byte i = 0; i<len; i++){
            sprintf(msgString, " 0x%.2X", rxBuf[i]);
            Serial.print(msgString);
          }
        }
            
        Serial.println();
      }
    }
    
    /*********************************************************************************************************
      END FILE
    *********************************************************************************************************/

  4. #4
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,274
    You will need to filter the messages for the messages ids containing speed, rpm etc.

  5. #5
    I think I need to find a better library that I can understand....

    The line: CAN0.readMsgBuf(&rxId, &len, rxBuf); // Read data: len = data length, buf = data byte(s) is retrieving the data.... But I don't understand how to change that to obtain what I want.
    Do I need filtering, if I am only requesting a single item anyway?

    From what I understand, the first part of that request is the id of what I require, which I believe is 01 for Mode 1 (which is current data), and then 0c for example, which should be RPM.
    But, entering those values in any format fails.

    I clearly don't quite get it.

  6. #6
    Junior Member
    Join Date
    Oct 2019
    Posts
    6
    Quote Originally Posted by SteveSFX View Post
    I think I need to find a better library that I can understand....

    The line: CAN0.readMsgBuf(&rxId, &len, rxBuf); // Read data: len = data length, buf = data byte(s) is retrieving the data.... But I don't understand how to change that to obtain what I want.
    Do I need filtering, if I am only requesting a single item anyway?

    From what I understand, the first part of that request is the id of what I require, which I believe is 01 for Mode 1 (which is current data), and then 0c for example, which should be RPM.
    But, entering those values in any format fails.

    I clearly don't quite get it.
    If you are connecting to a vehicle that supports OBD2 (IIRC anything manufacured after 2004), you need to request the data with the corresponding PID (https://en.wikipedia.org/wiki/OBD-II_PIDs - service 01).
    For this, you need to filter any messages with a response header of 0x7E8 (need to check if this is for trucks too), verify your response PID has a value of 0x40 added to it (sucessful response indicator eg if you requested PID 0x01, you'll get 0x41 in response from the ECU) and then extract the response data from the payload.

    To do this, you need to understand the request and response structure of the OBD protocol over Can bus.
    Start with this video (it explains UDS - the underlying application layer within car can networks, but covers the request-response structure) - https://www.youtube.com/watch?v=lY585Yp7zeY

    You can see an example of simple PID's in SK Pang's sketch
    https://github.com/skpang/Teensy_CAN-Bus_ECU_reader

  7. #7
    Senior Member
    Join Date
    Apr 2019
    Posts
    150
    Another sughestion is to export the data to something like excel and try understand what can codes relate to which module. Turning the wipers on and off for example should be the body control module

  8. #8
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,133
    Check out the examples from IFCT Library for teensy, should get you up and running. As for the truck you seem to be getting frames however, on some vehicles OBD is accessed over CAN as extended rather than standard. Granted if the EACEN bit is not set in the MCR register, a mailbox can pull both extended and standard frames from the same mailbox, otherwise each mailbox bit needs to be set to specify it to be explicitly only one type. I would suggest to try the fifo example with interrupts or polling, depending on your preference. If you want to get the correct ECU address over CAN I also suggest you hook up an OBD reader to the truck to read the ECU while logging on teensy, teensy will show you the correct addrese you SHOULD use when addressing commands to the ECU

Posting Permissions

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