Vorstellung des nRF52840 ProMicro/SuperMini Board (nice!nano kompatibel)
Die Firma Nordic Semiconductor baut System On Chip (SoCs) als Mikrocontroller, die sich durch ihren geringen Stromverbrauch und günstigen Preis auszeichnen.Aufmerksam bin ich auf den nRF52840 geworden, als ich ihn in zahlreichen Meshtastic-Geräten als Prozessor vorgefunden habe. Besonders in jenen, die einen niedrigen Stromverbrauch als Fokus hatten (solche mit ePaper-Display).
Nach meinen Deep-Sleep-Experimenten mit dem ESP32 habe ich herausgefunden, dass die ESP32-Boards, die ich bisher eingesetzt habe, nicht so richtig auf Low Power zu trimmen sind. Darum war ich neugierig, wie sich hier nRF-Boards schlagen. Vielleicht sind diese ja eher zu bändigen, um lange Batterielaufzeiten zu bekommen, so mein Gedanke.
Die SoCs von Nordic sind 3.3 Volt Mikrocontroller, die im Vergleich zum ESP32 nicht ganz so viel Rechenpower haben, dafür im Deep Sleep Modus noch ein Quäntchen mehr Strom sparen können. Sie kommen deswegen häufig in Wearables, Smart Watches, GPS-Empfänger oder LoRa / Meshtastic Geräte zum Einsatz.
Im Gegensatz zum ESP32 haben die nRF-Mikrocontroller allerdings keine vollständig implementierte WLAN-Funktionalität. Außerdem sind die nRF-Chips auf Low-Power-Funkprotokolle spezialisiert. Die Funkprotokolle ANT, Thread oder Zigbee sind oft schon an Bord verbaut und der nRF5340 kann auch LE Audio.
nRF-Chips sind zusammen mit ESP32 und Raspberry Pi Pico derzeit (2025) im Mikrocontroller-Segment die erste Wahl in Sachen Preis-/Leistungsverhältnis und Library-Unterstützung für Maker.
Als ich auf AliExpress dann nRF52840-Boards für ein paar Euro gesehen habe, konnte ich nicht länger widerstehen und habe ich mir ein paar zum Experimentieren bestellt.
Mein Wahl fiel auf das nRF52840 "ProMicro" Board, wie es auch von Tenstar Robot auf AliExpress angeboten wird. Dieses ist als Keyboard-Controller im Nice! Nano-Projekt populär geworden. Das wollen wir uns heute näher anschauen.
Das nRF52840 SoC
nRF-Mikrocontroller gibt es seit 2012. Die nRF51-Serie begründete die nRF5-Serie. Die nRF5er-Serie ist auch heute noch aktuell. Besonders interessant für Maker ist das Flaggschiff nRF52840, für das es eine gute Library-Unterstützung im Arduino-Framework gibt.Hier die Features des nRF52840-ProMicro-Baords (weitere nRF Varianten siehe Nordic Semiconductor nRF-Familien / Varianten):
- Cortex-M4F, 64 MHz
- Flash: 1 MB
- RAM: 256 KB
- Funk: BLE 5 (Long Range, 2Mbit), Thread, Zigbee, ANT, 2.4 GHz, USB
- Flaggschiff der Serie
- Krypto-Funktionen wie AES, SHA-256 und ein echter Zufallszahlengenerator (True Random Number Generator, TRNG)
- zwei Onboard-LEDs: blau (Alive-Status) und rot (Upload-Status)
- Unterstützung für LiIon-Zelle (3.7V) mit Lade-Chip (100 mA, kann auf 300 mA gejumpert werden bei Akkus > 500 mAh)
- Das Board ist auf Stomsparen ausgelegt mit Verbrauchswerten bis runter zu 20 µA
- Die 3.3V-Rail kann einfach abgeschaltet werden (Pin P0.13 auf Low setzen), um Sensoren etc. abzuschalten und so auch dort Strom zu sparen
Vergleich: nRF52840 vs. ESP32-WROOM32
Was der ESP32 (classic, WROOM32) hat, was dem nRF52840 fehlt:- ESP32: Vollwertiges Wi-Fi (802.11 b/g/n, 2,4 GHz). Das heißt: Internet-Anbindung ohne Gateway.
- nRF52840: Kein Wi-Fi - nur 2.4 GHz Low-Power (BLE, Zigbee, Thread). Für Internet braucht man ein extra Modul.
- ESP32: Zwei Xtensa LX6 Kerne (bis 240 MHz). Einer für Applikation, einer für RTOS/Wi-Fi-Stack.
- nRF52840: Single-Core Cortex-M4F (64 MHz). Energiesparend, aber weniger Multitasking-Power.
- ESP32: Typisch 4 MB externes Flash, manche Varianten bis 16 MB; RAM: 520 KB SRAM + optional externes PSRAM (8-16 MB).
- nRF52840: Fester interner Speicher (1 MB Flash, 256 KB RAM), kein externes RAM.
- ESP32: Eingebaute DACs, I2S mit mehr Kanälen, Unterstützung für MP3/AAC-Decoding (Libraries vorhanden).
- nRF52840: Kein DAC, I2S ist integriert, aber kein Audio-Beschleuniger.
Was der nRF52840 hat, was dem ESP32 fehlt:
- nRF52840: Sehr energiesparend. Optimiert für Batteriebetrieb, Standby im µA-Bereich, super für Sensoren, Wearables.
- ESP32: Wi-Fi zieht viel Strom (100–250 mA Peaks), Deep Sleep ca. 10–150 µA, also höher als Nordic.
- nRF52840: Vollwertige BLE 5.0 Features (Long Range bis 1 km mit Coded PHY, Direction Finding).
- ESP32: WROOM32 nur BLE 4.2, eingeschränkt in Reichweite und Features. Neue ESP32-Varianten haben bei Bluetooth nachgelegt
- nRF52840: Unterstützt nativ Zigbee und Thread (Matter-fähig).
- ESP32: Nur Wi-Fi + Bluetooth, kein Zigbee/Thread. Außer der ESP32-H2 und der ESP32-C6, die können ZigBee, Thread, Matter.
- nRF52840: Kann NFC mit 13.56 MHz nativ, benötigt dafür nur eine entsprechende Spule an den Pins NFC1 und NFC2
- ESP32: benötigt extra NFC-Reader/Writer und Spule wie zum Beispiel ein RC522-RFID Modul
- nRF52840: Hat integrierten USB (z. B. für HID-Geräte, Mass Storage, CDC).
- ESP32: Kein nativer USB (man braucht extra UART-Chip), außer auf den Boards mit dem großen ESP32-S3 mit PSRAM und zwei USB-C-Ports
- nRF52840:Zuverlässiger RF-Stack & Industrie-Einsatz:Nordic BLE-Stack ist extrem stabil, weit verbreitet in Medizintechnik, Industrie, Consumer-Geräten.
- ESP32-BLE ist für Maker gut, aber nicht ganz so ausgereift für professionelle Serienprodukte.
Wenn man WLAN benötigt, dann nimmt man den ESP32, oder auch den neuen Raspberry Pi Pico W. Der ESP32 bietet auch mehr Rechenpower als der nRF52840. Wenn man allerdings besonders stromsparend unterwegs sein will für kleine Geräte wie Wearables, Smartwatches, IoT- und LoRa-Sensoren, dann bietet sich ein nRF an. Auch weil ein nRF gleich die dort üblichen Funkstandards wie BLE/Zigbee/Thread unterstützt.
Ist der Stromverbrauch nicht das Wichtigste, dann kann man auch einen der neuen ESP32-Varianten nehmen, die ebenfalls Bluetooth 5.x, ZigBee, Thread und Matter unterstützen.
Oder ganz kurz zusammengefasst als Faustformel:
Internet und Power → ESP32
Batterie und Funk → nRF52840
Für ESP32 im Arduino-Framework auf PlatformIO gibt es einen Top Support, eine riesige Community, und fast alles läuft "out of the box". Ideal für schnelle Maker-Projekte, Internet-of-Things mit Wi-Fi, Webservern, MQTT.
Pinout des nRF52840 ProMicro-Boards

Download als PDF
Anmerkungen:
- Mit 2x schnell (innerhalb von 0.5 Sekunden) Reset und GND verbinden kommt man in den Bootloader-Upload-Modus, bei dem man ein .UF2-File auf das dann erscheinende Laufwerk kopieren kann
- Das Board lädt einen an B- und B+ angeschlossenen LiIon-Akku normalerweise mit 100 mA, was nicht sehr schnell ist. Auf der Rückseite befinden sich nahe den RST und VCC Pins zwei kleine Pads. Wenn diese verbunden werden, wird mit 300 mA geladen. Das soll man aber nur tun, wenn der Akku mehr als 500 mAh Kapazität hat, weil sonst Explosionsgefahr besteht.
- Auf der Rückseite befinden sich die 4 Pads VDD, DIO, CLK und GND. Diese sind für die Programmierung über Pogo-Pins mittels eines JTAG-Programers gedacht. Wobei DIO=SWD und LCK=SWC entspricht. Mit dem richtigen Bootloader (mit dem das Board schon ausgeliefert wird), kann aber über USB programmiert werden.
- Die rote LED blinkt z. B. beim Hochladen eines Scripts. Sie ist über P0.15 ansprechbar, muss allerdings erst als Output über PinMode definiert werden. Die blaue LED blitzt in Intervallen auf und gibt evtl. den Funkstatus wieder.
- Zieht man Pin P0.14 oder P0.16 in der Software auf Low, dann wird ein Reset ausgeführt.
- Zieht man Pin P0.13 per Software auf Low, wird die VCC-Leitung auf 0V statt 3.3V geschaltet. So kann man einfach externe Sensoren abschalten und nochmals Strom sparen.
Unterstützung von nRF52840 im Arduino-Framework auf PlatformIO
Die Unterstützung von nRF52840 im Arduino-Framework auf PlatformIO ist okay, aber begrenzt. BLE/USB funktioniert zwar mit Adafruit-Libs, aber es ist nicht alles abgedeckt. Für ernsthafte IoT-Protokolle (Thread, Zigbee, Matter) sollte man eher zum nRF Connect SDK (Zephyr) wechseln.Wie gesagt, wird das nRF52840 "ProMicro" Board von Tenstar eher als Keyboard-Controller verkauft, wie es im Nice! Nano-Projekt verwendet wird.
Ich würde gerne meine gewohnten Ardunio-Programmier-Befehle und auch weiterhin Visual Studio Code mit Platform IO als Entwicklungsumgebung behalten. Wie sich herausstellen soll, ist das gar nicht so einfach.
In der PlatformIO ist nämlich kein Board "NiceNano" oder "ProMicro" für den nRF52840 zu finden.
Es gibt wohl zwar das Projekt Adafruit_nRF52_Arduino, aber das scheint nicht ganz kompatibel zu sein.
Ich habe einige Board-Definitionen ausprobiert:
- die Eine hat beim Upload gleich mal den Bootloader zerschossen, so dass kein weiterer Upload möglich war. Gut, wenn man dann mehr als ein Board gekauft hat und von einem zweiten Board den Bootloader herunter- und auf das zerschossene Board wieder heraufladen kann.
- bei der nächsten war "Serial" unbekannt. Also keine Debug-Ausgaben über den USB-Port wie gewohnt.
- dann hatte ich Eine, bei der Serial und der Upload funktionierte, aber sich nichts auf GPIO-Ebene tat.
[env:adafruit_feather_nrf52840]
platform = nordicnrf52
board = adafruit_feather_nrf52840
framework = arduino
monitor_speed = 115200
lib_deps =
https://github.com/adafruit/Adafruit_nRF52_Arduino
Allerdings weigerte sich das System, meine Befehle mittels pinMode() und digitalWrite() richtig auszuführen. Es tat sich einfach nichts bei meiner RGB-LED, die ich in einer Testschaltung angeschlossen habe. Irgendwas war noch falsch. Erst hatte ich meine Pin-Definitionen in Verdacht, aber später kam ich darauf, dass die pinMode(), digitalWrite() einfach nicht richtig programmiert waren und irgendwie "daneben gingen".
Und bist du nicht willig, so gebrauche ich die LowLevel-API
Ein erster Versuch, direkt die nRF-Register direkt zu manipulieren, um die GPIO-Pins anzusteuern, brachte dann Erfolg und so hielt ich mich im weiteren Verlauf an die Dokumentation von Nordic Semiconductor, um meine eigenen Befehle zu programmieren, die ich digiMode(), digiWrite() und digiRead() nannte.Unter Verwendung von digiMode(), digiWrite() und digiRead() statt pinMode() und digitalWrite() und digitalRead() funktionierte nach ein bisschen Nordic-Dokumentation lesen und testen dann auch meine Schaltung wie gewünscht: Anzeige (Output) einer von drei Farben auf der RGB-LED, weiterschalten mit einem Taster (Input).
Der nRF52840 hat zwei 32 bit breite Register, um den High/Low-Status von bis zu 64 GPIOs zu verwalten. Die 64 Bits speichern den Zustand der Pins, 1 für High und 0 für Low.
Die erste Bank wird P0 genannt und ist für GPIO-Pin 0 bis 31 zuständig. Und die zweite Bank wird P1 genannt und ist für GPIO-Pin 32 bis 63 zuständig.
Außerdem gibt es 64 32-bit-Register, über den der Modus für den entsprechenden Pin eingestellt werden kann. Diese sind über NRF_Px->PIN_CNF[0...31] erreichbar. Zur Konfiguration eines Pins wird ein 32-bit-Wort übergeben.
NRF_Px->PIN_CNF[0...31]=mode ist also der Befehl, um den Modus (Input, Output, Pullup, Pulldown) zu konfigurieren.
NRF_Px->OUTSET(pinbit) setzt ein oder mehrere Pin-Bits auf HIGH.
NRF_Px->OUTCLR(pinbit) setzt ein oder mehrere Pin-Bits auf LOW.
In Code gegossen für die Funktionen pinMode() und digitalWrite() und digitalRead() sieht das dann so aus:
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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
/////////////////////////////////////////////////////////////////////////////////////////////////////////
void pinMode(int pin, uint32_t pin_mode) {
uint32_t mode=0;
if (pin_mode == OUTPUT ) mode = 3;
else if (pin_mode == INPUT ) mode = 0;
else if (pin_mode == INPUT_PULLUP ) mode = 12;
else if (pin_mode == INPUT_PULLDOWN) mode = 4;
if (pin <= 31) { // P0
NRF_P0->PIN_CNF[pin]=mode;
} else { // P1
NRF_P1->PIN_CNF[pin-32]=mode;
}
}
void digitalWrite(int pin_out, int pin_state) {
if (pin_out <= 31) { // 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 <= 31) { // 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;
}Die Pin-Definitionen sind nicht endgültig. Eventuell ändere und erweitere ich die noch. Zum Beispiel, wenn ich herausfinde, über welche Pins man die internen LEDs anspricht.
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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_015 15 // P0.15 LED?
//#define PIN_016 16 // P0.16
#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>Weitere Aussichten
Ob jetzt mit diesem Konstrukt I2C und SPI und alles andere Mögliche funktionieren wird - ich bin mir (noch) nicht sicher. Da muss ich erst tiefer forschen und wahrscheinlich noch das eine oder andere programmieren.Auf jeden Fall wundert mich nicht, dass ich so gut wie nichts zur Programmnierung des nRF52840 ProMicro Boards im Internet gefunden habe. Dafür ist das wohl eher nicht vorgesehen, sondern eher dafür, um darauf dieses Nice-Nano-Keyboard-Projekt laufen zu lassen.
Wie dem auch sei: Der Stromverbrauch scheint beim nRF52840 ProMicro Board sehr niedrig auszufallen, auch schon so ohne Deep Sleep. Das heißt, dass es auch mit der bisher möglich gemachten Funktionalität ein brauchbarer Kandidat für stromsparende Projekte ist.
Hier werde ich als nächsten mal einen Stromverbrauchsvergleich zwischen den einzelnen Mikrocontrollern, die ich sonst so habe, anstellen und schauen, wo sich dieses Board einordnet. Wenn es sich lohnt, werde ich weiter zu Deep Sleep forschen und dann hätte man ein tolles Board für langanhaltenden Batteriebetrieb - freundlicherweise ich ein LiIon-Ladeschaltung ja schon auf dem Board vorhanden.
Test-Aufbau
Als Test-Schaltung verwende ich einen einfachen Aufbau mit einer RGB-LED und einem Taster. Der Taster, damit ich auch einen Input habe, den ich testen kann.

Bilder anklicken, um sie größer darzustellen. Die RGB-LED ist common Ground und mit einem 220 Ω Widerstand an GND angeschlossen. Die 3 Anschlüsse für die Farben gehen auf die Pins 020, 022 und 024. Pin 100 geht zum Taster, der bei Betätigung mit GND kurzgeschlossen wird. Deshalb wird für diesen Pin der interne Pullup-Widerstand des nrf52840 aktiviert.
Beim Start soll das Programm die erste Farbe der LED anschalten, indem Pin 020 auf High gezogen wird. Nach Tastendruck sollen die Farben weitergeschaltet werden und wenn sie durch sind, wieder von vorne angefangen werden.
Der Sourcecode dazu sieht so aus:
#include "nicenano.h" // vor Arduino.h wegen SPI-Pins Arduino Mega
#include <Arduino.h>
int pin_in=PIN_100;
int pin_out_1=PIN_020;
int pin_out_2=PIN_022;
int pin_out_3=PIN_024;
void setup() {
pinMode(pin_in, INPUT_PULLUP);
pinMode(pin_out_1, OUTPUT);
pinMode(pin_out_2, OUTPUT);
pinMode(pin_out_3, OUTPUT);
// NRF_P0->PIN_CNF[20] = 0x00000003; // Output
// NRF_P0->PIN_CNF[22] = 0x00000003; // Output
// NRF_P0->PIN_CNF[24] = 0x00000003; // Output
// NRF_P1->PIN_CNF[0] = 0x0000000C; // Input mit Pullup
// digiMode(pin_in, INPUT_PULLUP);
// digiMode(pin_out_1, OUTPUT);
// digiMode(pin_out_2, OUTPUT);
// digiMode(pin_out_3, OUTPUT);
Serial.begin(115200);
Serial.println("Test gestartet!");
}
void loop() {
int led_an=1;
while (1) {
Serial.print("LED "); Serial.print(led_an); Serial.println(" an");
if (led_an == 1) { digitalWrite(pin_out_1, HIGH); digitalWrite(pin_out_2, LOW); digitalWrite(pin_out_3, LOW); }
if (led_an == 2) { digitalWrite(pin_out_1, LOW); digitalWrite(pin_out_2, HIGH); digitalWrite(pin_out_3, LOW); }
if (led_an == 3) { digitalWrite(pin_out_1, LOW); digitalWrite(pin_out_2, LOW); digitalWrite(pin_out_3, HIGH); }
// while (1) { // rudimentärer Blink-Test nRF
// NRF_P0->OUTSET |= (1 << 20); // Pin HIGH
// delay(200);
// NRF_P0->OUTCLR = (1 << 20); // Pin LOW
// delay(200);
// Serial.print(".");
// }
// while (1) { // rudimentärer Blink-Test nRF, eigene Routinen
// digiWrite(pin_out_2, HIGH);
// delay(200);
// digiWrite(pin_out_2, LOW);
// delay(200);
// Serial.print(".");
// }
while (digitalRead(pin_in) == HIGH) { // warten bis Taster gedrückt
delay (10);
}
Serial.println("Taster gedrückt");
while (digitalRead(pin_in) == LOW) { // warten bis Taster wieder losgelassen
delay (10);
}
Serial.println("Taster losgelassen");
led_an++;
if (led_an > 3) led_an = 1;
}
}
Video
Hier noch ein Demonstrationsvideo, um zu zeigen, dass der Code funktioniert und dem ich noch so das eine oder andere Wort rund um das Board verliere: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)
