RAK13006 CAN Module - Interrupt suddenly stops working

Hello Community,

i have a problem with the RAK13006 CAN Module. My target is, wakeup the ESP32 using the interrupt pin and send out latest temperature and humidity data. After that, the ESP32 shall go back to the sleep.

My setup is:

  • RAK19007 WisBlock Base Board 2nd Gen
  • RAK11200 WisBlock WiFi Module → mounted on CPU Slot
  • RAK1901 WisBlock Temperature and Humidity Sensor → mounted on Slot C
  • RAK13006 WisBlock CAN Module → mounted on IO Slot

The Problem is:
The Interrupt stops working without any reason and without any errors. I dont know why.
For some time ago, it was working fine but may be possible that i make mistake with interrupt handling during the firmware development. But i cannot determin where the problem is.

Code:
The setup function:

volatile uint8_t CANInterruptFlag = 0;
void setup() {
  Serial.begin(115200);
  
  /* Turn on 3V3_S line. Attention dont touch this IO!!! 
  It is important that the 3V3_S Channel is always on. This powering the CAN-Bus Module. */ 
  pinMode(WB_IO2, OUTPUT);
  digitalWrite(WB_IO2, HIGH);
  delay(300);

  /* Initialize temperature/humidity sensor and get data.*/
  isInitTH = initTH();
  getTH();

  /* Initialize CAN controller */
  initCAN();

  Serial.println("[INFO] [setup()]: CMD boot completed.");

  if(resetCode == ESP_SLEEP_WAKEUP_EXT0 || resetCode == ESP_SLEEP_WAKEUP_EXT1 ){
    CAN_sendRtrFrame(0x01);
  }

  sleep();
}

This is the initialization code for the CAN Module. I Extracted the most of the code frome the example code here: RAK13006_CAN_Slave.ino

void initCAN(){
  Serial.println("[INFO] [initCAN()]: Initialize CAN-Bus");
  Rak_Can.init();

  Serial.print ("[INFO] [initCAN()]: Sizeof (RAK_CAN_Settings): ");
  Serial.print (sizeof (RAK_CAN_Settings)) ;
  Serial.println (" bytes") ;

  Serial.println ("[INFO] [initCAN()]: Configure ACAN2518");
  RAK_CAN_Settings settings (RAK_CAN_Settings::OSC_40MHz, 125 * 1000); // CAN bit rate 125 kb/s
  settings.mRequestedMode = RAK_CAN_Settings::Normal20B;

  Serial.println ("[INFO] [initCAN()]: Init CAN-Module ACAN2518");
  const uint32_t errorCode = Rak_Can.begin (settings, [] { Rak_Can.isr () ; });
  if (errorCode == 0) {
    Serial.print ("[INFO] [initCAN()]: Return code 0x") ;
    Serial.println (errorCode, HEX) ;
    Serial.print ("[INFO] [initCAN()]: Bit Rate prescaler: ") ;
    Serial.println (settings.mBitRatePrescaler) ;
    Serial.print ("[INFO] [initCAN()]: Phase segment 1: ") ;
    Serial.println (settings.mPhaseSegment1) ;
    Serial.print ("[INFO] [initCAN()]: Phase segment 2: ") ;
    Serial.println (settings.mPhaseSegment2) ;
    Serial.print ("[INFO] [initCAN()]: SJW:") ;
    Serial.println (settings.mSJW) ;
    Serial.print ("[INFO] [initCAN()]: Actual bit rate: ") ;
    Serial.print (settings.actualBitRate ()) ;
    Serial.println (" bit/s") ;
    Serial.print ("[INFO] [initCAN()]: Exact bit rate ? ") ;
    Serial.println (settings.exactBitRate () ? "yes" : "no") ;
    Serial.print ("[INFO] [initCAN()]: Sample point: ") ;
    Serial.print (settings.samplePointFromBitStart ()) ;
    Serial.println ("%") ;

    pinMode(WB_IO5, INPUT_PULLDOWN);
    attachInterrupt(digitalPinToInterrupt(WB_IO5), CAN_Interrupt, RISING);

    isInitCAN = true;
  } else {
    Serial.print ("[ERROR] [initCAN()]: Configuration error 0x") ;
    Serial.println (errorCode, HEX) ;
    isInitCAN = false;
  }
}

In the loop, i add following code to handle incoming CAN messages.

void loop() {
  Rak_Can.isr_core();

  if (CANInterruptFlag == 1)
  {
    CANInterruptFlag = 0;
    Serial.println("[INFO] [loop()]: CAN Interrupt raised.");
  }
  

  if (Rak_Can.available()){
    CANMessage frame;
    Rak_Can.receive(frame);

    if (frame.id == 0x01) {
      Serial.println("[INFO] [loop()]: Receive data request.");
      CAN_sendDataFrame();
    }

    else if (frame.id == 0xFF){
      Serial.println("[INFO] [loop()]: Receive sleep command.");
      sleep();
    }
  }  
}

I played with some solutions around ISR but nothing works.

// Get interrupt flag
void IRAM_ATTR CAN_InterruptHandler(void) {
  CANInterruptFlag == 0 ? CANInterruptFlag = 1 : 0; 
}

During my investigations i found some things what i cant explaint to myself.

1# I saw in the src/Rak_CAN.cpp that is the interrupt pin defined to WB_IO6 but in the Documentation says WB_IO5. That is al little bit confusing. Which is now the correct pin?

const uint8_t MCP2518_INT = WB_IO6;

2# In the initialization squence. the begin() needs to define a isr() function but in the loops needs also a isr() function. Is this correct?

const uint32_t errorCode = Rak_Can.begin (settings, [] { Rak_Can.isr () ; }) ;
void loop() {
  Rak_Can.isr_core();
  ...

During running of the ESP32 the CAN communication works fine. But i get no interrupt signasl. In the sleep but also in running. I hope every one can help me to find the problem. Im not an expert in c/cpp programming. :slight_smile:

Thanks and regards to the entire community.
Andre

Welcome to RAK forum @AndreP ,

Regarding interrupt pins, IO5 and IO6 are actually both connected in schematic.

Here’s a complete one for your reference.

Regarding the ISR, it is not a standard ISR implementation if you look on the library itself (specially on ESP32). I haven’t look at it deeply but I can try the example code to check things.

Btw, where do you connect the CAN module? Are you sure there is data exchange happening on the BUS?

Hi @carlrowan,
thank you for the answer.
I understand the schematics and i know that IO5 and IO6 are Interrupts.
But the IO5 triggers not the Interrupt but IO6 triggers. But i need a interrupt to wake up the ESP32 from deepsleep.
This doesent work.
If booth boards are up, the CAN data exchange works.

Maybe your documentation is wrong? Im trying to get any signal on IO5, but no reacting on this pin.

Wakup from DeepSleep is not possible with IO5 because its not connected to an RTC IO. Thread can be closed.

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