CAN Bus Library for Teensy 3.1

1. Yes you need a CAN transceiver, it won't work to just connect between parts CAN_H and _L directly. Also include termination (resistors).

BTW I don't think CAN terminals of the microcontroller would be called CAN_H/L, I would expect CAN_RX/TX or similar. CAN_L/H is what you get from the transceiver (which as teachop mentioned is necessary)
 
I was trying to get the Teensy 3.1 reading CAN today and discovered that the teachop library (Many thanks for that!) seems to use pins 5 & 6 on the Teensy 3.1 board as teachop states in the readme. I was initially confused since the very pretty pinout card that comes with the Teensy 3.1 shows CAN on pins 3 & 4 and I, being the "hardware guy", was not looking at libraries when I wired it up.

I have not yet sent any packets, but did successfully and accurately read some packets on the powertrain bus of a Model S.

I am using a SN65HVD235D CAN transceiver chip with a 10K slope control resistor to ground on RS and 1K safety series resistors in both RX and TX connections to the Teensy. At this time it is not in listen only mode, though that's why I selected this chip to have that option.

Not wanting to derail the conversation (meaning if you want to talk more about this application, lets find another thread) for general entertainment here's a picture of a Teensy in a Tesla, it's mounted on top of an Adafruit motor driver board. I verified packet accuracy by comparing data read on the Teensy to the Phytec CAN dongle.

TeensyInTesla.jpg
 
Starting with a suggestion from Paul, and with big thanks going to teachop, I've incorporated the FlexCAN library into a "unified" CAN library. One simple API gets you functionality for three different types of CAN controller; Microchip MCP2515, Atmel SAM3X (Due), and Freescale K2x (Teensy 3.1). It's not quite finished yet, but if you are interested in using it, take a look at https://github.com/McNeight/CAN-Library/

Comments and patches are more than welcome.

-Neil
 
Neil, any chance you might restructure this library? With all the .cpp and .h files in the "src" directory, it can only work with Arduino 1.5.6. Currently, Teensy 3.1 only supports Arduino 1.0.5. Many people using the MCP2515 are probably also on Arduino 1.0.5, since 1.5.x is still considered beta test.
 
Paul,

I went with the 1.5.x library layout for two reasons:
1) This was originally meant to be just between the MCP2515 and the Due, which only uses the 1.5.x series
2) The 1.5.x library format is the way Arduino libraries are going for the foreseeable future

One of the things I discovered is that the new library format is very particular about how files are laid out and formatted. If the library.properties file doesn't parse correctly, the library is unavailable to the IDE. Also, if you cut and paste the library.properties file from another library, forgetting to change the name of the library effectively makes it disappear. The "legacy" library format is much simpler. For my testing with the Teensy, I simply took the contents of the src directory and copied them into the top level library directory, and then copied over the examples directory.

Would it be helpful if I created a 1.0.x branch in the repository to push changes into? Or possibly the other way around, with master becoming a 1.0.x-release branch and then having a 1.5.x-devel branch as well?

-Neil
 
I'd go with the 1.0.x format and not use the 1.5.x format at all. My opinion may be biased, since I'm making a product that I only support on 1.0.x.

If you're good an managing multiple branches, then a 1.0.x branch probably makes a lot of sense. Personally, I'm terrible at managing more than 1 master branch, but there are people who are amazing good at it.

As you're seeing, the 1.5.x stuff is still pretty rough around the edges. The simple truth is pretty all 3rd party libraries are using the 1.0.x format today. The 1.5.x format today is at the earliest stages of "early adopter", which is usually a painful path for anything "new".

On the other hand, their latest library spec claims no more changes are coming, so perhaps there's nothing to fear?

One thing is pretty certain, nearly all libraries not distributed inside 1.5.6 are using the old 1.0.x format. They're going to have to keep Arduino compatible with the old format for a very, very long time.
 
I forgot to mention my third reason for going with a 1.5.x library was the mistaken belief that 1.5.x couldn't use 1.0.x libraries.

So, I wound up branching the repository so that I could easily find the 1.5.x version of the library if I wanted to switch or add to it for some reason, and now have master laid out as a 1.0.x style library.
 
Looking at the 5 examples, I'd recommend simplifying the #include stuff. Currently, it's this:

Code:
#include <Arduino.h>
#include <CAN.h>

#if defined(ARDUINO_ARCH_AVR) // Arduino with SPI interface to MCP2515 chip
#include <SPI.h>
#include <CAN_MCP2515.h>
#elif defined(ARDUINO_ARCH_SAM) // Arduino Due
#include <CAN_SAM3X.h>
#elif defined(__MK20DX256__) // Teensy 3.1
#include <CAN_K2X.h>
#else
#error "Your CAN controller is currently unsupported."
#endif

I'm hoping you'll simply to something like this:

Code:
#include <CAN.h>
#include <SPI.h>

Arduino as a platform is all about simplicity. Details like this are usually handled automatically in library headers, so end users can just use the library. When/if your library is extended to support CAN bus on other boards, like Maple or upcoming Energia boards, you'll only have to update 1 header instead of 5 examples. More importantly, if people using your library publish projects, all that code on other websites won't need to have its #ifdef stuff updated as the library grows.

Unfortunately, you do need to have "#include <SPI.h>", even though it's not necessary on Due & Teensy. Maybe some future version of Arduino will probably detect library dependencies (I tried to contribute this years ago, but David Mellis rejected the idea at the time). For quite a long time, we're all going to be stuck with this requirement. Fortunately, including SPI.h is harmless.

There's no need to include Arduino.h in the .ino file. The system always automatically includes it.
 
Hi Guys,

What's the final outcome with this library and the PIN assignment Teensy diagram says can is 3 and 4, yet lib says 5/6 are used - does this change the assignment or does it not matter or can I set this somewhere - forgive the newbie questions, but I am trying to build a hardware shield to use the can properly ?
 
Hi Guys,

What's the final outcome with this library and the PIN assignment Teensy diagram says can is 3 and 4, yet lib says 5/6 are used - does this change the assignment or does it not matter or can I set this somewhere - forgive the newbie questions, but I am trying to build a hardware shield to use the can properly ?
There is no issue. They are two different ways to talk about the same nets. The Teensy 3.1 module pins 5 and 6 are Arduino I/O 3 and 4 function.
 
@teachop - Thanks ! I have not yet wired it up yet - any tips and tricks for a newbie CAN user ? My goal is to have a private message system using can to multi drop to a number of teensy's to form a distributed network for redundancy and to share processing load (I suppose not to dissimilar to a car environment)
 
@teachop - Thanks ! I have not yet wired it up yet - any tips and tricks for a newbie CAN user ? My goal is to have a private message system using can to multi drop to a number of teensy's to form a distributed network for redundancy and to share processing load (I suppose not to dissimilar to a car environment)
Distributed I/O this way will probably work nicely with a roll-your-own approach. If you are good with the 8 byte limitation, then keep it simple!

For transferring blocks of information, a fragmentation protocol on top of CAN is recommended. You mentioned cars, the diagnostic protocol in cars (often ISO15765) has fragmentation support. I did my own (dead simple) stack, but I bet there are open source diagnostic projects out there to pull from.
 
First Robotics Competition / CAN

FRC http://www.usfirst.org/roboticsprograms/frc will be using an all new control system for 2015 competition. http://www.usfirst.org/roboticsprograms/frc/blog-2015-control-system-kop-survey

The new system implements CAN throughout. For example, the power distribution board(PDB) is a CAN node that can report current draw on each circuit. This could be used to detect wheel slippage(abnormally low current draw), or jammed mechanisms(abnormally high current draw).
The new pneumatic control module(PCM) is now solely controlled via CAN. One of the yet to be released motor controllers is CAN only http://www.usfirst.org/roboticsprograms/frc/blog-motor-controller-options-2015

I am a mentor on one of the teams(5002) currently doing the beta testing and have just ordered a few Teensy 3.1 for IO expansion and experimentation. Please contact me if you have questions, ideas, or Teensy code you would like tested with the new control system prior to release.
dmaki@usfirst.org
 
Am I right, that Teensy 3.1 cannot be used for CAN Bus reading itself without using an additional "Can Bus transceivers" attached to it? Or maybe somebody can show a wiring example for this board?
 
Thank you guys! This is great work!

Question,
If the rx buffer is full and another message is received which message is dropped?
 
Anyone getting compilation errors with flexcan?

Fresh 1.0.6 Arduino + Teensyduino 1.20 Install

Example code produces
Code:
Arduino: 1.0.6 + Td: 1.20 (Windows 7), Board: "Arduino Uno"
C:\Program Files (x86)\Arduino\libraries\FlexCAN\FlexCAN.cpp: In constructor 'FlexCAN::FlexCAN(uint32_t)':
C:\Program Files (x86)\Arduino\libraries\FlexCAN\FlexCAN.cpp:16: error: 'CORE_PIN3_CONFIG' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\FlexCAN\FlexCAN.cpp:16: error: 'PORT_PCR_MUX' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\FlexCAN\FlexCAN.cpp:17: error: 'CORE_PIN4_CONFIG' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\FlexCAN\FlexCAN.cpp:19: error: 'OSC0_CR' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\FlexCAN\FlexCAN.cpp:19: error: 'OSC_ERCLKEN' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\FlexCAN\FlexCAN.cpp:20: error: 'SIM_SCGC6' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\FlexCAN\FlexCAN.cpp:20: error: 'SIM_SCGC6_FLEXCAN0' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\FlexCAN\FlexCAN.cpp: In member function 'int FlexCAN::read(CAN_message_t&)':
C:\Program Files (x86)\Arduino\libraries\FlexCAN\FlexCAN.cpp:133: error: 'yield' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\FlexCAN\FlexCAN.cpp: In member function 'int FlexCAN::write(const CAN_message_t&)':
C:\Program Files (x86)\Arduino\libraries\FlexCAN\FlexCAN.cpp:197: error: 'yield' was not declared in this scope

Any thoughts?
 
Last edited:
Anyone getting compilation errors with flexcan?

Fresh 1.0.6 Arduino + Teensyduino 1.20 Install

Example code produces
Code:
  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.
Arduino: 1.0.6 + Td: 1.20 (Windows 7), Board: "Arduino Uno"
C:\Program Files (x86)\Arduino\libraries\FlexCAN\FlexCAN.cpp: In constructor 'FlexCAN::FlexCAN(uint32_t)':
C:\Program Files (x86)\Arduino\libraries\FlexCAN\FlexCAN.cpp:16: error: 'CORE_PIN3_CONFIG' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\FlexCAN\FlexCAN.cpp:16: error: 'PORT_PCR_MUX' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\FlexCAN\FlexCAN.cpp:17: error: 'CORE_PIN4_CONFIG' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\FlexCAN\FlexCAN.cpp:19: error: 'OSC0_CR' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\FlexCAN\FlexCAN.cpp:19: error: 'OSC_ERCLKEN' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\FlexCAN\FlexCAN.cpp:20: error: 'SIM_SCGC6' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\FlexCAN\FlexCAN.cpp:20: error: 'SIM_SCGC6_FLEXCAN0' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\FlexCAN\FlexCAN.cpp: In member function 'int FlexCAN::read(CAN_message_t&)':
C:\Program Files (x86)\Arduino\libraries\FlexCAN\FlexCAN.cpp:133: error: 'yield' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\FlexCAN\FlexCAN.cpp: In member function 'int FlexCAN::write(const CAN_message_t&)':
C:\Program Files (x86)\Arduino\libraries\FlexCAN\FlexCAN.cpp:197: error: 'yield' was not declared in this scope

Any thoughts?
Change the board to Teensy3.1 and check again please.
 
Back
Top