Controlling Motor Controller via CAN Bus

Not open for further replies.



I am trying to communicate to a motor controller via CAN bus on a Teensy 3.6 with a Waveshare CAN transceiver. I am using an oscilloscope to analyze the communication with CAN High and Low. The Teensy is using the FlexCan library to test the communication. From the Teensy perspective, the oscilloscope shows random bursts of data which tops at 25 mV. From the motor controller perspective, the oscilloscope shows continuous bursts of data topping at 230 mV.

When both the motor controller and transceiver are connected, the code that is being used displays nothing because the CAN0.available() is false.

I am using a Waveshare transiever:

Here is the code I am using:

// -------------------------------------------------------------
// CANtest for Teensy 3.6 dual CAN bus
// by Collin Kidder, Based on CANTest by Pawelsky (based on CANtest by teachop)
// Both buses are left at default 250k speed and the second bus sends frames to the first
// to do this properly you should have the two buses linked together. This sketch
// also assumes that you need to set enable pins active. Comment out if not using
// enable pins or set them to your correct pins.
// This sketch tests both buses as well as interrupt driven Rx and Tx. There are only
// two Tx buffers by default so sending 5 at a time forces the interrupt driven system
// to buffer the final three and send them via interrupts. All the while all Rx frames
// are internally saved to a software buffer by the interrupt handler.

#include <FlexCAN.h>

#ifndef __MK66FX1M0__
  #error "Teensy 3.6 with dual CAN bus is required to run this example"

static CAN_message_t msg;
static uint8_t hex[17] = "0123456789abcdef";

// -------------------------------------------------------------
static void hexDump(uint8_t dumpLen, uint8_t *bytePtr)
  uint8_t working;
  while( dumpLen-- ) {
    working = *bytePtr++;
    Serial.write( hex[ working>>4 ] );
    Serial.write( hex[ working&15 ] );

// -------------------------------------------------------------
void setup(void)
  Serial.println(F("Hello Teensy 3.6 dual CAN Test."));


  //if using enable pins on a transceiver they need to be set on

  msg.ext = 0; = 0x0A0;
  msg.len = 8;
  msg.buf[0] = 10;
  msg.buf[1] = 20;
  msg.buf[2] = 0;
  msg.buf[3] = 100;
  msg.buf[4] = 128;
  msg.buf[5] = 64;
  msg.buf[6] = 32;
  msg.buf[7] = 16;

// -------------------------------------------------------------
void loop(void)
  CAN_message_t inMsg;
          Serial.println("Here reading");
          Serial.print("[ECHO]CAN bus 0: "); hexDump(8, inMsg.buf);

The motor controller being used is an RMS p100x. Here is a link to its CAN protocol

Should the difference I am seeing on the oscilloscope be that dramatic?
Any idea why CAN0.available() is false?

Any help with this would be much appreciated.
is the motor controller broadcasting at any time or just set to receive only? available wouldnt see anything if nothing was being sent around on the bus.
have you tried IFCT library with a simple IFCT example loaded? If that works then you confirmed its a configuration/library issue with your code
I tried using IFCTsimpleFIFOPolling to see if any communication would show on the serial monitor. The monitor showed nothing. Prior to testing the code, I changed the baud rate to 250000 to match the motor controller which is set at the same speed.
Can the IFCT library read any kind of CAN bus data? Or is it only set to read a certain kind of CAN bus data?
all CAN data is the same, I would check if the transceiver pin is enabled and verify the connections if you still see no data
some transceivers have an enable pin, if theyre not asserted, you simple wont see anything at all, transmit or receive.
you should have a common ground between the teensy and transceiver and connect TX to TX and RX to RX between them. The enable pin can be gpio toggled or hardwired to be always functional

your waveshare board doesnt look like it has one, just verify those 4 header pins are properly connected to teensy, and not using the AGND pin, make sure its GND pin of teensy
Have you closed the terminator jumper on the Waveshare board ? Try that.

You might also need to do something similar on the motor controller side if it hasn't got a terminator.

A CAN network requires two 120R terminator resistors, one at each end.
I verified all the connections are good. I also connected the oscilloscope to the motor controller.
It showed clear square waves so it is definitely working. A 120R terminator resistor is connected to the transceiver and the motor controller.
Could there be a problem with the transceiver? If so is there a way to check?
is there any activity on the transceiver and/or teensy pin? if so, try swapping the io pins RX/TX perhaps theyre reversed?
and your testing the normal pins at end of t3.6 board or pins 3 and 4? the main ones are bottom corner, 3&4 are alternate pins you can swap to using the Can0.setRX(ALT) functions on IFCT, but shiuld make sure you try the end pins first
I switched the teensy with another one. The TX pin is now pulled high when the teensy is running. The RX pin has zero volts on the teensy. I am using the pins on the bottom corner. I am also using the IFCTsimpleFIFOPolling example. When connecting the RX pin of the CAN transceiver, data waves from the motor controller are visible. So I know that the data from the motor controller is being sent to the teensy, but I don't know why the teensy can't read the CAN bus data. Any ideas?
Hi Saurabh
I know I am jumping in here at the last minute but a couple things struck me just looking at the manual real quick
RMS CAN communication is set up with a default rate of 250 K baud. The available baud rates include 125K, 250K, 500K, and 1M. The terminator resistor is available and active by default. RMS CAN is configurable through parameters that are available through the RMS GUI as well as CAN. GUI parameters have the same name as mentioned in this document with the exception that they end withthe keyword “EEPROM”. Following parameters are used to configure RMS CAN:......

I am also assuming you didn't make any eeprom changes to the controller. With that said. Are you positive you got your connections right. I have a the same transceiver and have not had any issues with it:
For the transceiver to the teensy (just like tonton81 said):
rx => rx (pin 3) (remember the 1st pin on the T3.6 is ground on that side of the teensy so the rx is actually 4 pins from the edge, add 1 to the tx pin # to get actual pin count from the edge)
tx => tx (pin 4)
gnd => gnd
3.3v => 3.3v on the teensy)

Is there a transceiver on the motor controller side?

You didn't post a link to the controller (hw) that I saw anywhere in the post or a picture of your connection setup. Also did you look at the wave forms directly on the transceiver to make sure its seeing signals from the motor controller.

EDIT: Took a little while but is this the manual: and the software for motor controller: To me this is the normal run of the mill motor controllers :)

if it is then the connection (J1 - 35p AMPSEAL Plug 776164 - 1 with crimp contact 770854-1:
pin 22 -GND - go to common gnd with the Teensy, Ground
CAN Channel A Hi: pin 33 - CANA_H => canh on the transceiver
CAN Channel A Low: pin 11 - CANA_L => canl on the trasceiver
Last edited:
Sorry for the lack of pictures of the teensy. 'I have linked some pictures of the teensy. The breadboard is resting on top of the motor controller. The motor controller is correctly configured, and both the teensy and the motor controller are set at 250k baud.
Last edited:
why are you using ONLY CAN1 TX, and trying to access Can0 in code, definately wrong

try using pins 3 & 4, CAN requires both RX and TX to be used in order to be working, hooked up to a transceiver

tonton81 is absolutely correct. You have a wiring problem From the Teensy to the waveshare transceiver. You hook as he mentioned and as I showed in post 15
Not open for further replies.