This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF52840 watchdog for Arduino Nano 33 BLE Sense

Writing an app for the Arduino Nano 33 BLE Sense:

https://store.arduino.cc/usa/nano-33-ble-sense

Basically I am reading all sensors on the Sense board (temperature, humidity, pressure, acceleration, gyro, light, noise), sending the data to a Raspberry Pi for processing, and then to Graphite for long term storage, and visualization with Grafana. This is the project page:

https://github.com/FlorinAndrei/WeatherStation

So far so good and the project works pretty well. But there's one snag:

Every few days the Arduino sketch stops working - it just hangs. I will attempt to troubleshoot it and figure out what causes the hang - there are several libraries I'm using for the various sensors, and perhaps there's a bad interaction somewhere. Or some memory leak, I'm not sure.

Anyway, meanwhile, if I had a way to trigger a watchdog to reset the board, that would be an acceptable workaround.

Is there a library I could integrate with the Arduino IDE that would give me a watchdog for this CPU? And is that documented somewhere, with examples?

Thanks!

Parents
  • Hi Florian,

    We do not have any Arduino code for our devices. 

    However, if you're able to write directly to the nRF52840 registers in the Arduino IDE, then you can enable and start the WDT as follows:

    //Configure WDT.
    NRF_WDT->CONFIG         = 0x01;     // Configure WDT to run when CPU is asleep
    NRF_WDT->CRV            = 3932159;  // Timeout set to 120 seconds, timeout[s] = (CRV-1)/32768
    NRF_WDT->RREN           = 0x01;     // Enable the RR[0] reload register
    NRF_WDT->TASKS_START    = 1;        // Start WDT               

    Then configure a timer to call the code below at a fixed interval lower than 120s or call it in the infinite main loop or similar to feed the WDT. 

    // Reload the WDTs RR[0] reload register
    NRF_WDT->RR[0] = WDT_RR_RR_Reload; 


    Best regards
    Bjørn
  • Thank you for the information, it shed some light on things I didn't understand at all before.

    I'm still trying to figure out the registers thing. I've opened a thread discussing the issue I have on the Arduino forums, still waiting for some relevant reply:

    https://forum.arduino.cc/index.php?topic=643883.0

    I understand you guys just make the CPU and you're not involved with the Arduino Nano 33 project. Now, if the Nano 33 takes off and becomes a popular device, I think you guys may receive more and more queries like this one. It might be of some help if you could clarify issues such as this one for folks who use the Nano 33, who indirectly use your chips.

    It's low-level, CPU-related things, such as how to access the registers. There's very little information about that in the Arduino ecosystem. When you said "access the registers from the Arduino IDE", my first thought was "where do I even begin?" There's a gap there that ought to be bridged somehow - but that would have to be someone who is very familiar with either the CPU, or the Arduino itself, or ideally both. That's clearly not me.

    It's your decision, of course, I'm just thinking out loud. If you think this is not your problem, that's understandable.

Reply
  • Thank you for the information, it shed some light on things I didn't understand at all before.

    I'm still trying to figure out the registers thing. I've opened a thread discussing the issue I have on the Arduino forums, still waiting for some relevant reply:

    https://forum.arduino.cc/index.php?topic=643883.0

    I understand you guys just make the CPU and you're not involved with the Arduino Nano 33 project. Now, if the Nano 33 takes off and becomes a popular device, I think you guys may receive more and more queries like this one. It might be of some help if you could clarify issues such as this one for folks who use the Nano 33, who indirectly use your chips.

    It's low-level, CPU-related things, such as how to access the registers. There's very little information about that in the Arduino ecosystem. When you said "access the registers from the Arduino IDE", my first thought was "where do I even begin?" There's a gap there that ought to be bridged somehow - but that would have to be someone who is very familiar with either the CPU, or the Arduino itself, or ideally both. That's clearly not me.

    It's your decision, of course, I'm just thinking out loud. If you think this is not your problem, that's understandable.

Children
  • Hi Florian, 

    I apologize if my answer was a bit stumped. 

    Its hard for us to provide support on  Arduino libraries that we have not written ourselves, but at the lower layers, these libraries are writing to the registers of the nRF52840. I have used Arduino boards in the past, mostly the Atmega328 ones and when using those I could usually just reference the registers directly with the names from the AT

    I figured the same should be the case for the NRF52840 on the Nano 33 board, soI just copy pasted the code in my previous reply into an Arduino sketch for the Arduino Nano 33 board and clicked verify. It seems to compile fine, but sadly I do not have a Nano 33 to test with, so could you try it in your end?

  • Bjorn,

    Wow, my bad, I didn't realize that was actually code I could try. That sounds great, actually.

    I am in the middle of a reliability test - I've sprinkled the code with delay() statements around sensor read commands and I'm testing now with 20 ms delay. I want to leave it run untouched for at least one week without fail before I declare it stable, seeing as the crash happened with the old code after up to 48 hours of continuous run.

    If it still crashes with delay(20) I will double the value and try again for up to one week.

    So it will take a while for my reliability test to complete. After that, I will definitely try your code and report back.

    Thank you!

  • It works! Thank you.

    int ledState = LOW;
    
    void setup() {
      Serial.begin(115200);
      pinMode(LED_BUILTIN, OUTPUT);
    
      //Configure WDT.
      NRF_WDT->CONFIG         = 0x01;     // Configure WDT to run when CPU is asleep
      NRF_WDT->CRV            = 32769;    // CRV = timeout * 32768 + 1
      NRF_WDT->RREN           = 0x01;     // Enable the RR[0] reload register
      NRF_WDT->TASKS_START    = 1;        // Start WDT       
      
      Serial.println("booting up");
    }
    
    void loop() {
      // Reload the WDTs RR[0] reload register
      NRF_WDT->RR[0] = WDT_RR_RR_Reload;
    
      ledState = ledState ? LOW: HIGH;
      digitalWrite(LED_BUILTIN,  ledState);
    
      delay(2000);
    }

    But there's a catch: the watchdog keeps working even when you try to upload another sketch. If the watchdog timeout is too low (1 second in my case), the Nano 33 will reboot when you try to upload the sketch.

    The solution: tap the Reset button two times quickly. The LED will start pulsing slowly. Now you can upload your sketch on the alternative COM port.

    I've a question: I believe it is possible to program a timeout shorter than 1 second into the watchdog, but is it recommendable? I mean, will there be any issues with short watchdog times? (assuming such a time makes sense for your sketch)

  • Florin Andrei said:
    It works! Thank you.

    Great! 

    Florin Andrei said:
    I've a question: I believe it is possible to program a timeout shorter than 1 second into the watchdog, but is it recommendable? I mean, will there be any issues with short watchdog times? (assuming such a time makes sense for your sketch)

     I think that a watchdog timer with a sub 1 second timeout will do more harm than good. If you have full control of what the nRF52840 is doing, then one could do it, but there may occur BLE events and other interrupts that may prevent the RR register from being reloaded in time. Hence, I would not recommend it. 

     Best regards

    Bjørn

Related