Not able to read CANbus data with Teensy 3.2 uController using the Flexcan library

Status
Not open for further replies.

Robinhva1

New member
We are converting a oldtimer Jaguar XJ-6 from 1988. It will be from the outside a classical jaguar expression but from the inside a electrical powered system. But to keep the originalnal dashboard cluster I need to develop a CANbus interface.

I already managed to work with the arduino due and the dueCAN library from Collin Kidder (https://github.com/collin80). Credits for that!

But now I want it to work with the Teensy 3.2 microcontroller. I am able to Send Canbus frames but for some reason I Cannot read any data. I have tried every FlexCAN library version availible. But nothing works. I am almost 100% sure the hardware connection is correct. My guess is that ther is a weird software isseu. Any Help or tips that can provide would be appreciated.

Some detaills:
a Teensy 3.2 microcontroller on a working CANbus line with a MCP2551 CANbus transeiver. On the same CAN bus line an arduino due with the GVRET SavvyCAN software to monitor the CANbus frames.
Flexcan version I used:
https://github.com/teachop/FlexCAN_Library
https://github.com/pawelsky/FlexCAN_Library
https://github.com/collin80/FlexCAN_Library

The working code I used to transmit :

#include <FlexCAN.h>
#include <kinetis_flexcan.h>

int led = 13;
// create CAN object
FlexCAN CANTransmitter(500000);
static CAN_message_t msg;

void setup() {
// init CAN bus
CANTransmitter.begin(500000);
pinMode(led, OUTPUT);
delay(1000);
Serial.println("CAN Transmitter Initialized");
}

void loop() {
Serial.print("Sending: ");
msg.id = 0x222;
msg.len = 2;
for(int i=0; i<msg.len; i++) {
msg.buf = '0' + i;
Serial.print(msg.buf); Serial.print(" ");
}
Serial.println("");
CANTransmitter.write(msg);
digitalWrite(led, !digitalRead(led));
delay(500);
}

The code to recieve ( that is not working ):

#include <FlexCAN.h>
#include <kinetis_flexcan.h>

int led = 13;
// create CAN object
FlexCAN CANReceiver(500000);
static CAN_message_t msg;

void setup() {
// init CAN bus
CANReceiver.begin(500000);
pinMode(led, OUTPUT);
delay(1000);
Serial.println("CAN Receiver Initialized");
}

void loop() {
while( CANReceiver.read(msg)) {
// toggle LEDs
digitalWrite(led, !digitalRead(led));
Serial.print("Receiving: ");
for(int i=0; i<msg.len; i++) {
Serial.print(msg.buf); Serial.print(" ");
}
Serial.println("");
}
}


NOTE: I used some information from an other topic. But I think there is an other problem.
(https://forum.pjrc.com/threads/41899-Teensy-3-2-Unable-to-get-a-successful-CAN-Bus-read)

already thank you all for the support!
 
you havn’t tried all libraries. there are multiple forks of those libraries some work some don’t. i believe the working one you need to search the forums for nmea2000 and you’ll find it. there is also a new one called IFCT which has a very easy interface for the user. The examples demonstrate it’s usage and simplicity, however this library is tailored specifically for teensy 3.x series (so 3.2 as well), you only need a transceiver to use the one built in your 3.2 :)

Tony
 
Modifications with IFCT library

Thanks you Tony! it worked at ones!
Robinhva1, will you please post the code you have working with the IFCT library? I assume you changed the #include statement to IFCT and renamed the buses. I am trying to send from a teensy 3.2 and receive on a teensy 3.6 canbus1. They seem to be operational but not transmitting and receiving, so I assume the changes I made were not correct. If you can't, I will repost with my code. Thanks, Gary
 
GLMc,

I used the example IFCT/examples/IFCTsimpleFIFOPolling/IFCTsimpleFIFOPolling.ino

it worked at ones with the teensy 3.6. Try this code and connect the transceiver wright.

I hope you can continue with your project.

Regards,
Robin
 
GLMc,

I used the example IFCT/examples/IFCTsimpleFIFOPolling/IFCTsimpleFIFOPolling.ino

it worked at ones with the teensy 3.6. Try this code and connect the transceiver wright.

I hope you can continue with your project.

Regards,
Robin

Thanks, Robin. I did try that example, also, with both Can0 and Can1 on two teensy 3.6 boards. I have a teensy 3.2 driving two MCP2562 transceivers to the teensy 3.6. The scope signal indicates the transmitted bits get to the receiver which acknowledges, but the teensy does not read any data. The only odd thing that I have seen is that the bits do not match up with the expected protocol. I see exactly the same scope trace as shown by moult https://forum.pjrc.com/threads/41899-Teensy-3-2-Unable-to-get-a-successful-CAN-Bus-read. For example, the id seems correct but the data length does not look right to me. In a couple of weeks I will have a logger dash so will try sending data then. Thanks, again, Gary
 
can you show your code? if they are getting acknowledged theres an issue with either your callback or your interrupts

i just set it up now on a t3.5 and t3.2 and i can see send and receives on both ends :)
make sure your transceivers are enabled as well, some people forget that
im using the dual can tindie boards here
 
can you show your code? if they are getting acknowledged theres an issue with either your callback or your interrupts

i just set it up now on a t3.5 and t3.2 and i can see send and receives on both ends :)
make sure your transceivers are enabled as well, some people forget that
im using the dual can tindie boards here

Here is the code for the Teensy 3.2 which is driving an Maxim MCP2562 transceiver. The transceivers have a standby which I have grounded but not an enable. I thought callback or interrupt was handled in the library so have not included anything there, so you are probably right. When I return home tonight I will add a photo of my setup. Great work on your library(s), by the way, and thanks for your help. Gary

Code:
#include <IFCT.h>
#include <kinetis_flexcan.h>

int led = 13;
// create CAN object
IFCT CAN0(500000);
static CAN_message_t msg;

void setup() {
  Serial.begin(115200);delay(3000);
// init CAN bus
CAN0.begin();
pinMode(led, OUTPUT); 
delay(1000);
Serial.println("CAN Transmitter Initialized");
}

void loop() {
Serial.print("Sending: ");
msg.id = 0x222;
msg.len = 2;
for(int i=0; i<msg.len; i++) { 
msg.buf[i] = '0' + i;
Serial.print(msg.buf[i]); Serial.print(" ");
}
Serial.println("");
CAN0.write(msg);
digitalWrite(led, !digitalRead(led));
delay(500);
}
Can+ and Can- are connected to a second MCP2562 which are, in turn, connected to the Teensy 3.6. Here is the code I am using to connect to Pins 3 and 4 on the 3.6.
Code:
#include <IFCT.h>

void setup() {
  pinMode(2, OUTPUT); // for the transceiver enable pin
  Can0.setBaudRate(500000);
  Can0.enableFIFO();
}

void loop() {
  CAN_message_t msg;
  if ( Can0.read(msg) ) canSniff(msg);
}

void canSniff(const CAN_message_t &msg) {
  Serial.print("MB "); Serial.print(msg.mb);
  Serial.print("  LEN: "); Serial.print(msg.len);
  Serial.print(" EXT: "); Serial.print(msg.flags.extended);
  Serial.print(" REMOTE: "); Serial.print(msg.rtr);
  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();
}
 
please dont use the constructor in the first code, Can0 is always available when IFCT.h is included.
your second example looks alright, verify that you are using pins 3 & 4 on t3.2/3.5/3.6, if your using the alternate ones on the t3.6 at end of board use the Can0.setRX(ALT) and Can0.setTX(ALT) to swap to them.

Second example is using polling not interrupts, either way are fine though, i would double check the connections and make sure a common ground exists between both teensies.
First code is not using interrupts or events, just used as a transmitter, its fine in this case, im pretty sure there is a connection issue, i wired mine today to pins 3&4 of teensy 3.2/3.5 on a breadboard and sending data back and forth
the transceivers are powered from teensy’s 3.3v pin and use 3.3v
 
please dont use the constructor in the first code, Can0 is always available when IFCT.h is included.
your second example looks alright, verify that you are using pins 3 & 4 on t3.2/3.5/3.6, if your using the alternate ones on the t3.6 at end of board use the Can0.setRX(ALT) and Can0.setTX(ALT) to swap to them.

Second example is using polling not interrupts, either way are fine though, i would double check the connections and make sure a common ground exists between both teensies.
First code is not using interrupts or events, just used as a transmitter, its fine in this case, im pretty sure there is a connection issue, i wired mine today to pins 3&4 of teensy 3.2/3.5 on a breadboard and sending data back and forth
the transceivers are powered from teensy’s 3.3v pin and use 3.3v

Thanks, Tony. I had not clued in on setting the alternate pins. I think you are right about a connection, or at least hardware problem. I rewired everything for the nth time and have measured all the grounds and voltages. The signal still goes through the Can bus to the 3.6 pin.4 Now, the acknowledge bit is not present from the 3.6 but the transmitted signal is being returned from the first transceiver MCP2562 on the T3.2 RX pin4??? These transceivers require 5V to power then 3.3V to drive the signals (through level shifters) and those voltages are correct but it may have failed.
My CAN bus is only an inch long and I am using a 50 ohm resistor so reflections could be an issue. I will also try different ids and data lengths as it may be as simple as the 3.6 not recognizing the transmission because of what seems to me two or three faulty bits coming from the 3.2. I will post again when I figure this out. Gary
 
Also if not already done canbus requires a 120 ohm termination, the resistor is already in place on the breakout board i use, possibly check yours?
 
Also if not already done canbus requires a 120 ohm termination, the resistor is already in place on the breakout board i use, possibly check yours?

I will check but I don't think there is one on either end. I will also get the right resistors... I just had 100 ohm.
 
Eureka! In the night it occurred to me the baud rates were maybe not matched between TX and RX. When I used your Can0.SetBaudRate in the TX everything worked, interrupts, polling... I also re-read the CAN specs and now realize there is a bit stuffed when 5 successive 0's or 1's so there were no bit errors. Finally, I realized that the transmitted signal will also show up on the receive line of the transmitter as it is just like any other node on the bus. Thanks, Tony, for helping me through this. Great library and great help. Gary
 
Status
Not open for further replies.
Back
Top