Teensy 3.1 and CAN Bus

Maybe I should clarify selling, if I'm lucky I might recoup a $1 or $2 per board after components, solder, time, and shipping, I would hardly call it a commercial enterprise selling 1000/week. Just as you contributed your design to the community, I'm offering an easy option for those that can't (or don't) want to hunt down components and solder SMD parts; buying bare boards isn't within everybody's wheel house. If you don't want me to offer them thats fine, however, I'm not the only member whose offered to assemble boards for people (@onehorse)

There is only one rule and it is very clear - as long as you or anybody else is making ANY profit of it (and I know exactly what's the cost of components to build these boards), you are violating the 'license' under which this design has been made available. You didn't even bother to contact me before offering these for sale so you shouldn't be surprised that I'm not happy about your 'offer'.
 
There is only one rule and it is very clear - as long as you or anybody else is making ANY profit of it (and I know exactly what's the cost of components to build these boards), you are violating the 'license' under which this design has been made available. You didn't even bother to contact me before offering these for sale so you shouldn't be surprised that I'm not happy about your 'offer'.

You may know how much components cost (though that varies based on vendor and quantity), but that doesn’t include my time and shipping, which isn't even accounted for in my list below, likely another $2 USPS, making my so called profit nil.

CAN Transceiver (1) 2.07
Capacitors (2) 0.52
3.3V Regulator (1) 0.85
Boards (1) 1.75
Soldering at $35/hr - 30min 18
Brk Away Headers 0.25
SD Slot 0.21
Grand Total (no shipping) 23.65

I would like to sincerely apologize for what you thought was me taking advantage, I was just trying to help. As such, I have removed the offer from my previous post.
 
Has anyone looked at an interrupt routine in the code that gets serviced when one of the RX filters matches?
 
Hi guys

This is my first post in this forum, but i'm being using it for some time, solving my doubts with the help of what you've posted before.

I'm doing a project that involves using 6 Teensy 3.1, and I want to use the CANBus to have communication between them, actually it's more between a Master and 5 Slaves.

Things went quite well, I have the protocol set, and the bus working, when I use one to one communication (2 teensy on the bus).

When I add more teensy 3.1, the canbus doesn't work.

My test setup has a 5V power supply, and every teensy is powered by it, I'm not powering them through the USB port.
I have terminator (120 Ohm), in the start and in the end of the bus, also followed this troubleshooting guide http://www.esd-electronics-usa.com/CAN-Bus-Troubleshooting-Guide.html
Everything is good. The same happens if I only have one terminator resistor.

I noticed that when I have only three teensy 3.1 in the bus, and I disconnect one of them from the bus, the messages sent previously start being sent (in the other two), so I think this is a hardware related problem.

Because I have a few teensy 3.1 with me I've tested with each one of them, and the symptoms are all the same.

Also I wrote this code to test the bus:

Code:
#include <FlexCAN.h>

int ledPin = 13;
FlexCAN CANbus(250000);
static CAN_message_t rxmsg, txmsg;
String msg;
bool pinState;

// -------------------------------------------------------------
void setup(void)
{
  Serial.begin(38400);
  CANbus.begin();
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, 1);
  delay(1000);
  Serial.println(F("Hello Teensy 3.1 CAN Test."));
}

// -------------------------------------------------------------
void loop(void)
{
  String Smsg;
  while (!CANbus.available()){
    toggle(ledPin);
    delay(25);
  }
  if (CANbus.read(rxmsg) )
    printCanMsg(rxmsg);   
  delay(1000);
  toggle(ledPin);
}

void toggle(int pinNum) {
  // set the LED pin using the pinState variable:
  digitalWrite(pinNum, pinState); 
  // if pinState = 0, set it to 1, and vice versa:
  pinState = !pinState;
}

void printCanMsg(CAN_message_t m){
  String a = "";
  for (int i=0; i<m.len ; i++)
    a += (char)m.buf[i];
  Serial.println(a);
}

void serialEvent(){
  char inChar;
  while (Serial.available()){
    inChar = (char)Serial.read();
    switch (inChar){
      case 'a':
        sendmsg1();
      break;
      case 'b':
        sendmsg2();
      break;
      default :
        sendmsg();  
    }
  }
}

void sendmsg(){
    String a="abcdefgh";
      txmsg.id=0x0001;
      txmsg.len=8;
      for (int i=0; i< txmsg.len; i++)
        txmsg.buf[i]=a[i];
      CANbus.write(txmsg);
}

void sendmsg1(){
    String a="12345678";
      txmsg.id=0x0001;
      txmsg.len=8;
      for (int i=0; i< txmsg.len; i++)
        txmsg.buf[i]=a[i];
      CANbus.write(txmsg);
}
void sendmsg2(){
    String a="A1B2C3D4";
      txmsg.id=0x0001;
      txmsg.len=8;
      for (int i=0; i< txmsg.len; i++)
        txmsg.buf[i]=a[i];
      CANbus.write(txmsg);
}

TeensyCanbus.jpg

Could you help me on this?
I appreciate it.
 
Last edited:
Hi guys

Could you help me on this?
I appreciate it.

CAN bus requires an interface chip that you seem to be lacking in your picture. It's basically an open collector bus. Your tx pins are not expecting to be tied together and that may damage the chips.
Maybe check out this project to help you on your way.
https://oshpark.com/shared_projects/VeJFD9qA
It may be possible to simulate it with resistors and diodes for a board level application like your demo, but I haven't really considered it before.
 
CAN bus requires an interface chip that you seem to be lacking in your picture. It's basically an open collector bus. Your tx pins are not expecting to be tied together and that may damage the chips.
Maybe check out this project to help you on your way.
https://oshpark.com/shared_projects/VeJFD9qA
It may be possible to simulate it with resistors and diodes for a board level application like your demo, but I haven't really considered it before.

Thanks for pointing me to the correct place.

Basically I need a Can Transceiver, to each one of them so I can have a bus.

I'm new to Can Bus, so I didn't expected that, and was thinking that Teensy 3.1 was an out of the box solution to have a Can Bus network, but basically one only get a way to connect to an existing bus, but not to make one.

I've tried to understand how to do it using resistors and diodes as you said, but couldn't understand how, can you point me on something?

Thanks again for the info.
 

Thank you for this.

It works like a charm, used a 1N4148 Diode and a 2,2k resitor for the pullup to 3,3V, and it just works with the bonus of using only one wire instead of two. Also I tested it with a wire of about 5 meters (the pdf refers less than 1 meter), with a speed of 500000.

I want to put another question related to the library and the Flexcan controller on the chip.
The library only accepts 8 possible filters, but could the chip accept more than 8?

In the reference manual (in first page of this thread) there is this:
16.2.5 Configuration of Rx FIFO ID filter table elements
The Rx FIFO ID tables or ID filter table elements are used as message acceptance filters
whose ID fields function as acceptance ID code. It is necessary to configure the Rx FIFO
ID filter table elements in freeze mode.
Kinetis supports up to 40 ID tables — therefore CTRL2[RFFN] = 4 at maximum.

when we look at the code in kinetics.h:
Code:
/* Rx FIFO ID Filter Table Element 0 to 127 */
#define FLEXCAN0_IDFLT_TAB0		(*(vuint32_t*)(FLEXCAN0_BASE+0xE0))
#define FLEXCAN0_IDFLT_TAB(n)		(*(vuint32_t*)(FLEXCAN0_BASE+0xE0+(n*4)))
//#define FLEXCAN0_IDFLT_TAB(n)		(*(vuint32_t*)(FLEXCAN0_BASE+0xE0+(n<<2)))

and in the Flexcan.c:
Code:
void FlexCAN::setFilter(const CAN_filter_t &filter, uint8_t n)
{
  if ( 8 > n ) {
    if (filter.ext) {
      FLEXCAN0_IDFLT_TAB(n) = ((filter.rtr?1:0) << 31) | ((filter.ext?1:0) << 30) | ((filter.id & FLEXCAN_MB_ID_EXT_MASK) << 1);
    } else {
      FLEXCAN0_IDFLT_TAB(n) = ((filter.rtr?1:0) << 31) | ((filter.ext?1:0) << 30) | (FLEXCAN_MB_ID_IDSTD(filter.id) << 1);
    }
  }
}

this is limited to 8 filters, but could we change it to use more? 128 Possible filters?
 
Has anyone successfully used the MCP2562? Is there a glaring problem to this transceiver or should it work with Teachop's library?
 
There is only one rule and it is very clear - as long as you or anybody else is making ANY profit of it (and I know exactly what's the cost of components to build these boards), you are violating the 'license' under which this design has been made available. You didn't even bother to contact me before offering these for sale so you shouldn't be surprised that I'm not happy about your 'offer'.

Copyright doesn't apply to hardware, so no license is being violated.
 
Copyright can pertain to the design of a car, a painting, or a circuit board layout. It doesn't matter whether its software/hardware.
Noone was copying anyways, the debate was in regards to resale of the item, which should not be part of this topic and dealt with personally.
(mods feel free to delete this post)
 
MrCanBus

send an eight byte packet with message ID 0x0500
0x6C,0x00,0x00,0x21,0x00,0x00,0x00,0x00

Oil service and/or Desmo service reset for your model.

With the reflash of the ECU I add extra CAN messages with the data needed to tune the bike.
The ECU on the MTS1200 uses less than half the CAN mailbox slots.

If you want to test sending CAN messages you can send the 0x80 message to test sending messages on the bus.
The ECU sends the 0x80 message and it does not care if other 0x80 messages are on the bus.
Send a message with RPM and you should see the dash show RPM and the headlight should turn on.
The 0x80 message is sent at 5 m/s intervals, You could wait until you get the 0x80 message then send 0x80, this will mean your message is the one the dash will use.

Do you have the correct byte packet to reset Oil/Desmo Service for the Panigale ?
 
G'day,
does anyone know if the current library has any option to send a message with the RTR bit turned on? I can see that the filter has the option to set the RTR bit, but i can't see any way to send a message with it or check if a message had it without the filter.

Cheers
 
Just in case anyone else wanted to be able to detect the presence of the RTR bit being set in a received packet, the add an rtr element to the CAN_message type in the FlexCAN.h as shown:

Code:
typedef struct CAN_message_t {
  uint32_t id; // can identifier
  uint8_t ext; // identifier is extended
  uint8_t rtr; // RTR bit
  uint8_t len; // length of data
  uint16_t timeout; // milliseconds, zero will disable waiting
  uint8_t buf[8];
} CAN_message_t;

then in the FlexCAN.cpp file, add the RTR line to the read(message) code as shown:

Code:
// get identifier and dlc
  msg.len = FLEXCAN_get_length(FLEXCAN0_MBn_CS(rxb));
  msg.ext = (FLEXCAN0_MBn_CS(rxb) & FLEXCAN_MB_CS_IDE)? 1:0;
  msg.rtr  = (FLEXCAN0_MBn_CS(rxb) & FLEXCAN_MB_CS_RTR)? 1:0;
  msg.id  = (FLEXCAN0_MBn_ID(rxb) & FLEXCAN_MB_ID_EXT_MASK);

To write the RTR bit, the CAN write function needs to have another mask set on it in the presence of an RTR bit. This is a modification of the last part of the write(message) code in the FlexCAN.cpp:

Code:
if(msg.ext) {
    if(msg.rtr) {
    	FLEXCAN0_MBn_CS(buffer) = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_ONCE)
                              | FLEXCAN_MB_CS_LENGTH(msg.len) | FLEXCAN_MB_CS_SRR | FLEXCAN_MB_CS_IDE | FLEXCAN_MB_CS_RTR;
    } else {
    	 FLEXCAN0_MBn_CS(buffer) = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_ONCE)
                              | FLEXCAN_MB_CS_LENGTH(msg.len) | FLEXCAN_MB_CS_SRR | FLEXCAN_MB_CS_IDE; 
    }
  } else {
    if(msg.rtr){
    	FLEXCAN0_MBn_CS(buffer) = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_ONCE)
                              | FLEXCAN_MB_CS_LENGTH(msg.len)| FLEXCAN_MB_CS_RTR;
    } else {
    	 FLEXCAN0_MBn_CS(buffer) = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_ONCE)
                              | FLEXCAN_MB_CS_LENGTH(msg.len);
    }
  }


Again, this is probably bad coding (im more a hardware guy), but it works. Im sure there are much more elegant ways to do this.

Cheers
 
Last edited:
Teensy MCP2551

Hi. I'm new on the CAN protocol , I'm developing a project in wich I need to use a Can bus, but I'm having some issues with it. I'm using the Teensy 3.1 and the MCP2551 transcriver. I made some Teensy programs to write and read, i have two Teensys and two MCPs but I dont know why does not work, I think that my conecctions are ok but i think that i don't understand quite well the "Masks Filters and ID's stuff" can someone help me? I will really apreciate it.

This is the code of the frist Teensy
Code:
#include <FlexCAN.h>
#include <kinetis_flexcan.h>

const int baudRate = 50000;
const int ledPin = 13;
const int delayTime = 1000;
int count = 0;
FlexCAN myCAN(baudRate);
CAN_message_t message;
CAN_message_t rxmsg;

void setup(){
  pinMode(ledPin,OUTPUT);
  Serial.begin(9600);
  digitalWrite(ledPin,HIGH);
  myCAN.begin();
  Serial.println("CAN PROTOCOL - INIT ... WAIT...");
  digitalWrite(ledPin,LOW);
  delay(5000);
  digitalWrite(ledPin,HIGH);
  Serial.println("Master ON - READY");
}

void loop(){
  Serial.print("MY CAN data: ");
  //Serial.println(myCAN.available());
  if(myCAN.available()){
    myCAN.read(rxmsg);
    Serial.println(rxmsg.buf[0]);
    if(rxmsg.buf[0] == 49){
      Serial.println("Message Sent");
      message.buf[0] = count;
      message.buf[1] = count + 1;
      message.len = 2 ;
      message.id = 0x2;
      myCAN.write(message);
      count++;
    }
  }
   //Serial.print("Data buf[0]: ");
   //Serial.println(rxmsg.buf[0]);
   
   delay(delayTime);
}

And this is the second Code
Code:
#include <FlexCAN.h>  
#include <kinetis_flexcan.h>

const int baudRate = 50000;
const int ledPin = 13;
const int delayTime = 50;

FlexCAN myCAN(baudRate);
CAN_message_t message;
CAN_message_t rxmsg;

void setup(){
  pinMode(ledPin,OUTPUT);
  Serial.begin(9600);
  myCAN.begin();
  Serial.println("CAN PROTOCOL - INIT ... WAIT...");
  digitalWrite(ledPin,LOW);
  delay(5000);
  digitalWrite(ledPin,HIGH);
  Serial.println("SLAVE ON - READY");
}

void loop(){
  for(int i = 1 ; i < 50 ; i++){
    message.buf[0] = i;
    message.id = 0x1;
    myCAN.write(message);
    Serial.print("Message: ");
    Serial.println(message.buf[0]);
    digitalWrite(ledPin,HIGH);
    delay(delayTime);
    digitalWrite(ledPin,LOW);
    delay(delayTime);
  }
  if (myCAN.available()){
    Serial.println("Message Recived");
    myCAN.read(rxmsg);
    Serial.println(rxmsg.buf[0]);
    Serial.println(rxmsg.buf[1]);
  }
}

I'm having some issues with the IDs, Idont know if i have to define a ID for the frist teensy or how do i know what id to use?
 
Check the comments in the FlexCAN.cpp to see whether you have the library version that does support 50000 baudrate. The latest version on github does, the official release 1.0 doesn't.

You are right, what i mean was 500000 bauds. I already modify it but still dont work :( any ideas?

Here is my wiring Fritzing.jpg
 
Last edited:
Back
Top