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

Thread: CAN communication problems

  1. #1
    Junior Member
    Join Date
    Nov 2020
    Posts
    7

    CAN communication problems

    Hello everyone. I have been trying to set up a CAN communication between two teensy 3.6. I have been using a TJA1051T/3 (link) can transiver. I have connected the Vref pin to 3.3V, Tx to Tx and Rx to Rx, CANH to CANH and CANL to CANL. Using two 60ohm resistors with a cap to ground for each termination. Both microcontrollers and the transivers share a common ground.

    First I tried using the example code found of the FlexCAN library. The second teensy never received any message and the CAN1.available condition was never met. I have also tried measuring the voltage on the can bus lines using an oscilloscope and no signal was measured. The Tx pin on the transmitting teensy instead presented some PWM signal. The RX pin on the receiving is stuck at one.

    I have also tried some other codes found online (such as this one and the result was the same. I am quite confused on what I'm doing wrong so any help is appreciated!

    PS: I don't have pictures of wiring/signal readings right now. If needed I can add them on Monday.

  2. #2
    Senior Member
    Join Date
    Jan 2015
    Location
    UK
    Posts
    147
    You need to post the schematic. Can't see a Vref pin on the TJA1051T/3.

  3. #3
    Junior Member
    Join Date
    Nov 2020
    Posts
    7
    Quote Originally Posted by skpang View Post
    You need to post the schematic. Can't see a Vref pin on the TJA1051T/3.
    Thank you for your answer.
    You are right, I meant V_io, which is a reference voltage for the Tx and Rx pins, where Vtx and Vrx = V_io - 0.4.
    I'll add a schematic tomorrow morning.

  4. #4
    Make sure both transceivers have their "S" pin pulled low. Also, just to be certain, you are supplying the transceivers with 5v?

  5. #5
    Junior Member
    Join Date
    Nov 2020
    Posts
    7
    UPDATE:
    I am adding some pictures to make the question more clear:
    Schematic:
    Click image for larger version. 

Name:	schematic.jpg 
Views:	18 
Size:	40.5 KB 
ID:	22581

    Tx Teensy output:
    TEK0000.BMP

    Rx Teensy input:
    TEK0001.BMP

    CanH when no other transceiver is connected:
    TEK0002.BMP

    CanH when 2nd transceiver (listener/no code - same result) is connected:
    TEK0003.BMP

    2nd teensy Rx pin:
    TEK0004.BMP

    Quote Originally Posted by msadie View Post
    Make sure both transceivers have their "S" pin pulled low. Also, just to be certain, you are supplying the transceivers with 5v?
    Yes both S pin is pulled to ground and we are supplying 5V to Vcc

  6. #6
    Senior Member
    Join Date
    Jan 2015
    Location
    UK
    Posts
    147
    Wiring looks ok.

    Post the code for both Teensy.

  7. #7
    Junior Member
    Join Date
    Nov 2020
    Posts
    7
    Okay, thanks.
    Here is the code, it is the same for both Teensy s, but I also tried running it with no code uploaded on the 2nd teensy.

    Code:
      
    // -------------------------------------------------------------
    // CANtest for Teensy 3.1
    // by teachop
    //
    // This test is talking to a single other echo-node on the bus.
    // 6 frames are transmitted and rx frames are counted.
    // Tx and rx are done in a way to force some driver buffering.
    // Serial is used to print the ongoing status.
    //
    
    #include <Metro.h>
    #include <FlexCAN.h>
    
    Metro sysTimer = Metro(1);// milliseconds
    
    int led = 13;
    //FlexCAN Can1(500000);
    static CAN_message_t msg,rxmsg;
    static uint8_t hex[17] = "0123456789abcdef";
    
    int txCount,rxCount;
    unsigned int txTimer,rxTimer;
    
    
    // -------------------------------------------------------------
    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 ] );
      }
      Serial.write('\r');
      Serial.write('\n');
    }
    
    
    // -------------------------------------------------------------
    void setup(void)
    {
      Can1.begin(1000000);
      pinMode(led, OUTPUT);
      pinMode(32,  OUTPUT);
      
    
      delay(1000);
      Serial.println(F("Hello Teensy 3.1 CAN Test."));
    
      sysTimer.reset();
    }
    
    
    // -------------------------------------------------------------
    void loop(void)
    {
      digitalWrite(32, HIGH);
      digitalWrite(led, 1);
      // service software timers based on Metro tick
      if ( sysTimer.check() ) {
        if ( txTimer ) {
          --txTimer;
        }
        if ( rxTimer ) {
          --rxTimer;
        }
      }
    
      // if not time-delayed, read CAN messages and print 1st bit
      if ( !rxTimer ) {
        while ( Can1.read(rxmsg) ) {
          //hexDump( sizeof(rxmsg), (uint8_t *)&rxmsg );
          Serial.write(rxmsg.buf[0]);
          rxCount++;
        }
      }
    
      // insert a time delay between transmissions
      if ( !txTimer ) {
        // if frames were received, print the count
        if ( rxCount ) {
          Serial.write('=');
          Serial.print(rxCount);
          rxCount = 0;
        }
        txTimer = 100;//milliseconds
        msg.len = 8;
        msg.id = 0x222;
        /*for( int idx=0; idx<8; ++idx ) {
          msg.buf[idx] = '1';
        }*/
        msg.buf[0] = '0';
        msg.buf[1] = '0';
        msg.buf[2] = '0';
        msg.buf[3] = '0';
        msg.buf[4] = '0';
        msg.buf[5] = '0';
        msg.buf[6] = '0';
        msg.buf[7] = '0';
       
        // send 6 at a time to force tx buffering
        txCount = 6;
        digitalWrite(led, 1);
        Serial.println("sending...");
        while ( txCount-- ) {
          Can1.write(msg);
          msg.buf[0]++;
        }
        digitalWrite(led, 0);
        // time delay to force some rx data queue use
        rxTimer = 3;//milliseconds
      }
    
    }
    Other codes that I tried:
    Transmitter:
    Code:
    // -------------------------------------------------------------
    // 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"
    #endif
    
    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 ] );
      }
      Serial.write('\r');
      Serial.write('\n');
    }
    
    
    // -------------------------------------------------------------
    void setup(void)
    {
      delay(1000);
      Serial.println(F("Hello Teensy 3.6 dual CAN Test."));
    
      Can0.begin();  
      Can1.begin();
    
      //if using enable pins on a transceiver they need to be set on
      pinMode(13, OUTPUT);
      pinMode(35, OUTPUT);
    
      digitalWrite(13, HIGH);
      digitalWrite(35, HIGH);
    
      msg.ext = 0;
      msg.id = 0x100;
      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)
    {
      
      msg.buf[0]++;
      Can1.write(msg);
      msg.buf[0]++;
      Can1.write(msg);
      msg.buf[0]++;
      Can1.write(msg);
      msg.buf[0]++;
      Can1.write(msg);
      msg.buf[0]++;
      Can1.write(msg);  
      delay(20);
    }
    Receiver:
    Code:
    // -------------------------------------------------------------
    // 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"
    #endif
    
    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 ] );
      }
      Serial.write('\r');
      Serial.write('\n');
    }
    
    
    // -------------------------------------------------------------
    void setup(void)
    {
      delay(1000);
      Serial.println(F("Hello Teensy 3.6 dual CAN Test."));
    
      Can0.begin();  
      Can1.begin();
    
      //if using enable pins on a transceiver they need to be set on
      pinMode(2, OUTPUT);
      pinMode(35, OUTPUT);
    
      digitalWrite(2, HIGH);
      digitalWrite(35, HIGH);
    
    
    }
    
    
    // -------------------------------------------------------------
    void loop(void)
    {
      CAN_message_t inMsg;
      while (Can1.available()) 
      {
        Can1.read(inMsg);
        Serial.print("CAN bus 0: "); hexDump(8, inMsg.buf);
      }
     
    }
    using the last codes no signal was measured on the canH/canL wires

    EDIT: an additional note: if in the first code the can1.write() function is commented for one teensy so that it only reads, the signal is gone for both teensys in the Tx pin
    Last edited by WarPig; 11-23-2020 at 01:14 PM. Reason: more info

  8. #8
    Senior Member
    Join Date
    Jan 2015
    Location
    UK
    Posts
    147
    Your schematic on the Teensy doesn't show which pins you have used. There are two CAN ports on the 3.6.

    Show how you wired up CAN_TX and CAN_RX.

  9. #9
    Junior Member
    Join Date
    Nov 2020
    Posts
    7
    I am using pin 34 and 35 on the teensy 3.6, just a wire connection to Tx and Rx in the transceiver.

    While I was waiting for an answer I fixed one connection on the chip were the soldering tin didn't stick properly. Now the signal on the Tx pin is propagated to the Rx of the same teensy, on the CanH line, the complementary on CanL line, also with the proper DC bias at 2.5V, but still nothing is received at the Rx of the 2nd teensy.

  10. #10
    Senior Member
    Join Date
    Jan 2015
    Location
    UK
    Posts
    147
    In the Transmitter and Receiver you need to specify the baud rate like this:

    Can1.begin(500000);

    In the receiver try this:
    Code:
    void loop() {
     CAN_message_t rxmsg;
    
      while(Can1.read(rxmsg))
      { 
         String CANStr(""); 
         for (int i=0; i < 8; i++) {     
    
             CANStr += String(rxmsg.buf[i],HEX);
             CANStr += (" ") ;
         }
         Serial.print(rxmsg.id,HEX); 
         Serial.print(' '); 
         Serial.print(rxmsg.len,HEX); 
         Serial.print(' ');
         Serial.println(CANStr);  
       
    
         
      }
    }

  11. #11
    Junior Member
    Join Date
    Nov 2020
    Posts
    7
    First of all thank you for the quick answers and dedication, I really appreciate it!
    I'm using your code now, and a signal is measured on the receiving Rx pin. On the other hand, the Can1.available condition is never true, and nothing is printed on the serial.
    I am thinking that the PWM signal of the teensy Tx pin is not correct, as it is the same regardless of the message (see figure above, where there is one initial longer Low-pulse, and then a bunch of shorter low-pulses)

  12. #12
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,514
    Lets rule out the software, put this on both your Teensy 3.6's pins 34 and 35, itll read and write to the bus and both serial monitors will be scrolling data

    Code:
    #include <FlexCAN_T4.h>
    FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> Can0;
    
    void setup(void) {
      Serial.begin(115200); delay(400);
      pinMode(6, OUTPUT); digitalWrite(6, LOW); /* optional tranceiver enable pin */
      Can0.begin();
      Can0.setBaudRate(500000);
      Can0.setMaxMB(16);
      Can0.enableFIFO();
      Can0.enableFIFOInterrupt();
      Can0.onReceive(canSniff);
      Can0.mailboxStatus();
    }
    
    void canSniff(const CAN_message_t &msg) {
      Serial.print("MB "); Serial.print(msg.mb);
      Serial.print("  OVERRUN: "); Serial.print(msg.flags.overrun);
      Serial.print("  LEN: "); Serial.print(msg.len);
      Serial.print(" EXT: "); Serial.print(msg.flags.extended);
      Serial.print(" TS: "); Serial.print(msg.timestamp);
      Serial.print(" ID: "); Serial.print(msg.id, HEX);
      Serial.print(" Buffer: ");
      for ( uint8_t i = 0; i < msg.len; i++ ) {
        Serial.print(msg.buf[i], HEX); Serial.print(" ");
      } Serial.println();
    }
    
    void loop() {
      Can0.events();
    
      static uint32_t timeout = millis();
      if ( millis() - timeout > 200 ) {
        CAN_message_t msg;
        msg.id = random(0x1,0x7FE);
        for ( uint8_t i = 0; i < 8; i++ ) msg.buf[i] = i + 1;
        Can0.write(msg);
        timeout = millis();
      }
    
    }
    if it still doesnt work, check your wiring

  13. #13
    Junior Member
    Join Date
    Nov 2020
    Posts
    7
    Yes, we figured it out and it is now working! Thank you a lot for your time and help!

Posting Permissions

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