How to hook up CAN bus?

jim lee

Well-known member
I've been using a custom circuit board with a CAN chip on it for talking to my Teensy. There are CAN bus pins on this thing, how does one hook up a can bus to them? What does one need to read/write CAN messages using these pins? Is there hardware needed? Libraries?
 
@jim lee:

For CAN hardware connectivity with the T4.0, I've successfully used a SN65HVD230 breakout board connected to the following pins:

PIN D22/A8 = CAN1 TX (to CTX on SN65HVD230 breakout board)
PIN D23/A9 = CAN1 RX (to CRX on SN65HVD230 breakout board)

In <this> thread, I posted a sketch that I developed over a long period of time (with lots of help from others on this forum, most especially @PaulS) which I used extensively for querying & monitoring the CAN bus on my 2020 Honda Civic (& other vehicles as well).

Hope that helps . . .

Mark J Culross
KD5RXT
 
Would this work? Adafruit can bus interface
Or possibly this one? Waveshare SN65HVD230 - Found on Amazon.
@jim lee: Sorry, I don't have any personal experience with the Adafruit device. The CANbus interface that I used was ordered from Amazon (it was a SN65HVD230 breakout), however, it is no longer available. Based upon the fact that the Waveshare device is using the same SN65HVD230 primary IC, I would think that it should work as well.

Hope that helps !! Good luck & have fun !!

Mark J Culross
KD5RXT
 
@jim lee : I would definitely suggest the Waveshare board, it works fine.

These will probably also work [although there are fake SN65HVD230 parts out there]:

1786863815261.png


But be aware that the silkscreen may be wrong on the other side of the PCB. See this post.

Paul
 
To my knowledge all CANBus driver chips are equivalent dumb transceivers - all the smarts is in the microcontroller, so other than maximum baud rate limitations and maximum fanout limitations the transceiver chips should all inter-work.

But watch out for termination issues and very long busses - a 120R terminator at each end is required (for multidrop the intermediate transceivers need termination resistor disabled/unsoldered).
 
I think I have the termination issue already solved. It's a long bus with teminators on the ends. (35' Sailboat) I just cooked my original electronics. And need something to get myself back up and running. I'm going to give the Adafruit one a try because I can get it quick and know who to yell at if it doesn't work.
 
Ok I'm assuming this : FlexCAN_T4 is the library I want to use for this "TJA1051" board. This says it it goof for Teensy 4.0 processors.

The way the example creates the instance of the interface :
Code:
FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> Can0;

I'm not familiar with this kind of creation. typeName<this,that,theOther> objName; What's with these <> brackets? How are they different than the old ( ) brackets? I never learned templates. My previous driver I was able to create it as a pointer and use newObj = new typeName(Params); Is there some sort of mapping between the two types or creators?

Thanks Millions!
 
Ok I'm assuming this : FlexCAN_T4 is the library I want to use for this "TJA1051" board. This says it it goof for Teensy 4.0 processors.

The way the example creates the instance of the interface :
Code:
FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> Can0;

I'm not familiar with this kind of creation. typeName<this,that,theOther> objName; What's with these <> brackets? How are they different than the old ( ) brackets? I never learned templates. My previous driver I was able to create it as a pointer and use newObj = new typeName(Params); Is there some sort of mapping between the two types or creators?

Thanks Millions!
You can find an explanation here. (From Google Search)
 
I was unclear on my question. I can add in the library, no problem. It's that actual line with the < > brackets that I don't really understand how it works.

FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> Can0;
 
When the compiler builds templated code it substitutes the values for the template parameters. So you can write generic code once and then create specialized objects by using different parameters.
 
So, I"m still missing something on this built in CAN bus thing.

I"m using the Adafruit can bus interface along with FlexCAN_T4 library. Running the example I found at FlexCAN_T4 Github..

Code:
#include <FlexCAN_T4.h>

FlexCAN_T4<CAN3, RX_SIZE_256, TX_SIZE_16> Can0;
//    CHANGED CAN0 to CAN3

void setup(void) {
  Serial.begin(115200); delay(400);
  pinMode(6, OUTPUT); digitalWrite(6, LOW); /* optional tranceiver enable pin */
  Can0.begin();
  Can0.setBaudRate(1000000);
  Can0.setMaxMB(16);
  Can0.enableFIFO();
  Can0.enableFIFOInterrupt();
  Can0.onReceive(canSniff);
  Can0.mailboxStatus();
}

void canSniff(const CAN_message_t &msg) {
  Serial.print("MB "); Serial.print(msg.mb);
  Serial.print("  OVERRUN: "); Serial.print(msg.flags.overrun);
  Serial.print("  LEN: "); Serial.print(msg.len);
  Serial.print(" EXT: "); Serial.print(msg.flags.extended);
  Serial.print(" TS: "); Serial.print(msg.timestamp);
  Serial.print(" ID: "); Serial.print(msg.id, HEX);
  Serial.print(" Buffer: ");
  for ( uint8_t i = 0; i < msg.len; i++ ) {
    Serial.print(msg.buf[i], HEX); Serial.print(" ");
  } Serial.println();
}

void loop() {
  Can0.events();
 
  static uint32_t timeout = millis();
  if ( millis() - timeout > 200 ) {
    CAN_message_t msg;
    msg.id = random(0x1,0x7FE);
    for ( uint8_t i = 0; i < 8; i++ ) msg.buf[i] = i + 1;
    Serial.println("writing");
    Can0.write(msg);
    Can0.mailboxStatus();
    timeout = millis();
  }

}

Using pins 30 CRX3 & 31 CTX3

Hooking Rx - Rx & Tx to Tx from the Teensy to the Adafruit board.

Using the scope I can see there is incoming and outgoing messages. But I never see canSniff() get called. And the output looks like it's filling buffers but not getting anything sent.

Example:
Code:
FIFO Enabled --> Interrupt Enabled
    FIFO Filters in use: 8
    Remaining Mailboxes: 8
        MB8 code: TX_DATA (Transmitting)(Standard Frame)(ID: 0x76D)(Payload: 1 2 3 4 5 6 7 8)
        MB9 code: TX_DATA (Transmitting)(Standard Frame)(ID: 0x4BC)(Payload: 1 2 3 4 5 6 7 8)
        MB10 code: TX_DATA (Transmitting)(Standard Frame)(ID: 0x489)(Payload: 1 2 3 4 5 6 7 8)
        MB11 code: TX_INACTIVE
        MB12 code: TX_INACTIVE
        MB13 code: TX_INACTIVE
        MB14 code: TX_INACTIVE
        MB15 code: TX_INACTIVE

I must be missing something fundamental here. Anyone?

Thanks!

-jim lee
 
Yes, the resistors are there. And the ends of my tiny bus.

One thing I failed to mention is that this is NMEA2000 bus. It runs on the extended CAN Bus.

IMG_0608.JPG
IMG_0611.JPG
 
Check the baudrate on the Teensy. NMEA2000 normally runs at 250kbps. Your code is set at 1Mbps.
 
I was foggy on the entire baud rate of NMEA2K. There was a baud() command on my orignial harware. It was originally set to 500E3. I asked about it, and thought they said each device sets it's own? Or something similar? I was taking in a lot of new info. at the time, so who knows? I don't recall hearing NMEA2K had a standard rate. Makes more sense to me than what I thought I'd heard. I'd tried 500E3 as before, with same results. I wanted to change the example as little as possible so I left the 1Mbps baud as I found it. Setting the baud to 250E3 PRESTO! Data flows in and out!

And IT WORKS!!

Thank you SO SO much for that last piece of the puzzle!
 
Back
Top