ESP32 CAN bus not working

Hello,
I am trying to set up the CAN bus on the ESP32 with the Arduino CAN library. It initializes ok but then it hangs on the writing of a message. Also receiving does not work. I can see with a LogicPro that the messages from a PCAN adapter are sent over the physical bus (CANH and CANL have proper levels and message is visible). But on the CANRX pin only the first few bits are present. Then out of some reason the CANRX stays high until the next message starts. So the messages are not propery passed on the the ESP32. And yes, the bus is terminated properly with 120 Ohms on each end.
If I only have the ESP32 side CAN tranceiver on the wire and send a message from the ESP32 and monitor the CANTX then the pattern does in no way resemble a CAN message at 250K baud. It just gives out pulses of 200µs and 8µs once and then hags in the CAN.endpacket().
So the CANL and CANH signal is ok, but anything that happens on CANRX or CANTX is garbage.

Here is my code:

#include <CAN.h>
void setup() {
Serial.begin(115200);
if (!CAN.begin(250E3)) 
  {
    LOGN("CAN BUS FAILED");
  }else{
    LOGN("CAN bus initialized");
  }
}

void loop() {
  CAN.beginPacket(0x10);
  CAN.write(0xAA);
  CAN.write(0xAA);
  CAN.write(0xAA);
  CAN.write(0xAA);
  CAN.write(0xAA);
  CAN.endPacket();
delay(500);
}

Any tips on whats going on here? I checked all my wiring with severel other tutorials I found. Using a SN65HVD231 and a TJA1042 both the same error. Pin 1 to ESP IO 5 and Pin 4 to ESP IO 4 of my ESP32 WROOM 32E. I used the canbus a dozen times with a STM32 without any trouble. I can not understand why this is not working.
Thanks for any tips. I will try to add some screenshots.

Please follow the advice given in the link below when posting code, in particular the section entitled 'Posting code and common code problems'

Use code tags (the </> icon above the compose window) to make it easier to read and copy for examination

I did the ESP32 CAN thing awhile back.

#include <ESP32CAN.h>

CAN_device_t CAN_cfg;
// CAN_frame_t rx_frame;
// http://www.iotsharing.com/2017/09/how-to-use-arduino-esp32-can-interface.html
// https://github.com/nhatuan84/arduino-esp32-can-demo

void setup()
{
CAN_cfg.speed = CAN_SPEED_1000KBPS;
  CAN_cfg.tx_pin_id = GPIO_NUM_12; // green wire
  CAN_cfg.rx_pin_id =  GPIO_NUM_13; // white wire
  CAN_cfg.rx_queue = xQueueCreate(3, sizeof(CAN_frame_t));
  //start CAN Module
  ESP32Can.CANInit();
}

void fSendCAN_Buss( void *pvParameters )
{
  stuSERVO_Message pxServo_Message;
  for ( ;; )
  {
    xEventGroupWaitBits (eg, evtSendCAN_Buss, pdTRUE, pdTRUE, portMAX_DELAY);
    if ( xSemaphoreTake( sema__Send_CAN_Bus, xTicksToWait0 ) == pdTRUE ) // grab semaphore no wait
    {
      CAN_frame_t rx_frame;
      // Serial.println ( " fSendCAN_Buss 2 "  );
      if ( (CAN_cfg.rx_queue != NULL) && (uxQueueMessagesWaiting(CAN_cfg.rx_queue)) ) // if queue not null and something is waiting in queue
      {
        // Serial.println ( uxQueueMessagesWaiting(CAN_cfg.rx_queue) );
        if (xQueueReceive( CAN_cfg.rx_queue, &rx_frame , xTicksToWait0) == pdTRUE )
        {
          if ( rx_frame.MsgID == 2 )
          {
            // Serial.println ( rx_frame.data.u8[0] );
            if ( rx_frame.data.u8[0] == '6' )
            {
              EOT = false;
              // Serial.print ( " frame ID " );
              // Serial.print ( rx_frame.MsgID );
              // Serial.println ( "ACK" );
              //              rx_frame.FIR.B.FF = CAN_frame_std;
              //              rx_frame.MsgID = xServo_EOT.MsgID;
              //              rx_frame.FIR.B.DLC = xServo_EOT.DLC;
              //              rx_frame.data.u8[0] = xServo_EOT.Servo_EOT;
              //              rx_frame.data.u8[1] = xServo_EOT.p4; // send all '0'
              //              rx_frame.data.u8[2] = xServo_EOT.p4;
              //              rx_frame.data.u8[3] = xServo_EOT.p4;
              //              rx_frame.data.u8[4] = xServo_EOT.p4;
              //              rx_frame.data.u8[5] = xServo_EOT.p4;
              //              rx_frame.data.u8[6] = xServo_EOT.p4;
              //              rx_frame.data.u8[7] = xServo_EOT.p4;
              //              ESP32Can.CANWriteFrame(&rx_frame);
              // Serial.println ( " sent Servo controller ack " );
              //              vTaskDelay( pdMS_TO_TICKS( 6 ) );
            }
            //            if (rx_frame.data.u8[0] = '3')
            //              {
            //                EOT = false;
            //              }
            if ( rx_frame.data.u8[0] == '4' )
            {
              //                          rx_frame.FIR.B.FF = CAN_frame_std;
              //                          rx_frame.MsgID = xServo_EOT.MsgID;
              //                          rx_frame.FIR.B.DLC = xServo_EOT.DLC;
              //                          rx_frame.data.u8[0] = '4';
              //                          rx_frame.data.u8[1] = xServo_EOT.p4;
              //                          rx_frame.data.u8[2] = xServo_EOT.p4;
              //                          rx_frame.data.u8[3] = xServo_EOT.p4;
              //                          rx_frame.data.u8[4] = xServo_EOT.p4;
              //                          rx_frame.data.u8[5] = xServo_EOT.p4;
              //                          rx_frame.data.u8[6] = xServo_EOT.p4;
              //                          rx_frame.data.u8[7] = xServo_EOT.p4;
              //                          ESP32Can.CANWriteFrame(&rx_frame);
              // Serial.println ( "InitComplete ack " );
              EOT = false;
              xSemaphoreGive ( sema_HexaPodAdjustment ); // begin walking forward task
            }
          } // if ( rx_frame.MsgID == 2 )
        } // if (xQueueReceive( CAN_cfg.rx_queue, &rx_frame , xTicksToWait5) == pdTRUE )
      } // if ( (CAN_cfg.rx_queue != NULL) && (uxQueueMessagesWaiting(CAN_cfg.rx_queue)) )
      //      // ack the initialization
      if ( xQueueReceive ( xQ_SERVO_Message, &pxServo_Message, QueueReceiveDelayTime ) == pdTRUE )
      {
        rx_frame.FIR.B.FF = CAN_frame_std;
        rx_frame.MsgID = pxServo_Message.MsgID;
        rx_frame.FIR.B.DLC = pxServo_Message.DLC;
        rx_frame.data.u8[0] = pxServo_Message.Instruction;
        rx_frame.data.u8[1] = pxServo_Message.p1;
        rx_frame.data.u8[2] = pxServo_Message.p2;
        rx_frame.data.u8[3] = pxServo_Message.p3;
        rx_frame.data.u8[4] = pxServo_Message.p4; // end of torque to position
        rx_frame.data.u8[5] = pxServo_Message.p5;
        rx_frame.data.u8[6] = pxServo_Message.p6;
        rx_frame.data.u8[7] = pxServo_Message.p7;
        //                Serial.print ( " message in sendCanBus " );
        //                Serial.print ( ", " );
        //                Serial.print ( rx_frame.data.u8[0] );
        //                Serial.print ( ", " );
        //                Serial.print ( rx_frame.data.u8[1] );
        //                Serial.print ( ", " );
        //                Serial.print (rx_frame.data.u8[2] );
        //                Serial.print ( ", " );
        //                Serial.print ( rx_frame.data.u8[3] );
        //                Serial.print ( ", " );
        //                Serial.print ( rx_frame.data.u8[4] );
        //                Serial.println ( " message end." );
        ESP32Can.CANWriteFrame(&rx_frame);
      }
      //
      xSemaphoreGive ( sema__Send_CAN_Bus );
      ////
      // Serial.print( "fSendCAN_Buss " );
      // Serial.print(uxTaskGetStackHighWaterMark( NULL ));
      // Serial.println();
      // Serial.flush();
    }  // if ( xSemaphoreTake( sema__Send_CAN_Bus, xTicksToWait0 ) == pdTRUE ) // grab semaphore no wait
  } // the for loop
  vTaskDelete( NULL );
} // void fSendCAN_Buss( void *pvParameters )

The Arduino CAN thingy does not work with an ESP32. Try the ESP32 version of a can library thingy.

Thanks for the answer. I already tried that library. Same effect, did not work. Although I am using pins 4 and 5. I will try the pins 12 and 13.

So I tryed pins 12 and 13 without luck. Then I used 4 and 5 again with the ESP32CAN. It works now. It seems it was not working because the baudrate is always half as what it is set to.
I looked at the CAN library. It says it does have support for the EPS's SJA1000 CAN controller. But the library produces no can messages. I need the callback functionality of the CAN library, which the ESP32CAN does not have. Why does the CAN library not work? anyone got an idea?
Thanks for the tip.

1 Like

So end of the story is: my 3.3v CAN transeivers do not work at all (tried two different ones). And I had a bloody broken wire in the CAN bus. I hooked up a ADM3055 and that worked imediately flawlessly.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.