Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 14 of 14

Thread: Help asked for basic FlexCan use

  1. #1
    Senior Member PaulS's Avatar
    Join Date
    Apr 2015
    Location
    Netherlands
    Posts
    332

    Help asked for basic FlexCan use

    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:

    Click image for larger version. 

Name:	IMG_20201006_115917.jpg 
Views:	16 
Size:	380.0 KB 
ID:	21990

    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:

    Click image for larger version. 

Name:	DSView-201006-102734.jpg 
Views:	16 
Size:	54.2 KB 
ID:	21991

    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

  2. #2
    Senior Member
    Join Date
    Jan 2015
    Location
    UK
    Posts
    146
    You need to connect the CAN Tx pin is well even if you only want to receive.

  3. #3
    Senior Member PaulS's Avatar
    Join Date
    Apr 2015
    Location
    Netherlands
    Posts
    332
    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:

    Click image for larger version. 

Name:	DSView-201006-143447.jpg 
Views:	13 
Size:	51.5 KB 
ID:	21992

    Paul

  4. #4
    Senior Member
    Join Date
    Jan 2015
    Location
    UK
    Posts
    146
    Try and change:

    if (Can0.available()) {
    Can0.read(msg);

    To

    if(Can0.read(msg))
    {

  5. #5
    Senior Member PaulS's Avatar
    Join Date
    Apr 2015
    Location
    Netherlands
    Posts
    332
    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

  6. #6
    Senior Member
    Join Date
    Jan 2015
    Location
    UK
    Posts
    146
    Is there a terminator on the transceiver board ?

  7. #7
    Senior Member PaulS's Avatar
    Join Date
    Apr 2015
    Location
    Netherlands
    Posts
    332
    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

  8. #8
    Senior Member
    Join Date
    Jan 2015
    Location
    UK
    Posts
    146
    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.

  9. #9
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,904
    Note: digitalToggleFast - was added in one of the more recent releases of Teensyduino.

  10. #10
    Senior Member PaulS's Avatar
    Join Date
    Apr 2015
    Location
    Netherlands
    Posts
    332
    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

  11. #11
    Senior Member
    Join Date
    Jan 2015
    Location
    UK
    Posts
    146
    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");
    }

  12. #12
    Senior Member PaulS's Avatar
    Join Date
    Apr 2015
    Location
    Netherlands
    Posts
    332

    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);]:

    Click image for larger version. 

Name:	Capture.PNG 
Views:	5 
Size:	11.8 KB 
ID:	21994

    Thanks again,
    Paul

  13. #13
    Senior Member
    Join Date
    Jan 2015
    Location
    UK
    Posts
    146
    Yes, the default for extended frame is disabled. So you have to manually enable it.

    I'm using this Teensy 3.2 board:
    http://skpang.co.uk/catalog/teensy-c...32-p-1507.html

    For testing I'm using a PCAN-USB Pro FD, CAN-bus analyser from Peak System.

  14. #14
    Senior Member PaulS's Avatar
    Join Date
    Apr 2015
    Location
    Netherlands
    Posts
    332
    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;
    static CAN_filter_t allPassFilter;
    
    void setup() {
      pinMode(LED_BUILTIN, OUTPUT);
      Serial.begin(115200);
      while (!Serial) ;       // wait for serial monitor
      
      allPassFilter.flags.extended = 1;  // 1 for extended/29 bit IDs
      Can0.begin(250000, allPassFilter); // init CAN bus @ 250kbps
      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:

    Click image for larger version. 

Name:	CAN-monitor output.png 
Views:	9 
Size:	39.6 KB 
ID:	22115


    Regards,
    Paul

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •