Stromverbrauch und DeepSleep des nRF52840 ProMicro/SuperMini Board (nice!nano kompatibel) vs. ESP32 und andere

Die Vorstellung des nRF52840 SuperMini/ProMicro-Boards gab es ja im letzten Artikel. Nachdem wir uns dort mit dem Pinout vertraut gemacht haben, habe ich meinen Code vorgestellt, mit dem man die GPIOs für das Board wie im Arduino Framework gewohnt programmieren kann: mit pinMode() und digitalWrite() und digitalRead(). Dazu hatte ich meine eigene nicenano.h geschrieben.
Den Testaufbau aus diesem Artikel brauchen wir später noch einmal.
Doch zuerst geht es heute um den Stromverbrauch des nRF52840 SuperMini im Vergleich zu den anderen Mikrocontroller-Boards, die ich so in meinem Zoo habe. Der nRF52840 soll sich ja angeblich durch geringen Stromverbrauch auszeichnen. Mal schauen, was da dran ist.
Versuchsaufbau Stromvergleich
USB-Messgeräte sind ja sehr praktisch, um sich den Strom, der über den USB-Port geht, anzeigen zu lassen. Aber für das, was wir jetzt vorhaben, sind es maximal Schätzeisen. Wir rechnen mit kleinen Strömen, die wir genau messen wollen und dafür sollte man dann doch ein vernünftiges Amperemeter / Multimeter verwenden, gerade bei kleineren Leistungen.Darum habe ich ein USB-C-Kabel in der Mitte zerschnitten und mein vertrauenswürdiges Multimeter dazwischen geschaltet. Das kann sogar Mikro-Ampere messen und sollte deswegen mehr als ausreichend sein.
Damit die einzelnen Mikrocontroller gleiche Ausgangsbedingungen haben, werde ich auf allen einen Blink-Sketch, wie er auch schon häufig im Auslieferungszustand nach dem Kauf vorzufinden ist, laufen lassen. Dass ich da nicht jeden einzelnen Mikrocontroller neu programmieren muss, kommt mir natürlich sehr entgegen.
Die Boards werden als Gesamtheit gemessen, also mit allem, was darauf verlötet ist. Es kann durchaus sein, dass ähnliche Boards leicht abweichende Werte haben, da sie zum Beispiel andere Spannungswandler verbauen, aber im Groben sollte das passen. Wer genau wissen will, welche Boards zum Einsatz kamen, der möge sich bitte das folgende Video anschauen, dort werden sie alle der Reihe nach gezeigt und der Stromverbrauch gemessen.
Die gemessenen Werte habe ich in folgende Tabelle eingetragen und einen Mittelwert in der rechten Spalte gebildet. Die Mikrocontroller sind nach Hersteller und Familien sortiert:
| Mikrocontroller | mA Bereich | mA Mittel |
|---|---|---|
| nRF52840 SuperMini / ProMicro | 2.5 - 3.5 | 3 |
| Raspi Pico RP2040 USB-C ohne LED | 10 - 12 | 11 |
| Arduino Nano USB-C 2x LED | 20 | 20 |
| Arduino ATtiny85 Digispark | 30 - 35 | 32 |
| Arduino ATtiny85 Board | 31 | 31 |
| STM32 Blue Pill STM | 35 - 40 | 37 |
| STM32 Blue Pill CKS | 30 | 30 |
| ESP8266 D1 Mini USB-C | 69 | 69 |
| ESP8266 Node MCU | 78 | 78 |
| ESP32 WROOM 32 | 120 | 120 |
| ESP32 LOLIN 32 | 97 | 97 |
| ESP32-C3 Super Mini | 18 - 22 | 20 |
| ESP32-S2 Mini | 10 - 11 | 11 |
| ESP32-C6 (LOLIN Format) | 39 | 39 |
| ESP32-S3 (LOLIN Format) | 45 | 45 |
Sortiert nach dem mittleren "Stromverbrauch" (eigentlich korrekt ja der Leistungsaufnahme), ergibt sich folgendes Bild:
| Mikrocontroller | mA Bereich | mA Mittel |
|---|---|---|
| nRF52840 SuperMini / ProMicro | 2.5 - 3.5 | 3 |
| Raspi Pico RP2040 USB-C ohne LED | 10 - 12 | 11 |
| ESP32-S2 Mini | 10 - 11 | 11 |
| Arduino Nano USB-C 2x LED | 20 | 20 |
| ESP32-C3 Super Mini | 18 - 22 | 20 |
| STM32 Blue Pill CKS | 30 | 30 |
| Arduino ATtiny85 Board | 31 | 31 |
| Arduino ATtiny85 Digispark | 30 - 35 | 32 |
| STM32 Blue Pill STM | 35 - 40 | 37 |
| ESP32-C6 (LOLIN Format) | 39 | 39 |
| ESP32-S3 (LOLIN Format) | 45 | 45 |
| ESP8266 D1 Mini USB-C | 69 | 69 |
| ESP8266 Node MCU | 78 | 78 |
| ESP32 LOLIN 32 | 97 | 97 |
| ESP32 WROOM 32 | 120 | 120 |
Sieger ist das nRF52840 SuperMini / ProMicro Board mit nur 3 mA. Dahinter Raspberry Pi Pico RP2040 und ESP32-S2 Mini mit ungefähr dem 4-fachen Verbrauch. Danach folgen die nicht mehr so stromsparenden Mikrocontroller mit 20 mA und mehr, was bis zu 120 mA für den ESP32 classic (WROOM32) hochgeht, was dann schon eine Hausnummer ist dafür, dass das Board eigentlich nichts produktives tut. Das sind 40 mal so viel wie beim nRF52840 SuperMini!
Von den alten Arduino 8-Bit-Kandidaten hätte ich persönlich weniger Verbrauch erwartet, wie auch vom kleinen ESP32-C3 SuperMini. Der Verbrauch von ESP32-S2 Mini war überraschend gut, den hätte ich höher eingeschätzt. Und der ESP32 classic hat mich eher negativ überrascht mit seinem Stromhunger.
Man kann schon sagen, dass das nRF52840 SuperMini Board eine gute Wahl ist, wenn es auf den Stromverbrauch ankommt. Insbesondere, weil es ein sehr gutes Preis-/Leistungsverhältnis bietet. Damit ist es mein Favorit, wenn es auf stromsparende Anwendungen ankommt. Und im Batteriebetrieb, wenn die Spannungswandler weniger gefordert werden, ist eventuell noch ein leicht besserer Wert drin.
Allerdings ist der nRF52840 auch nicht so leicht zu programmieren. Zumindest in der Arduino / PlatformIO-Welt. Aber mit meinen Routinen, die ich auch schon im ersten Artikel vorgestellt habe, wird das schon einfacher und man kann seinen Code wie gewohnt schreiben. Wenn auch nicht die ganze Library-Vielfalt zur Verfügung steht.
Deep Sleep Mode mit dem nRF52840
So richtig stromsparend wird ein Mikrocontroller, wenn man ihn in den Tiefschlaf schickt. Dann sollte er eigentlich so gut wie keinen Strom mehr verbrauchen. Dafür dient der Deep Sleep Mode, der immer ziemlich hardwarenah und für jeden Hersteller anders zu programmieren ist.Wie gesagt kommt es immer auf das Board an und was darauf alles mit Strom versorgt werden muss. Am Ende bringt der Deep Sleep Modus aber immer ein wenig was.
Bei meinem LoRa Dev-Board mit RP2040 ging der Verbrauch von 220 mW auf 80 mW im DeepSleep herunter. 80 mW entsprechen ungefähr 16 mA bei 5V. Bei einem RP2040 auf dem Original Raspberry Pi Board hatten wir ja eben 10 mA im "Blinkbetrieb" gemessen. Aber auf dem LoRa Board sind ja auch jeden Menge Komponenten drauf.
Und das Cheap Yellow Display, das für den Deep Sleep Test mit einem ESP32-WROOM32 herhalten musste, ging der Verbrauch von 280 mW auf 68 mW im DeepSleep herunter. 68 mW entsprechen ungefähr 14 mA bei 5V.
Und natürlich ist die Programmierung des Deep Sleep Modes mit dem nRF52840 wieder anders als mit dem ESP32 oder dem Pi Pico. Es hat eine Weile gedauert, bis ich die richtigen Register und deren richtige Konfiguration gefunden hatte, um sie hardwarenah anzusprechen und den Deep Sleep Modus zu aktivieren und zwar so, dass man mit einem Ereignis (Flankenwechsel an einem Pin) den Mikrocontroller auch wieder aufwecken kann.
Das Schlafenlegen selbst war schnell gefunden: ein
NRF_POWER->SYSTEMOFF = 1;Damit verbraucht das nRF52840 SuperMini-Board dann nur noch sehr gute 250 µA, also 0.25 mA oder ¼ mA. Das ist zwar mehr als die Versprechung von wenigen Mikroampere im nRF52840-Datenblatt, aber das sind natürlich nur die Werte für den Chip selbst, ohne die Peripherie.
Als Versuchsaufbau nehme ich wieder den vom letzten Mal: den mit RGB-LED und Taster auf einem Breadboard. Den Taster kann ich dann zum Schlafenlegen und zum Wiederaufwecken benutzen.
Das Video, in dem ich den Deep-Sleep-Stromverbrauch ermittle, kann hier bestaunt werden:
Ich bin mit den 0.25 mA für das Board sehr zufrieden. Wenn man eine kleine Rechnung macht mit einem halbwegs großen 2000 mAh 18650-Akku, dann sind das 2000 mAh * 3.7 V / 5 V / 0.25 mA = 5920 Stunden = 246.66 Tage = ungefähr 8 Monate Laufzeit, bis die Batterie leer ist, wenn der nRF nur schläft und nichts tut. Damit kann man arbeiten.
Zum Vergleich die Rechnung mit 15 mA (ESP32): 2000 mAh * 3.7 V / 5 V / 15 mA = 98.66 h, das sind gerade mal 4 Tage.
Es ist schon ein immenser Unterschied, ob man alle dreiviertel Jahre oder alle vier Tage einen Akku austauschen muss. Auch die Anforderung an ein Solar-Panel sind ganz andere, um ein Board am laufen zu halten.
Source-Code
Ich habe meine nicenano.h angepasst:nicenano.h (klicken, um diesen Abschnitt auf- und zuzuklappen)
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Source Code (C) 2025 Oliver Kuhlemann, cool-web.de (aka Doc Cool)
// see https://cool-web.de/nrf/nrf52840-promicro-nicenano-board-platformio-vorstellung.htm for more info
// Please provide Source and Link, if you use this code
/////////////////////////////////////////////////////////////////////////////////////////////////////////
#define PIN_002 2 // P0.02
//#define PIN_003 3 // P0.03
//#define PIN_004 4 // P0.04
//#define PIN_005 5 // P0.05
#define PIN_006 6 // P0.06
#define PIN_UART1_TX 6 // P0.06
//#define PIN_007 7 // P0.07
#define PIN_008 8 // P0.08
#define PIN_UART1_RX 8 // P0.08
#define PIN_009 9 // P0.09
#define PIN_010 10 // P0.10
#define PIN_011 11 // P0.11
//#define PIN_012 12 // P0.12
#define PIN_013 13 // P0.13
#define PIN_VCC_OFF 13 // P0.13 // auf LOW setzen, um 3.3V-Rail abzuschalten
#define PIN_014 14 // P0.14
#define PIN_RESET 14 // P0.14 // auf LOW setzen für Reset
#define PIN_015 15 // P0.15 // rote LED
#define PIN_LED 15 // P0.15 // zuerst pinmode(15,OUTPUT);
//#define PIN_016 16 // P0.16 // ebenfalls Reset
#define PIN_017 17 // P0.17
//#define PIN_018 18 // P0.18
//#define PIN_019 19 // P0.19
#define PIN_020 20 // P0.20
//#define PIN_021 21 // P0.21
#define PIN_022 22 // P0.22
//#define PIN_023 23 // P0.23
#define PIN_024 24 // P0.24
//#define PIN_025 25 // P0.25
//#define PIN_026 26 // P0.26
//#define PIN_027 27 // P0.27
//#define PIN_028 28 // P0.28
#define PIN_029 29 // P0.29
//#define PIN_030 30 // P0.30
#define PIN_031 31 // P0.31
#define PIN_100 32 // P1.00
#define PIN_101 33 // P1.01
#define PIN_102 34 // P1.02
//#define PIN_103 35 // P1.03
#define PIN_104 36 // P1.04 (SDA) (SPECIFY &Wire)
#define PIN_I2C_SDA 36 // P1.04 (SDA) (SPECIFY &Wire)
//#define PIN_105 37 // P1.05
#define PIN_106 38 // P1.06 (SCL) (SPECIFY &Wire)
#define PIN_I2C_SCL 38 // P1.06 (SCL) (SPECIFY &Wire)
#define PIN_107 39 // P1.07
//#define PIN_108 40 // P1.08
//#define PIN_109 41 // P1.09
//#define PIN_110 42 // P1.10
#define PIN_111 43 // P1.11 (SCK)
#define PIN_SPI_SCK 43 // P1.11 (SCK)
//#define PIN_112 44 // P1.12
#define PIN_113 45 // P1.13 (MOSI)
#define PIN_SPI_MOSI 45 // P1.13 (MOSI)
//#define PIN_114 46 // P1.14
#define PIN_115 47 // P1.15 (MISO)
#define PIN_SPI_MISO 47 // P1.15 (MISO)
#include <Arduino.h>
// Manche Werte in Arduino.h sind falsch bzw. passen nicht und müssen überschrieben werden
// Soll der Werte für RF_Px->PIN_CNF[0...31]=uint32_t
#undef OUTPUT
#define OUTPUT 0x00000001
#undef INPUT
#define INPUT 0x00000000
#define INPUT_DISCONNECTED 0x00000002
#undef INPUT_PULLUP
#define INPUT_PULLUP 0x0000000C
#undef INPUT_PULLDOWN
#define INPUT_PULLDOWN 0x00000004
#undef INPUT_SENSE_LOW
#define INPUT_SENSE_LOW 0x00030000
#undef INPUT_SENSE_HIGH
#define INPUT_SENSE_HIGH 0x00020000
#define INPUT_PULLUP_SENSE_LOW 0x0003000C
#define INPUT_PULLUP_SENSE_HIGH 0x0002000C
#define INPUT_PULLDOWN_SENSE_LOW 0x00030004
#define INPUT_PULLDOWN_SENSE_HIGH 0x00020004
// https://docs.nordicsemi.com/bundle/ps_nrf5340/page/gpio.html
//uint32_t PP0=0; // Bitmuster der angeschalteten Pins 0-31 merken
//uint32_t PP1=0; // Bitmuster der angeschalteten Pins 0-31 merken
void pinMode(int pin, uint32_t pin_mode) {
if (pin < 32) { // P0
NRF_P0->PIN_CNF[pin]=pin_mode;
} else { // P1
NRF_P1->PIN_CNF[pin-32]=pin_mode;
}
}
void digitalWrite(int pin_out, int pin_state) {
if (pin_out < 32) { // P0
if (pin_state) { // HIGH
NRF_P0->OUTSET |= (1 << pin_out);
} else { // LOW
NRF_P0->OUTCLR = (1 << pin_out);
}
} else { // P1
if (pin_state) { // HIGH
NRF_P1->OUTSET |= (1 << (pin_out-32));
} else { // LOW
NRF_P1->OUTCLR = (1 << (pin_out-32));
}
}
}
int digitalRead(int pin_in) {
unsigned long state = 0;
if (pin_in < 32) { // P0
state = NRF_P0->IN ^ (1 << pin_in);
} else { // P1
state = NRF_P1->IN ^ (1 << (pin_in-32));
}
if (state == 0) return 1; // XOR Pin-Bit, wenn 1, dann "1 XOR 1" = 0
return 0;
}
void deepSleep() {
//Serial.println("Deep Sleep Mode entered");
//https://docs.nordicsemi.com/bundle/ps_nrf9160/page/chapters/pmu/doc/operationmodes/frontpage.html
//NRF_POWER_MODE_LOWPWR is the default power mode, so unless you have set it to something else you don't need to set it in the code.
//sd_app_evt_wait(); sd steht für soft device, light sleep, bei dem z. B. BLE anbleiben kann. wird dann in loop aufgerufen
//Serial.println("SYSTEM OFF!");
//NRF_P1->PIN_CNF[0] = 0x0002000C; // SENSE=Low + PULL=Pullup + INPUT=Connect
digitalWrite(PIN_VCC_OFF, LOW);
NRF_POWER->SYSTEMOFF = 1; // 0.25 mA // Der Chip wacht über Reset auf ? setup() startet neu.
// oder auch sd_power_system_off();
}
Sie enthält jetzt den Befehl deepSleep(), der das Board schlafen schickt. Hat man vorher keinen Wakeup-Pin definiert, dann braucht es einen Reset (RST und GND verbinden), damit das Board wieder aufwacht.
Möchte man ein externes Ereignis zum Aufwachen benutzen, dann muss dieses Ereignis einen Input-Pin auf High oder Low bringen. Einfachstes Beispiel dafür ist wohl ein Taster. Es kann aber auch eine Fotodiode, ein Mikrofon oder eine Lichtschranke sein; ggf. jeweils durch einen Operationsverstärker auf den richtigen Pegel gebracht.
Das Aufwachereignis wird mit dem PinMode konfiguriert:
pinMode(PIN_100, INPUT_PULLUP_SENSE_LOW );Sobald deepSleep() aufgerufen ist, sorgt der nRF52840 selbst dafür, diesen Sense-Pin zu beobachten, ob sich ein Flankenwechsel von High auf Low ergibt. Dann führt er einen Reset durch und das Programm startet wieder bei setup(), gefolgt von loop().
Ich persönlich finde es sehr elegant, das Aufweckereignis direkt mit der PinMode-Definition zu verbinden wie es hier der nRF52840 macht und dass es keinen Extra-Code zur Definition eines Wakeup-Events braucht, wie bei anderen Mikrocontrollern üblich. Das ein Pin ein Aufweck-Pin ist, gehört ja auch irgendwie zur Pin-Konfiguration selbst und so hat man alles beieinander.
Quellen, Literaturverweise und weiterführende Links
- Nordic Semiconductor

- Product Sheet nRF52840

- platformio.org: Nordic nRF52840-DK

- platformio.org: Adafruit Feather nRF52840 Express

- platformio.org: nRF52xxx Boards

- Github: Adafruit_nRF52_Arduino

- nicekeyboards.com: nice!nano als Pro Micro Ersatz für schnurlose Tastaturen

- Adafruit Feather nRF52840 Express

- Nordic: nRF52840 DK (Development Kit)

- Nordic: GPIO-Register und Konsiguration

- Nordic: Power Saving
