Teensy 3.1 and CAN Bus

Played around a bit and the solution is right here:

Code:
#include <FlexCAN.h>

unsigned long time=0;
byte stopper=0;

class ExampleClass : public CANListener 
{
public:
   void printFrame(CAN_message_t &frame, int mailbox);
   void gotFrame(CAN_message_t &frame, int mailbox); //overrides the parent version so we can actually do something
};

void ExampleClass::printFrame(CAN_message_t &frame, int mailbox)
{
   Serial.print(stopper);
   Serial.print(" ID: ");
   Serial.print(frame.id, HEX);
   Serial.print(" Data: ");
   for (int c = 0; c < frame.len; c++) 
   {
      Serial.print(frame.buf[c], HEX);
      Serial.write(' ');
   }
   Serial.write('\r');
   Serial.write('\n');
}

void ExampleClass::gotFrame(CAN_message_t &frame, int mailbox)
{
    printFrame(frame, mailbox);
}

ExampleClass exampleClass;

// -------------------------------------------------------------
void setup(void)
{
  delay(1000);
  Serial.println(F("Go"));

  Can0.begin(500000);  
  Can0.attachObj(&exampleClass);
  exampleClass.attachGeneralHandler();

}


// -------------------------------------------------------------
void loop(void)
{
  if(millis()>2000 && stopper==0){exampleClass.detachGeneralHandler();Serial.println("stop");stopper++;} // works!
 
  if(millis()>4000 && stopper==1){Can0.attachObj(&exampleClass);exampleClass.attachGeneralHandler();Serial.println("start");stopper++;}
}
 
Hi All,

I am having trouble getting my Teensy 3.2 to read CAN data and I was hoping some of you guys that are used to it can point out the error in my ways.

I am new to Teensy but a moderate Arduino user. I have previously used an Arduino paired with MCP2515 and MCP2551 to both send and recieve CAN data to and from an engine ECU.
I got interested in the Teensy because of the inbuilt CAN functionality and higher I/O capacity but have been so far unsuccessful with CAN on the Teensy.

As part of my setup, I have an ECU and known Arduino connected as nodes in the bus as well as the Teensy. Both ECU and Arduino are sending and receiving messages successfully but the Teensy does not appear to be reading any messages.

I have a Teensy 3.2 with the below code loaded onto it. The code is based off a snippet for receiving only that I found on this forum. I am using a PDIP MCP2551 transceiver powered by a regulated 5V supply. The bus includes 120ohm terminating resistors at both ends, the MCP2551 has a 10k slope control resistor between pin 8 & ground and the Teensy is connected to the MCP2551 as follows:

Teensy Pin 3 --> MCP2551 Pin 1
Teensy Pin 4 --> MCP2551 Pin 4

At the moment, I am just wanting the Teensy to read data from the bus but it appears that does not see any data on the bus as the "if (CANbus.read(rxmsg))" statement does not get fulfilled and goes straight to the "else" part.

If anyone can shed any light on something I might be missing or have any suggestions then they would be most welcome!


Code:
#include <FlexCAN.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH1106.h>

#define OLED_RESET 4
Adafruit_SH1106 display(OLED_RESET);

FlexCAN CANbus(1000000);  //1M bus
static CAN_message_t rxmsg,txmsg;
//int txCount;


// Setup Loop -------------------------------------------------------------
void setup() {
  
  Serial.begin(115200);
  display.begin(SH1106_SWITCHCAPVCC, 0X3C);
  
  display.setTextSize(2); 
  display.setTextColor(WHITE);
  
  CANbus.begin();
  Serial.print("CAN Init");
  
  }

// Main Loop -------------------------------------------------------------

void loop() {
  
  if(!CANbus.available()); {
    display.clearDisplay(); //all pixels off
    display.setTextSize(2);
    display.setCursor(0,0);
    display.println("CAN OK");
    display.display();
    //Serial.println(CANbus.available());
    
    if (CANbus.read(rxmsg)){   
      //display.clearDisplay(); //all pixels off
      display.setTextSize(2);
      display.setCursor(0,30);
      display.println("MSG REC");
      display.display();
      //Serial.print("ID=== ");Serial.print(rxmsg.id,HEX);
      //Serial.print(", BUF0= ");Serial.print(rxmsg.buf[0],HEX);
      //Serial.print(", BUF1= ");Serial.print(rxmsg.buf[1],HEX);
      //Serial.print(", BUF2= ");Serial.print(rxmsg.buf[2],HEX);
      //Serial.print(", BUF3= ");Serial.print(rxmsg.buf[3],HEX);
      //Serial.print(", BUF4= ");Serial.print(rxmsg.buf[4],HEX);
      //Serial.print(", BUF5= ");Serial.print(rxmsg.buf[5],HEX);
      //Serial.print(", BUF6= ");Serial.print(rxmsg.buf[6],HEX);
      //Serial.print(", BUF7= ");Serial.println(rxmsg.buf[7],HEX);
      }
      
      else {
        display.clearDisplay(); //all pixels off
        display.setTextSize(2);
        display.setCursor(0,30);
        display.println("NO MSG");
        display.display();
        //Serial.println("NO MSG");
        }
        }
            
            }
 
The current FlexCAN library is incompatible with earlier versions, so your code won't work:
https://forum.pjrc.com/threads/45344-Tennsy-3-2-doesn-t-read-CAN-messages

I think I see where the issue is now thank you. I hadn't appreciated that the FlexCAN library is included in current releases of TeensyDuino. I take it the built in library is the correct and up to date version? I had downloaded Teachops library from Github and assumed the #include <FlexCAN.h> was referring to this library? I assume the built in library takes precedence? I will try to adjust the code and remove the additional library tonight and see how I get on.


jblaze: I copied this line from another users code and I must admit it did confuse me slightly as it implies that the second if statement only gets executed when CANbus.available() returns 0. This seems counter intuitive! I had removed that if statement altogether though and was still not seeing any data on the bus. I till try TNI's suggestions first and see.

Thank you both for your input.
 
So deleting the additional FlexCan library and adjusting the code to the new format worked. Thank you!

Even with proper masks and filters in place though I am fnding that the data is being read off the bus quite slowly. Approx 2Hz. The bus speed is 1Mbps and I know data is being sent onto the bus at least 10x the rate the Teensy is reading it and the Arduino is also reading it as quickly as I would expect.

Is this slow read rate normal for the Teensy? Is the anything I can do to improve it? I don't need lightning fast read rates but 10-20Hz would be acceptable.
 
At 1Mbps, you can have around 12000 messages per second maximum (small packets). Teensy 3.2 has no problems whatsoever handling that.

Even with proper masks and filters in place though I am fnding that the data is being read off the bus quite slowly. Approx 2Hz.
What does that mean? Are you looking at the refresh rate of a slow I2C display? If so, try without the display and dump the messages to USB serial.
 
At 1Mbps, you can have around 12000 messages per second maximum (small packets). Teensy 3.2 has no problems whatsoever handling that.

What does that mean? Are you looking at the refresh rate of a slow I2C display? If so, try without the display and dump the messages to USB serial.

Thats what I thought. I couldn't understand what would be causing the controller to only update the CAN message at 2Hz! I was trying to output the message value over both the I2C display and the serial and it was through the serial monitor that I figured the refresh rate was 2 Hz. Originally I was just letting the buffer receive all messages and then finding the data I wanted using an IF statement to check the message ID. I thought this may have been causing the buffer to drop messages and mean that the IF statement was missing some data so I implemented a mask and filter to rule out that as a cause.

After you mentioned it I removed the OLED code lines and now the data refresh rate is where I expected it. I know I2C displays aren't the fastest but 2 Hz?
 
Can someone update me?

Hi --

I have been absent this discussion over the last 6-10 months.

Is the included FlexCAN library with Teensyduino the latest version, or should I be accessing a different library?

Thanks!
David
 
According to what jpdiag/melcodiag displays, horizontal and vertical might be swapped in your definitions of throttle angles (and then %) - while it's not a big deal, are you sure of your mapping?
(this is based on looking at what MelcoDiag displays 'TPS V = 21' and 'TPS H = 22' and ELM327 message '2A2C3333190000C8' on the serial port)

Here is an example of the 080 message for the Panigale
Byte 0, bit no 1, length 7 = Horizontal throttle angle
Byte 1, bit no 1, length 7 = Vertical throttle angle
Byte 2, bit no 0, length 8 = Horizontal throttle %
Byte 3, bit no 0, length 8 = Vertical throttle %
 
Hello, I'm quite new on all this world. I am trying to communicate my teensy with my car obdii port to get some data to display it on a screen but I do not succedd on it. I was reading and I think my problem is regarding the hardware instead of software. I was reding and it seems I cannot transmit and receive data on the same canbus pins of the teensy (mine is teensy 3.2), is this right or did I misundertand something? Do I need a transreceiver or what do I need to be able to request the desired pid and receive the answer?

Thanks!
 
Hi, is there a right place for advertising? I have CAN Transceiver Breakout Board to sell for LOW Speed Fault Tolerant Comfort CAN for older cars. search for my name on ebay.
(mods move or delete if discouraged)
 
Hello,

I have the compilation error you see below when i try to use it on a Arduino MEGA 2560 R3.
Is it possible that the library is not compatible with this board? Any solution?
Code:
C:\Users\dragosm\Documents\Arduino\libraries\FlexCAN\FlexCAN.cpp: In constructor 'FlexCAN::FlexCAN(uint32_t, uint8_t, uint8_t, uint8_t)':
C:\Users\dragosm\Documents\Arduino\libraries\FlexCAN\FlexCAN.cpp:43:20: error: 'CORE_PIN32_CONFIG' was not declared in this scope
     if(txAlt == 1) CORE_PIN32_CONFIG = PORT_PCR_MUX(2); else CORE_PIN3_CONFIG = PORT_PCR_MUX(2);
                    ^~~~~~~~~~~~~~~~~
C:\Users\dragosm\Documents\Arduino\libraries\FlexCAN\FlexCAN.cpp:43:40: error: 'PORT_PCR_MUX' was not declared in this scope
     if(txAlt == 1) CORE_PIN32_CONFIG = PORT_PCR_MUX(2); else CORE_PIN3_CONFIG = PORT_PCR_MUX(2);
                                        ^~~~~~~~~~~~
C:\Users\dragosm\Documents\Arduino\libraries\FlexCAN\FlexCAN.cpp:43:40: note: suggested alternative: 'UINTPTR_MAX'
     if(txAlt == 1) CORE_PIN32_CONFIG = PORT_PCR_MUX(2); else CORE_PIN3_CONFIG = PORT_PCR_MUX(2);
                                        ^~~~~~~~~~~~
                                        UINTPTR_MAX
C:\Users\dragosm\Documents\Arduino\libraries\FlexCAN\FlexCAN.cpp:43:62: error: 'CORE_PIN3_CONFIG' was not declared in this scope
     if(txAlt == 1) CORE_PIN32_CONFIG = PORT_PCR_MUX(2); else CORE_PIN3_CONFIG = PORT_PCR_MUX(2);
                                                              ^~~~~~~~~~~~~~~~
C:\Users\dragosm\Documents\Arduino\libraries\FlexCAN\FlexCAN.cpp:43:81: error: 'PORT_PCR_MUX' was not declared in this scope
     if(txAlt == 1) CORE_PIN32_CONFIG = PORT_PCR_MUX(2); else CORE_PIN3_CONFIG = PORT_PCR_MUX(2);
                                                                                 ^~~~~~~~~~~~
C:\Users\dragosm\Documents\Arduino\libraries\FlexCAN\FlexCAN.cpp:43:81: note: suggested alternative: 'UINTPTR_MAX'
     if(txAlt == 1) CORE_PIN32_CONFIG = PORT_PCR_MUX(2); else CORE_PIN3_CONFIG = PORT_PCR_MUX(2);
                                                                                 ^~~~~~~~~~~~
                                                                                 UINTPTR_MAX
C:\Users\dragosm\Documents\Arduino\libraries\FlexCAN\FlexCAN.cpp:44:20: error: 'CORE_PIN25_CONFIG' was not declared in this scope
     if(rxAlt == 1) CORE_PIN25_CONFIG = PORT_PCR_MUX(2); else CORE_PIN4_CONFIG = PORT_PCR_MUX(2);// | PORT_PCR_PE | PORT_PCR_PS;
                    ^~~~~~~~~~~~~~~~~
C:\Users\dragosm\Documents\Arduino\libraries\FlexCAN\FlexCAN.cpp:44:40: error: 'PORT_PCR_MUX' was not declared in this scope
     if(rxAlt == 1) CORE_PIN25_CONFIG = PORT_PCR_MUX(2); else CORE_PIN4_CONFIG = PORT_PCR_MUX(2);// | PORT_PCR_PE | PORT_PCR_PS;
                                        ^~~~~~~~~~~~
C:\Users\dragosm\Documents\Arduino\libraries\FlexCAN\FlexCAN.cpp:44:40: note: suggested alternative: 'UINTPTR_MAX'
     if(rxAlt == 1) CORE_PIN25_CONFIG = PORT_PCR_MUX(2); else CORE_PIN4_CONFIG = PORT_PCR_MUX(2);// | PORT_PCR_PE | PORT_PCR_PS;
                                        ^~~~~~~~~~~~
                                        UINTPTR_MAX
C:\Users\dragosm\Documents\Arduino\libraries\FlexCAN\FlexCAN.cpp:44:62: error: 'CORE_PIN4_CONFIG' was not declared in this scope
     if(rxAlt == 1) CORE_PIN25_CONFIG = PORT_PCR_MUX(2); else CORE_PIN4_CONFIG = PORT_PCR_MUX(2);// | PORT_PCR_PE | PORT_PCR_PS;
                                                              ^~~~~~~~~~~~~~~~
C:\Users\dragosm\Documents\Arduino\libraries\FlexCAN\FlexCAN.cpp:44:81: error: 'PORT_PCR_MUX' was not declared in this scope
     if(rxAlt == 1) CORE_PIN25_CONFIG = PORT_PCR_MUX(2); else CORE_PIN4_CONFIG = PORT_PCR_MUX(2);// | PORT_PCR_PE | PORT_PCR_PS;
                                                                                 ^~~~~~~~~~~~
C:\Users\dragosm\Documents\Arduino\libraries\FlexCAN\FlexCAN.cpp:44:81: note: suggested alternative: 'UINTPTR_MAX'
     if(rxAlt == 1) CORE_PIN25_CONFIG = PORT_PCR_MUX(2); else CORE_PIN4_CONFIG = PORT_PCR_MUX(2);// | PORT_PCR_PE | PORT_PCR_PS;
                                                                                 ^~~~~~~~~~~~
                                                                                 UINTPTR_MAX
C:\Users\dragosm\Documents\Arduino\libraries\FlexCAN\FlexCAN.cpp:58:3: error: 'OSC0_CR' was not declared in this scope
   OSC0_CR |= OSC_ERCLKEN;
   ^~~~~~~
C:\Users\dragosm\Documents\Arduino\libraries\FlexCAN\FlexCAN.cpp:58:14: error: 'OSC_ERCLKEN' was not declared in this scope
   OSC0_CR |= OSC_ERCLKEN;
              ^~~~~~~~~~~
C:\Users\dragosm\Documents\Arduino\libraries\FlexCAN\FlexCAN.cpp:59:36: error: 'SIM_SCGC6' was not declared in this scope
   if(flexcanBase == FLEXCAN0_BASE) SIM_SCGC6 |=  SIM_SCGC6_FLEXCAN0;
                                    ^~~~~~~~~
C:\Users\dragosm\Documents\Arduino\libraries\FlexCAN\FlexCAN.cpp:59:50: error: 'SIM_SCGC6_FLEXCAN0' was not declared in this scope
   if(flexcanBase == FLEXCAN0_BASE) SIM_SCGC6 |=  SIM_SCGC6_FLEXCAN0;
                                                  ^~~~~~~~~~~~~~~~~~

exit status 1

Compilation error: exit status 1

My code:
Code:
#include <FlexCAN.h>

// Define CAN message ID and data length
#define CAN_ID 0x123
#define CAN_DLEN 8

// Define joystick pins
#define JOYSTICK_X A0
#define JOYSTICK_Y A1

// Define motor parameters
#define MAX_SPEED 32767
#define MAX_ACCEL 32767

// Define CAN message data structure
struct MotorCommand {
  int32_t position;
  int16_t speed;
  int16_t accel;
};

// Initialize CAN bus and message buffer
FlexCAN CANbus(500000);
static CAN_message_t msg;

void setup() {
  // Initialize serial communication and CAN bus
  Serial.begin(9600);
  while (!Serial) {}
  CANbus.begin();

  // Set joystick pins as inputs
  pinMode(JOYSTICK_X, INPUT);
  pinMode(JOYSTICK_Y, INPUT);
}

void loop() {
  // Read joystick position and map to motor speed
  int16_t joystick_x = analogRead(JOYSTICK_X);
  int16_t joystick_y = analogRead(JOYSTICK_Y);
  int16_t speed = map(joystick_y, 0, 1023, -MAX_SPEED, MAX_SPEED);

  // Send motor command over CAN bus
  MotorCommand command = {0, speed, MAX_ACCEL};
  msg.id = CAN_ID;
  msg.len = CAN_DLEN;
  memcpy(msg.buf, &command, sizeof(command));
  CANbus.write(msg);

  // Print debug information
  Serial.print("Joystick X: ");
  Serial.print(joystick_x);
  Serial.print(", Joystick Y: ");
  Serial.print(joystick_y);
  Serial.print(", Speed: ");
  Serial.println(speed);

  // Wait for a short period of time before sending the next command
  delay(10);
}
 
You are right, I forgot to mention, I have a CAN-BUS Shield V2.0 from SEEED. I will check on their website and see what I can find. Thank you for the reply!

I would greatly appreciate it if anyone with more experience could give me some tips on making this work, it's my second day trying so solve it and there is not much resource online.

photo_2023-04-25_15-08-31.jpg

I have made a new topic about this, here: https://forum.pjrc.com/threads/72666-CAN-BUS-Shield-V2-0-Tmotors-AK80-64
 
Last edited:
Back
Top