Help asked for basic FlexCan use

Status
Not open for further replies.

PaulS

Well-known member
Been trying to read out a CAN-based touch encoder but I'm stuck at just receiving the CAN bus data.
Here is the setup:

IMG_20201006_115917.jpg

Parts here: Teensy 3.2, Waveshare CAN transceiver [powered by 3V3] and a Grayhill Touch Encoder [powered by 5V]. Datasheet of the encoder is here.
The encoder spits out CAN data at 250kbps and uses the extended frame format with 8 data bytes.
I hooked up the logic analyzer to the CAN RX pin of the transceiver board and this is output:

DSView-201006-102734.jpg

The identifier matches the datasheet and as far as I can tell the CAN message seems valid. Also the signal on pin 4 of the Teensy looks OK on the oscilloscope.

Now I'm trying to get the Teensy read this CAN bus data. I'm using the latest copy of the FlexCAN library. Copied that library into Arduino\Libraries and removed the one that came with Teensyduino. Using Arduino 1.8.13, Teensyduino 1.53.
Here is my basic code that compiles without error or warning:
Code:
#include <FlexCAN.h>

static CAN_message_t msg;

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(115200);
  while (!Serial);
  Can0.begin(250000);    // init CAN bus
  Serial.println("CAN Receiver Initialized");
}

void loop() {
  if (Can0.available()) {
    Can0.read(msg);
    digitalToggle(LED_BUILTIN);
    Serial.print("Receiving: ");
    for (int i = 0; i < msg.len; i++) {
    Serial.print(msg.buf[i]); Serial.print(" ");
    }
    Serial.println("");
  }
}

But no CAN data is shown in the serial monitor after the CAN Receiver Initialized line.
I also tried the FlexCAN_T4 library and a few other CAN libraries on GitHub but I just don't seem to be able to read the CAN data. I even tried a little sketch using digitalRead to check whether pin 4 was perhaps dead but it's OK. Also the 5V and 3V3 are OK on the Teensy and transceiver board.

Any idea what I'm doing wrong here? I'm out of ideas what to try next.

Thanks,
Paul
 
Hi Sukkin, thanks for your help.
I connected the TX line as well, but unfortunately I'm still not getting data on the serial monitor.
However, I did see the Teensy transmit a dominant level in the ACK slot, so it apparently received a valid CAN frame. I guess that's good news.
Here is the logic analyzer output showing the ACK:

DSView-201006-143447.jpg

Paul
 
So I changed the code to:
Code:
void loop() {
  if (Can0.read(msg)) {
    digitalToggle(LED_BUILTIN);
    Serial.print("Receiving: ");
    for (int i = 0; i < msg.len; i++) {
      Serial.print(msg.buf[i]); Serial.print(" ");
    }
    Serial.println("");
  }
}
but unfortunately no CAN data output on the serial monitor...no LED activity as well.

Paul
 
Yes, there is - 120 Ω.
I have the feeling that is not hardware related though. The FlexCAN library correctly acknowledges the frame. It's just the content that is not showing in the serial monitor.

Paul
 
Strange your program won't compile in my version 1.8.12
It doesn't have digitalToggle() function.

I had to change it to:
Code:
#include <FlexCAN.h>

static CAN_message_t msg;

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(115200);
  while (!Serial);
  Can0.begin(250000);    // init CAN bus
  Serial.println("CAN Receiver Initialized");
}

void loop() {
  if (Can0.read(msg)) {
   digitalWrite(LED_BUILTIN,HIGH);
    Serial.print("Receiving: ");
    for (int i = 0; i < msg.len; i++) {
      Serial.print(msg.buf[i]); Serial.print(" ");
    }
    Serial.println("");
  }
}

This program works on my hardware.
 
Note: digitalToggleFast - was added in one of the more recent releases of Teensyduino.
 
Thanks for trying. Paul Stoffregen added a digitalToggle function in Teensyduino version 1.53.

I copied your code, compiled and uploaded it, but the serial monitor only outputs CAN Receiver Initialized and the LED does not turn on.
What CAN bus device did you use for testing?

I'm now suspecting that the CAN message from the encoder is not liked by the library one way or another. I don't think the CAN message is corrupted since the protocol decoder of the logic analyzer interprets the CAN fields correctly.

Paul
 
I know what it is now. It is the extended frame filter.

Change to this:

void setup() {
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
while (!Serial);
Can0.begin(250000); // init CAN bus

CAN_filter_t allPassFilter;

allPassFilter.ext=1;
for (uint8_t filterNum = 4; filterNum < 16;filterNum++){
Can0.setFilter(allPassFilter,filterNum);
}
Serial.println("CAN Receiver Initialized");
}
 
It works!

Thank you very much! I wouldn't have figured this out myself by reading the README.md page...
Here is the output [I added a Serial.print(msg.id);]:

Capture.PNG

Thanks again,
Paul
 
Going through the FlexCAN library source code, I found another way to set the extended frame bit for all RX mailboxes.
Here is my CAN-monitor program for reference. The relevant code is in red.
Code:
#include <FlexCAN.h>                 // CAN transceiver: CTX pin 3, CRX pin 4

static CAN_message_t msg;
[COLOR="#FF0000"]static CAN_filter_t allPassFilter;[/COLOR]

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(115200);
  while (!Serial) ;       // wait for serial monitor
  
[COLOR="#FF0000"]  allPassFilter.flags.extended = 1;  // 1 for extended/29 bit IDs
  Can0.begin(250000, allPassFilter); // init CAN bus @ 250kbps[/COLOR]
  Serial.println("CAN initialized and listening");
}

void loop() {
  if (Can0.read(msg)) {
    digitalWrite(LED_BUILTIN, HIGH);
    Serial.printf("0x%08X", msg.id); Serial.print(" ");
    Serial.printf("0x%04X", msg.timestamp); Serial.print(" ");
    Serial.printf("0x%02X", msg.flags); Serial.print(" ");
    Serial.printf("0x%02X", msg.len); Serial.print(" ");
    for (byte i = 0; i < sizeof(msg.buf); i++) {
      Serial.printf("0x%02X", msg.buf[i]); Serial.print(" ");
    }
    Serial.println("");
    digitalWrite(LED_BUILTIN, LOW);
  }
}

And here is the CAN-monitor output on the serial monitor:

CAN-monitor output.png


Regards,
Paul
 
Status
Not open for further replies.
Back
Top