CAN Bus CANBed V1.2e ... No return communication

First off, I am very familiar with CAN Bus communication. I have some higher end equipment that I use to read CAN Bus on a regular basis. So I understand the communication method, what it should look like, and all the other details related to CAN Bus communication.

That said, I recently bought a Longan Labs CANBed V1 as I have a project I want to use a CAN Bus controller on. I have been fighting this for a few weeks and I have not been able to get the car to respond to the controller. I am more used to programming in Python and still need to learn the Arduino coding. Getting this thing to communicate would make that process a lot easier...

I will say I cannot find a lot of documentation on the CANBed input pin. I am using pin 2, as that is what is in the code but I am not 100% sure that is correct. I have tried changing the pin to about every other pin number with no change. But...pin 2 is what was in the code example, so I am thinking it should be right.

Anyway, this particular car works best if you send a message and wait for a response. Just listening on a "CAN Receive" code is unlikely to work well (it does not work for me either). With this in mind, I have the following code I am working with. It is sending a request, and that appears to be working correctly. However, I do not get a Rx response written to the serial monitor. The Rx and Tx lights do blink, but I am not seeing a Rx...

#include <SPI.h>
#include "mcp_can.h"

/* Please modify SPI_CS_PIN to adapt to different baords.

   CANBed V1        - 17
   CANBed M0        - 3
   CAN Bus Shield   - 9
   CANBed 2040      - 9
   CANBed Dual      - 9
   OBD-2G Dev Kit   - 9
   Hud Dev Kit      - 9
*/

#define SPI_CS_PIN  17

MCP_CAN CAN(SPI_CS_PIN);                                    // Set CS pin

#define PID_ENGIN_PRM       0x0C
#define PID_VEHICLE_SPEED   0x0D
#define PID_COOLANT_TEMP    0x05

#define CAN_ID_PID          0x7DF


void setup() {
    Serial.begin(115200);
    while(!Serial);

    // below code need for OBD-II GPS Dev Kit
    // pinMode(A3, OUTPUT);
    // digitalWrite(A3, HIGH);

    while (CAN_OK != CAN.begin(MCP_STDEXT, CAN_500KBPS, MCP_16MHZ)){             // init can bus : baudrate = 500k
        Serial.println("CAN init fail, retry...");
        delay(100);
    }
    Serial.println("CAN init ok!");

    // set mask, set both the mask to 0x3ff

    CAN.init_Mask(0, 0x7FF);
    CAN.init_Filt(0, 0x7DF);                 
    CAN.init_Filt(1, 0x7E8);
    
    // set filter, we can receive id from 0x04 ~ 0x09

    CAN.init_Mask(1, 0x7FF);
    CAN.init_Filt(2, 0x7DF);
    CAN.init_Filt(3, 0x7E8);
    CAN.init_Filt(4, 0x7DF); 
    CAN.init_Filt(5, 0x7E8);

    CAN.setMode(MCP_NORMAL);
    //CAN.setMode(MCP_LOOPBACK);

    pinMode(2, INPUT);
    Serial.println("And then?....");
}


void sendPid(unsigned char __pid){
    unsigned char tmp[8] = {0x02, 0x01, __pid, 0x55, 0x55, 0x55, 0x55, 0x55};
    CAN.sendMsgBuf(CAN_ID_PID, 8, tmp);
}

bool getSpeed(int *s)
{
    sendPid(PID_VEHICLE_SPEED);
    unsigned long __timeout = millis();
    Serial.println("Message Sent Successfully!");

    while(millis()-__timeout < 1000)      // 1s time out
    {
        unsigned long rxID;
        unsigned char len = 0;
        unsigned char buf[8];

        if (CAN_MSGAVAIL == CAN.checkReceive()){                // check if get data
            CAN.readMsgBuf(&rxID, &len, buf);    // read data,  rxID: Recieve ID, len: data length, buf: data buf

            if(buf[1] == 0x41)
            {
                *s = buf[3];
                return 1;
            }
        }
    }

    return 0;
}


void loop() {

    int __speed = 0;
    int ret = getSpeed(&__speed);
    if(ret)
    {
        Serial.print("Vehicle Speed: ");
        Serial.print(__speed);
        Serial.println(" kmh");
    }
    delay(500);
}

// END FILE

And here is what is on the serial monitor....

18:25:08.754 -> Entering Configuration Mode Successful!
18:25:08.754 -> Setting Baudrate Successful!
18:25:08.754 -> CAN init ok!
18:25:08.754 -> Starting to Set Mask!
18:25:08.754 -> Setting Mask Successful!
18:25:08.754 -> Starting to Set Filter!
18:25:08.754 -> Setting Filter Successful!
18:25:08.754 -> Starting to Set Filter!
18:25:08.754 -> Setting Filter Successful!
18:25:08.754 -> Starting to Set Mask!
18:25:08.754 -> Setting Mask Successful!
18:25:08.754 -> Starting to Set Filter!
18:25:08.754 -> Setting Filter Successful!
18:25:08.754 -> Starting to Set Filter!
18:25:08.754 -> Setting Filter Successful!
18:25:08.754 -> Starting to Set Filter!
18:25:08.754 -> Setting Filter Successful!
18:25:08.754 -> Starting to Set Filter!
18:25:08.754 -> Setting Filter Successful!
18:25:08.754 -> And then?....
18:25:08.754 -> Message Sent Successfully!
18:25:10.235 -> Message Sent Successfully!
18:25:11.730 -> Message Sent Successfully!
18:25:13.227 -> Message Sent Successfully!

I appreciate any help I can get on this. I reached out to Longan Labs a few weeks back, and they have been completely silent. I thought this would be a simple little project, but it certainly has not been to date. Starting to get a bit frustrating. Thanks in advance!

ghost

I found their website. No idea what module you're using, so chose one at random:

reading through that, I found, in small print,

If you are using the SoftwareSerial of Arduino, please don't set the baud rate to 115200.

That's because, in general, Software Serial is pretty fraught with problems above 19200 (some say 38400).

So, maybe try lowering your baud rate to 9600, see if you can get it working there, then raise the rate and see how far you can take it.

Thanks for the response. This is what I am using....

https://docs.longan-labs.cc/1030008/

I was really hoping that was it. I went out and changed the serial baud rate to 9600 hoping for the best. Sadly, no change. Serial Monitor returns the same as above. Poo.

It will probably be something that easy...just not that.

Use that equipment to verify that your CANBed device is sending data, and to see if the car sends a response.

Great Idea! Luckily I had a splitter so I could hook up both at the same time. Hooked them both up....and good news!!! It is sending, and responding....

7E8	RX		CAN Frame			Standard CAN		8	8.0000000000000000	04 41 0C 00 00 AA AA AA
7E9	RX		CAN Frame			Standard CAN		8	8.0000000000000000	04 41 0C 00 00 AA AA AA
7E8	RX		CAN Frame			Standard CAN		8	8.0000000000000000	10 09 41 68 01 2C 00 00
7E8	RX		CAN Frame			Standard CAN		8	8.0000000000000000	05 62 20 29 2D DD AA AA
7E8	RX		CAN Frame			Standard CAN		8	8.0000000000000000	05 62 13 D0 2D DD AA AA
**7DF	RX		CAN Frame			Standard CAN		8	8.0000000000000000	02 01 0D 55 55 55 55 55**
*7E8	RX		CAN Frame			Standard CAN		8	8.0000000000000000	03 41 0D 00 AA AA AA AA*
7E8	RX		CAN Frame			Standard CAN		8	8.0000000000000000	05 62 13 21 09 E4 AA AA
*7E9	RX		CAN Frame			Standard CAN		8	8.0000000000000000	03 41 0D 00 AA AA AA AA*
7E8	RX		CAN Frame			Standard CAN		8	8.0000000000000000	04 62 10 03 47 AA AA AA
7E8	RX		CAN Frame			Standard CAN		8	8.0000000000000000	04 62 10 01 46 AA AA AA
7E8	RX		CAN Frame			Standard CAN		8	8.0000000000000000	03 41 11 26 AA AA AA AA
7E8	RX		CAN Frame			Standard CAN		8	8.0000000000000000	05 62 29 82 0C 93 AA AA
**7DF	RX		CAN Frame			Standard CAN		8	8.0000000000000000	02 01 0D 55 55 55 55 55**
*7E8	RX		CAN Frame			Standard CAN		8	8.0000000000000000	03 41 0D 00 AA AA AA AA*
7E8	RX		CAN Frame			Standard CAN		8	8.0000000000000000	04 62 20 A1 2B AA AA AA
*7E9	RX		CAN Frame			Standard CAN		8	8.0000000000000000	03 41 0D 00 AA AA AA AA*
7E8	RX		CAN Frame			Standard CAN		8	8.0000000000000000	03 41 46 30 AA AA AA AA

Above is a snip of the output from my other equipment. Two asterix is the request from the CANBed. And one asterix is the response from the car. The first response (7E8) is from ECU and the second response (7E9) is from the TCU.

So...the CANBed is communicating. Yeah! It is just not seeing the response. Now, is there just a coding issue in my response? Or is the INT pin incorrect? Feel like it is coding based on all the reading I have done, since I am so new to Arduino.

Put a Serial.println("message received") under the CAN.readMsgBuf like so.

CAN.readMsgBuf(&rxID, &len, buf);
Serial.println("message received");

That will show if any data is being received.

If you get nothing then use the receive demo and send some data from your test equipment.

So progress...sort of. I now know that Pin 2 is correct for the interrupt. But I am still having some trouble receiving.

I added the serial print message you recommended...and no message came. It is clearly not seeing a "message available".

So then I used the CAN Receive code...and pushed some PIDs with my equipment. The CANBed received all of them perfectly. All came in and matched as expected. So as I said above, that does confirm that I have the pins set correctly. So then I looked at the coding for the receiving...

This one does not receive....

CAN.setMode(MCP_NORMAL);
pinMode(2, INPUT);


bool getSpeed(int *s)
{
    sendPid(PID_VEHICLE_SPEED);
    Serial.println("Message Sent Successfully!");

    while(millis()-__timeout < 50)      // 50ms time out
    {

        if (CAN_MSGAVAIL == CAN.checkReceive()){                // check if get data
            CAN.readMsgBuf(&rxID, &len, rxBuf);    // read data,  rxID: Recieve ID, len: data length, rxBuf: data buf
            Serial.println("Message Received!");

            if(rxBuf[1] == 0x41)
            {
                *s = rxBuf[3];
                return 1;
            }
        }
    }
    return 0;
}

And this one receives a message with no issues...

CAN.setMode(MCP_NORMAL);
pinMode(2, INPUT);


void loop()
{
  if(CAN_MSGAVAIL == CAN0.checkReceive())                         // If CAN0_INT pin is low, read receive buffer
  {
    CAN0.readMsgBuf(&rxId, &len, rxBuf);      // Read data: len = data length, rxbuf = 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();
  }
}

Anyone see a difference?

The obvious difference is the timeout. It currently shows a 50ms timeout. It was originally 1 second. I have actually completely removed the timeout and tested, and the same result. It simply does not see a message available.

Anything else I am missing? Any other ideas? Made some great progress, just need to figure out how to make it see its own response. Thanks!

ghost

Following up in case this helps someone in the future. I solved this today...

Working on it over the last couple of days, I noticed that this cars CANBus would respond really fast. So I knew the timeout that was in the code originally was not helping. I tried just removing the timeout all together and it still didn't make a difference. Because I am not looking for all CAN traffic, only the traffic (e.g. response) I wanted, I could simplify the code specific to my needs.

First thing I did was removed all the masking and filters. Because I am only looking for one specific response, I don't need masks to differentiate. I just need the response of that I am asking for...

And with that in mind, I combined everything into one loop, to make it check for the response immediately after sending the request. Rather than having a send loop and a receive loop, I put it all into one. I ended up with this...

//

#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 PID_ENGINE_RPM      0x0C
#define PID_VEHICLE_SPEED   0x0D
#define PID_COOLANT_TEMP    0x05

#define CAN_ID_PID          0x7DF

#define CAN0_INT 2                              // Set INT to pin 2
MCP_CAN CAN0(17);                               // Set CS to pin 17


void setup()
{
  Serial.begin(9600);
  
  // 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.
  //CAN0.setMode(MCP_LOOPBACK);
  pinMode(CAN0_INT, INPUT);                            // Configuring pin for /INT input
  
  Serial.println("MCP2515 Library Receive Example...");
}

void loop(){

  unsigned char tmp[8] = {0x02, 0x01, 0x0D, 0x55, 0x55, 0x55, 0x55, 0x55};
  CAN0.sendMsgBuf(CAN_ID_PID, 8, tmp);
  Serial.println("Message Sent...");

  if(CAN_MSGAVAIL == CAN0.checkReceive())                         // If CAN0_INT pin is low, read receive buffer
  {
    CAN0.readMsgBuf(&rxId, &len, rxBuf);      // Read data: len = data length, rxbuf = data byte(s)
    

      sprintf(msgString, "Standard ID: 0x%.3lX       DLC: %1d  Data:", rxId, len);
      Serial.print(msgString);
  
      for(byte i = 0; i<len; i++){
      sprintf(msgString, " 0x%.2X", rxBuf[i]);
      Serial.print(msgString);
      }
    }
        
    Serial.println();
    delay(5000);
  }

And here is what it looks like on the serial monitor...sends a request every 5 seconds...

Message Sent...
Standard ID: 0x7E8       DLC: 8  Data: 0x03 0x41 0x0D 0x00 0xAA 0xAA 0xAA 0xAA
Message Sent...
Standard ID: 0x7E8       DLC: 8  Data: 0x03 0x41 0x0D 0x00 0xAA 0xAA 0xAA 0xAA
Message Sent...
Standard ID: 0x7E8       DLC: 8  Data: 0x03 0x41 0x0D 0x00 0xAA 0xAA 0xAA 0xAA

Still need to clean up the code some more now that I have it working. But hopefully this will help someone in the future. Again, this is for the CANBed V1

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.