Small battery-powered radio nodes — a soil sensor in the garden, a door sensor, a tank-level sender — are the Pro Mini’s home ground. Pair it with an nRF24L01+ and it can report to a base station for months on a few cells.
The radio uses hardware SPI (D11/D12/D13) with CE on D9 and CSN on D10. The sketch sends the board’s own supply voltage every 10 seconds and switches the radio to its 1 µA power-down mode between sends.
Wiring
| Arduino Pro Mini (5 V) | nRF24L01+ 2.4 GHz transceiver | Wire | Notes |
|---|---|---|---|
| MCP1700 / AMS1117 3.3 V regulator (IN from Pro Mini VCC) · 3.3V | VCC | red | 10 µF across VCC/GND at the radio. On a 3.3 V Pro Mini, wire VCC → VCC directly instead. |
| GND | GND | black | |
| D9 | CE | orange | |
| D10 | CSN | purple | |
| D13 | SCK | yellow | |
| D11 | MOSI | green | |
| D12 | MISO | blue |
1.9–3.6 V — use 3.3 V part, 5 V board. VCC must be 3.3 V: 5 V destroys it. The signal inputs are 5 V tolerant, so an Uno can drive SCK, MOSI, CSN and CE directly; MISO is a 3.3 V output that every board reads fine.
Board quirks
- The 3.3 V / 8 MHz Pro Mini is the natural partner for the nRF24: its VCC rail is already 3.3 V, so the radio connects directly. On the 5 V board shown here, the radio needs its own 3.3 V regulator — never 5 V on its VCC.
- The signal pins are 5 V tolerant, so CE, CSN, SCK and MOSI wire straight to the 5 V Pro Mini.
- SPI is fixed: SCK = 13, MISO = 12, MOSI = 11. These are on the right-hand row of the Pro Mini, next to A0.
- The node measures its own supply voltage against the internal 1.1 V reference — no divider, no wasted current — and sends it in millivolts.
- The base station side is the Mega nRF24 base-station guide (this node uses “NODE2”).
Code
// nRF24L01+ sensor node on an Arduino Pro Mini: sends its own supply voltage (and A0) every
// ~10 s to a base station listening on "NODE2", powering the radio down in between.
// CE → D9, CSN → D10, SCK → D13, MOSI → D11, MISO → D12, VCC → 3.3 V regulator, GND → GND.
#include <SPI.h>
#include <RF24.h>
RF24 radio(9, 10); // CE, CSN
const uint8_t ADDRESS[6] = "NODE2";
long readVccMillivolts() { // the ATmega's 1.1 V bandgap measured against VCC
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
delay(2);
ADCSRA |= _BV(ADSC);
while (bit_is_set(ADCSRA, ADSC)) {}
return 1125300L / ADC;
}
void setup() {
Serial.begin(115200);
if (!radio.begin() || !radio.isChipConnected()) {
Serial.println(F("nRF24 not responding - check the 3.3 V supply and SPI"));
for (;;) {}
}
radio.setPALevel(RF24_PA_LOW);
radio.setDataRate(RF24_250KBPS);
radio.setChannel(108);
radio.setPayloadSize(sizeof(long));
radio.setRetries(5, 15); // 1.5 ms between retries, 15 tries
radio.openWritingPipe(ADDRESS);
radio.stopListening();
Serial.println(F("Node 2 ready"));
}
void loop() {
long mv = readVccMillivolts();
analogRead(A0); // first read after the bandgap switch is junk
long payload = mv; // send the supply voltage in mV; swap in a sensor value here
radio.powerUp();
delay(5); // oscillator start-up
bool ok = radio.write(&payload, sizeof(payload));
radio.powerDown(); // ~1 µA until the next send
Serial.print(F("VCC "));
Serial.print(mv);
Serial.print(F(" mV A0 "));
Serial.print(analogRead(A0));
Serial.println(ok ? F(" sent, ack OK") : F(" no ack"));
delay(10000);
}// nRF24L01+ sensor node on an Arduino Pro Mini: sends its own supply voltage (and A0) every
// ~10 s to a base station listening on "NODE2", powering the radio down in between.
// CE → D9, CSN → D10, SCK → D13, MOSI → D11, MISO → D12, VCC → 3.3 V regulator, GND → GND.
#include <SPI.h>
#include <RF24.h>
RF24 radio(9, 10); // CE, CSN
const uint8_t ADDRESS[6] = "NODE2";
long readVccMillivolts() { // the ATmega's 1.1 V bandgap measured against VCC
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
delay(2);
ADCSRA |= _BV(ADSC);
while (bit_is_set(ADCSRA, ADSC)) {}
return 1125300L / ADC;
}
void setup() {
Serial.begin(115200);
if (!radio.begin() || !radio.isChipConnected()) {
Serial.println(F("nRF24 not responding - check the 3.3 V supply and SPI"));
for (;;) {}
}
radio.setPALevel(RF24_PA_LOW);
radio.setDataRate(RF24_250KBPS);
radio.setChannel(108);
radio.setPayloadSize(sizeof(long));
radio.setRetries(5, 15); // 1.5 ms between retries, 15 tries
radio.openWritingPipe(ADDRESS);
radio.stopListening();
Serial.println(F("Node 2 ready"));
}
void loop() {
long mv = readVccMillivolts();
analogRead(A0); // first read after the bandgap switch is junk
long payload = mv; // send the supply voltage in mV; swap in a sensor value here
radio.powerUp();
delay(5); // oscillator start-up
bool ok = radio.write(&payload, sizeof(payload));
radio.powerDown(); // ~1 µA until the next send
Serial.print(F("VCC "));
Serial.print(mv);
Serial.print(F(" mV A0 "));
Serial.print(analogRead(A0));
Serial.println(ok ? F(" sent, ack OK") : F(" no ack"));
delay(10000);
}Library: RF24 (TMRh20) — compiled with RF24 1.6.2.
Expected serial output
Node 2 ready
VCC 4987 mV A0 412 sent, ack OK
VCC 4985 mV A0 409 sent, ack OKNode 2 ready VCC 4987 mV A0 412 sent, ack OK VCC 4985 mV A0 409 sent, ack OK
Common errors
nRF24 not responding
No 3.3 V on the radio, or SCK/MOSI/MISO on the wrong row. Full fix.
Always “no ack”
Base station on a different channel, data rate or payload size, or a weak 3.3 V supply. Add the 10 µF capacitor.