Hi,
I am fully aware that this is not an Arduino forum and that is not the responsibility of the users here to answer Arduino related questions - I have tried looking on the Arduino forums for answers but they basically send me to this forum as the question is quite specific to the nRF52840.
I am not a very experienced circuit board programmer and as such as I am having a hard time wrapping my head around how this all works. As such I am placing the full words next to abbreviations for other less experienced programmers. I would love if answers could do the same for me.
I am currently building a project using a nano 33 BLE. However, the issue that I am having should be irrelevant which board it is and as such I 'feel' like this forum is the correct place to pose my question, The project that I am building requires the Microcontroller (MCU) to stop consuming battery while it is not being used. The Nano 33 BLE comes with a 9 axis inertial measurement unit (IMU) which means that it includes an accelerometer, a gyroscope, and a magnetometer with 3-axis resolution each. As its name implies the communications chipset on the Nano 33 BLE can be both a BLE and Bluetooth client and host device.
I have managed to code, using the Arduino integrated development environment (IDE), my board to basically do what I want it to do. And I have even managed through the help of this forum to get it to go into SYSTEMOFF or 'deep sleep' mode when it is not emitting anything.
// Enable sleep mode NRF_POWER->SYSTEMOFF = 1;
My problem is that I want to have the board come back to life in a smart way. Either through the press of a button, detection of movement from the accelerometer, I would even be very happy with it just sporadically waking up to check if it has changed position since last and if so run a check for possible centrals to connect to. I am really open to any suggestions or low hanging fruit here.
Press of a button
I have managed to make it reset using the button that the nano 33 BLE has integrated bu the problem here that if that button is pressed twice in succession it resets the board back to default, thus erasing the program. Seeing as this prototype will be used at a hospital for a few months during a feasibility study I can't really risk that happening.
Detecting Movement
This seems like it could be a problem as this would mean the IMU would need to be kept awake or woken up sporadically to check its movement. Using my multimeter I can see that running the IMU is a rather expensive experience when it comes to current draw. But perhaps there is a smart to do this that I am not seeing?
Sporadic checking
This is what I think would be the best way to do this, and was trying to look into using the watchdog timer to do so during a watchdog reset, alas I was informed correctly by bjorn-spockeli that the reset behaviour informs us that the watchdog timer does not run during SYSTEMOFF as it does on the atmega328.
_____________
What the documentation says
I have read the documentation repeatedly, and as a bit of an amateur, I am simply lost trying to follow it, especially when I am trying to do so in an Arduino milieu. I am not entirely sure what is meant by the first 3 options from this section of the documentation:
"When in System OFF mode, the device can be woken up through one of the following signals:
- The DETECT signal, optionally generated by the GPIO peripheral.
- The ANADETECT signal, optionally generated by the LPCOMP module.
- The SENSE signal, optionally generated by the NFC module to wake-on-field.
- Detecting a valid USB voltage on the VBUS pin (VBUS,DETECT).
- A reset."
My guess' are as follows:
- I assume this is mapping a peripheral to a General Purpose Input/Output (GPIO) pin much like an external button? or another board?
- Using the Low power comparator to check the current voltage of a pin against a reference value?
- Some sort of signal that originated from a Near-field communication (NFC) detection?
- Plugging the device into a USB plug, much like plugging the Nano 33 BLE into my computer when uploading programs to it.
- Pressing the 'reset button' as I described earlier.
As you may see I am a bit at a loss here and would greatly appreciate a point in the right direction. Any sample code would be greatly appreciated, ideally in the Arduino IDE format but anything will do. Here is an example piece of code that I would like to wake up. If someone could provide some pseudocode it would go a long way to helping me out, and I presume many others working in the Arduino milieu.
#include <ArduinoBLE.h> // The BLE library // BLE Rotation Service BLEService rotationService("483a4000-fcde-4cc1-8ca1-59a33edf9061"); // BLE Accelerometer Characteristic :: BLERead allows central devices to read data. // BLEWrite allows centrals to write to this peripheral. // BLENotify allows remote clients to get notifications if this characteristic changes. BLECharacteristic rotationChar("483a4001-fcde-4cc1-8ca1-59a33edf9061", BLERead | BLEWrite | BLENotify, 17, true); void blePeripheralConnectHandler(BLEDevice central) { _connected = true; } void blePeripheralDisconnectHandler(BLEDevice central) { _connected = false; } void Sleep() { digitalWrite(LED_PWR, LOW); // turn off power LED digitalWrite(PIN_ENABLE_I2C_PULLUP, LOW); // turn off I²C pullup digitalWrite(PIN_ENABLE_SENSORS_3V3, LOW); // turn sensor OFF delay(500); // Enable sleep mode NRF_POWER->SYSTEMOFF = 1; } void setup() { // begin initialization if (!BLE.begin()) { while (1); } // Setup characteristic and the service to emit as well as their respective names BLE.setLocalName("SYNCS123456"); BLE.setDeviceName("SYNCS123456"); BLE.setAdvertisedService(rotationService); rotationService.addCharacteristic(rotationChar); BLE.addService(rotationService); rotationChar.writeValue(rotation); // assign event handlers for connected, disconnected to peripheral These are called when connecting or disconnecting from the central BLE.setEventHandler(BLEConnected, blePeripheralConnectHandler); BLE.setEventHandler(BLEDisconnected, blePeripheralDisconnectHandler); // start advertising BLE.advertise(); } void loop() { if(_connected) { // Do something (for example turn on IMU and start transmitting data) } else() { // Run a timer that after x time calls the Sleep() function. } }
Thank you very much for any help that can be provided on this and know that I have really tried over the last few weeks to get this answered on Arduino but they pish me here, I feel like I'm falling right between the two and thus kinda lost =(
regards!