I’m using day by day a custom board to debug and test my Arduino code. My board exposes an NRF24L01 connector that I’m using also to connect lot of devices (RFM12B, RFM69, MAX18355, SD, FLASH, …) mounted on a breakboard such as this one for example. Some time during test I’m switching from one board to another, it is quite useful to be able to check that the device is here and is responding.
How to do that ?
Well, as usual, reading data sheet of the device can help a lot. but I’ve already done this and the code is already written. Just read below on how to achieve this.
RFM12B Module
RFM12 datasheet has the ability to detect low voltage, we will be using this function to detect the device. For this example I’m using LowPowerLab rfm12b library written by Felix and tweaked from excellent one written by jcw from jeelabs, but you can use another one the same way.
The Low voltage threshold can be setup from 3.75V to 2.25V. So until you’re powering the RFM12B device from let’s say 2.4V to 3.6V (which is juste the datasheet recomendation) you will be able to detect the device. The trick is done in two phases.
- Set threshold voltage to 3.75V, and check we’re under voltage.
- then set threshold voltage to 2.25V and check we’re above under voltage
That’s it, simple and efficient not ?
NRF24L01 Module
NRF24L01 datasheet has the ability to set configuration parameters and read them back. We will be using this function to detect the device. For this example I’m using RF24 Arduino library from Stanley and tweaked from excellent one written by maniacbug, but you can use another one the same way, just check library functions and methods.
We will setup number of retries and read them back and also we will trie to set the module RF speed. Then read back the number of retries and check that speed command has been done successfully. The trick is done in three phases.
- Set number of retries
- Read back number of retries and compare with the value we set
- Set the speed (baud rate) and check if it has been done correctly
Example code
The example code below is a function that return if the device detected is an RFM12B or NRF24L01 module. Of course two radios modules need to be declared and instancied for this, but if you use only one, juste instantiate the one you use and remove code from the unneeded module in the function.
.... // The various RF Modules supported typedef enum { module_unknown = 0, module_nrf24 , module_rfm12b } module_e; // Instantiate Radio Modules RF24 radio_rf24(RF_CE,RF_CSN); /* NRF24L01 */ RFM12B radio_rfm12b; /* RFM12B */ module_e module; // RF module used /* ====================================================================== Function: detectDevice Purpose : try to detect device connected to SPI bus (NRF24 or RFM12B) Input : - Output : return device type Comments: - ====================================================================== */ uint8_t detectDevice() { module_e module = module_unknown; uint16_t status; // Init NRF24L01 Module radio_rf24.begin(); // Try to set retries to check later radio_rf24.setRetries(0x0A, 0x05); // NRF24L01 easy to detect, because setDataRate write and read again to see if the same // So if it is okay this mean that there is a NRF24L01 device if ( radio_rf24.getRetries()==0xA5 && radio_rf24.setDataRate(RF24_1MBPS) ) { // We are sure, this is a NRF24 module = module_nrf24; } else { // Init RFM12B module // whatever values here, the real init will be done later // We just need to init the device radio_rfm12b.Initialize(0, RF12_433MHZ); // Clock output (1.66MHz), Low Voltage threshold (3.75V) // we will change the Low Voltage threshold to the highest // value we can, as the module is powered by 3.3V the bit // indicating low voltage should now be set because at 3.3V // we are under 3.75V radio_rfm12b.Control(0xC04F); // Wait the voltage comparison to settle ? // I do not know, but it can't hurt delay(10); // Check if module is low battery ? if ( radio_rfm12b.LowBattery() ) { // Here we can have false detection in case of NRF24 plugged // since we just check SPI return on one bit (LowVoltage) // Clock output (1.66MHz), Low Voltage threshold (2.25V) // So set voltage detection to test inverted bit radio_rfm12b.Control(0xC040); delay(10); // Check if module is no more low battery ? // this time sounds we got a RFM12B module if ( !radio_rfm12b.LowBattery() ) module = module_rfm12b; } } return module; } void setup() { // Do serial init stuff // blah blah module = (module_e) detectDevice(); // Check Module if ( module == module_unknown ) Serial.println("No module detected.."); else Serial.print(module==module_nrf24?"NRF24L01":"RFM12B"); }
Have fun detection, I will add detection for RF69 as soon as I will need it and read the datasheet.
Charles