Arduino Nano RP2040 Connect¶
Warnung
Dieses Board wird nicht mehr unterstützt. Die letzte OpenMV-Firmware-Version für den Arduino Nano RP2040 Connect ist 4.7.0. Für dieses Ziel werden keine weiteren Firmware-Updates, Fehlerbehebungen oder neuen Funktionen mehr veröffentlicht. Die nachfolgenden Informationen werden für Anwender bereitgehalten, die 4.7.0 oder früher verwenden.
Der Arduino Nano RP2040 Connect ist ein 45 × 18 mm großes Board im Arduino-Nano-Formfaktor, das auf dem Raspberry Pi RP2040 basiert — einem Dual-ARM-Cortex-M0+ mit 133 MHz und 264 KB internem SRAM. WiFi und BLE stammen von einem U-blox-NINA-W102-Modul, und das Board trägt eine LSM6DSOX-6-Achsen-IMU sowie ein MP34DT06-PDM-Mikrofon. Die OpenMV-Firmware steuert all dies von MicroPython aus an.
Vollständiges Datenblatt, Fotos und Abmessungen finden Sie auf der Produktseite des Arduino Nano RP2040 Connect.
Highlights¶
Raspberry Pi RP2040 Dual-ARM-Cortex-M0+ mit 133 MHz und 264 KB internem SRAM.
16 MB externer QSPI-Flash.
U-blox-NINA-W102-Modul mit 2,4-GHz-Wi-Fi b/g/n und Bluetooth 4.2 (BR/EDR + LE).
LSM6DSOX-6-Achsen-IMU und MP34DT06-PDM-Mikrofon.
Micro-USB-Anschluss für Stromversorgung, Programmierung und eine CDC-REPL.
22 Benutzer-I/O-Pins an den standardmäßigen Nano-Headern —
TX/RX,D2–D13(digital),A0–A7(analog).
Pinbelegung¶
Pin-Referenz¶
Pin-Name |
Referenz |
Funktion |
|---|---|---|
TX |
3,3 V |
UART0 TX / SPI0 RX / I2C0 SDA / PWM0 A |
RX |
3,3 V |
UART0 RX / SPI0 CS / I2C0 SCL / PWM0 B |
D2 |
3,3 V |
SPI1 CS / UART1 RX / I2C0 SCL / PWM4 B |
D3 |
3,3 V |
SPI1 TX / UART0 RTS / I2C1 SCL / PWM7 B |
D4 |
3,3 V |
SPI0 RX / UART0 TX / I2C0 SDA / PWM0 A |
D5 |
3,3 V |
SPI0 CS / UART0 RX / I2C0 SCL / PWM0 B |
D6 |
3,3 V |
SPI0 SCK / UART0 CTS / I2C1 SDA / PWM1 A |
D7 |
3,3 V |
SPI0 TX / UART0 RTS / I2C1 SCL / PWM1 B |
D8 |
3,3 V |
SPI0 RX / UART1 TX / I2C0 SDA / PWM2 A |
D9 |
3,3 V |
SPI0 CS / UART1 RX / I2C0 SCL / PWM2 B |
D10 |
3,3 V |
SPI0 CS / UART1 RX / I2C0 SCL / PWM2 B |
D11 |
3,3 V |
SPI0 TX / UART1 RTS / I2C1 SCL / PWM3 B |
D12 |
3,3 V |
SPI0 RX / UART1 TX / I2C0 SDA / PWM2 A |
D13 |
3,3 V |
SPI0 SCK / UART1 CTS / I2C1 SDA / PWM3 A |
D14 / A0 |
3,3 V |
ADC / SPI1 SCK / UART1 CTS / I2C1 SDA / PWM5 A |
D15 / A1 |
3,3 V |
ADC / SPI1 TX / UART1 RTS / I2C1 SCL / PWM5 B |
D16 / A2 |
3,3 V |
ADC / SPI1 RX / UART0 TX / I2C0 SDA / PWM6 A |
D17 / A3 |
3,3 V |
ADC / SPI1 CS / UART0 RX / I2C0 SCL / PWM6 B |
D18 / A4 / SDA |
3,3 V |
ADC / I2C0 SDA / SPI1 RX / UART0 TX / PWM6 A |
D19 / A5 / SCL |
3,3 V |
ADC / I2C0 SCL / SPI1 CS / UART0 RX / PWM6 B |
D20 / A6 |
3,3 V |
ADC / GPIO |
D21 / A7 |
3,3 V |
ADC / GPIO |
RESET |
3,3 V |
Drücken Sie die On-Board-RESET-Taste oder ziehen Sie den Pin auf GND, um einen Reset auszulösen |
REC |
3,3 V |
BOOTSEL — beim Einschalten auf High ziehen, um den ROM-Bootloader des RP2040 zu starten |
LED_BUILTIN |
— |
Orangefarbene Benutzer-LED an |
LED_RED |
— |
Roter Kanal der RGB-LED |
LED_GREEN |
— |
Grüner Kanal der RGB-LED |
LED_BLUE |
— |
Blauer Kanal der RGB-LED |
Warnung
Die I/O-Pins des Nano RP2040 Connect sind nur für 3,3 V ausgelegt — sie sind nicht 5-V-tolerant. Das Anlegen von 5 V beschädigt den RP2040.
Stromversorgungs-Pins¶
VIN — 4–20 V Eingang. Versorgt das Board über den On-Board-Schaltregler. Wird außerdem über eine Diode aus der USB-5-V-Schiene gespeist, sodass USB und
VINgleichzeitig anliegen können, ohne sich gegenseitig rückzuspeisen.+5V — standardmäßig nicht verbunden.
+3V3 — Ausgang des 3,3-V-Reglers.
AREF — analoger Referenz-Pin. Auf diesem Board nicht mit dem RP2040 verdrahtet — der ADC ist immer auf 3,3 V referenziert.
GND — gemeinsame Masse.
Der Nano RP2040 Connect kann über einen der beiden Pfade mit Strom versorgt werden:
Micro-USB — liefert 5 V an den On-Board-Regler.
VIN-Pin — legen Sie eine geregelte Spannung von 4–20 V an.
Bemerkung
Ein Lötjumper auf der Unterseite des Boards verbindet +5V mit der USB-5-V-Schiene. Schließen Sie ihn, damit der +5V-Header-Pin tatsächlich 5 V führt.
Bemerkung
Ein normalerweise geschlossener Lötjumper am Ausgang des On-Board-4–20-V-Schaltreglers kann durchtrennt werden, um den Regler zu deaktivieren, sodass das Board direkt aus einer externen 3,3-V-Versorgung an +3V3 betrieben werden kann.
Recovery- und Debug-Pins¶
RESET — sowohl ein freiliegendes Pad als auch eine RESET-Taster auf der Oberseite des Boards, beide mit der NRST-Leitung des RP2040 verbunden. Ziehen Sie auf GND oder drücken Sie die Taste, um einen Reset auszulösen.
REC — freiliegendes Pad. Wenn
RECbeim Einschalten (oder während des Drückens von RESET) auf High gehalten wird, versetzt dies den RP2040 in seinen ROM-Bootloader; das Board meldet sich erneut als USB-Massenspeicherlaufwerk mit dem NamenRPI-RP2an und akzeptiert ein.uf2-Firmware-Image.
Der Nano RP2040 Connect verwendet den standardmäßigen Doppeltipp-Reset von Arduino, um den Arduino-Bootloader zu starten. Drücken Sie die RESET-Taste schnell zweimal — das Board meldet sich über USB erneut als UF2-Gerät an, und OpenMV IDE kann ein neues Firmware-Image flashen.
Die SWD-Signale des RP2040 sind auf metallisierten Pads auf der Rückseite des Boards, direkt unter dem NINA-Modul, herausgeführt. Alle Debug-Signale sind auf 3,3 V referenziert.
On-Board-Peripheriegeräte¶
LEDs¶
Der Nano RP2040 Connect verfügt über eine Benutzer-RGB-LED — angesteuert über die mit LED_RED, LED_GREEN und LED_BLUE bedruckten Kanäle — sowie eine separate orangefarbene LED_BUILTIN an D13. Alle vier sind per Software über machine.LED steuerbar:
from machine import LED
LED("LED_RED").on()
LED("LED_GREEN").on()
LED("LED_BLUE").on()
LED("LED_BUILTIN").on()
Eine separate grüne Power-LED auf dem Board leuchtet immer dann, wenn die +3,3-V-Schiene aktiv ist, und ist nicht benutzersteuerbar.
Kamerasensor¶
Die OpenMV-Firmware auf dem Nano RP2040 Connect unterstützt den parallelen CMOS-Sensor OmniVision OV7670. Das Board hat keinen On-Board-Bildsensor — verdrahten Sie ein OV7670-Modul mit den nachfolgend aufgeführten, bedruckten Header-Pins und steuern Sie es über das csi — Kamerasensoren-Modul an:
import csi
cam = csi.CSI()
cam.reset()
cam.pixformat(csi.RGB565)
cam.framesize(csi.QVGA)
cam.snapshot(time=2000) # let auto‑exposure settle
while True:
img = cam.snapshot()
Bemerkung
Der OV7670 benötigt 14 Pins. Die Firmware verdrahtet sie wie folgt:
Sensorsignal |
Nano-RP2040-Pin |
|---|---|
D0 |
|
D1 |
|
D2 |
|
D3 |
|
D4 |
|
D5 |
|
D6 |
|
D7 |
|
HSYNC |
|
VSYNC |
|
PXCLK |
|
MXCLK |
|
POWER |
|
RESET |
|
SCL |
|
SDA |
|
Der I²C-Steuerbus des OV7670 wird mit der On-Board-IMU und dem ATECC608A an I²C 0 geteilt. Der Sensor liegt auf der 7-Bit-Adresse 0x21 — Benutzergeräte an Bus 0 müssen diese Adresse ebenfalls meiden, wenn die Kamera verdrahtet ist.
IMU¶
Der On-Board-LSM6DSOX-6-Achsen-Beschleunigungssensor + Gyroskop sitzt an I2C0. Das machine.I2C(0) des rp2-Ports verwendet standardmäßig einen anderen Pin-Satz, übergeben Sie daher die bedruckten SDA/SCL-Pads explizit. Verwenden Sie den eingefrorenen Treiber lsm6dsox.LSM6DSOX:
import time
from machine import I2C, Pin
from lsm6dsox import LSM6DSOX
bus = I2C(0, scl=Pin("SCL"), sda=Pin("SDA"))
imu = LSM6DSOX(bus)
while True:
print(imu.accel()) # (x, y, z) in g
print(imu.gyro()) # (x, y, z) in deg/s
time.sleep_ms(100)
Mikrofon¶
Das On-Board-MP34DT06-PDM-Mikrofon wird über audio — Audio-Modul unter Verwendung eines der PIO-Blöcke des RP2040 erfasst:
import audio
from ulab import numpy as np
def loudness(pcmbuf):
samples = np.array(np.frombuffer(pcmbuf, dtype=np.int16), dtype=np.float)
rms = np.sqrt(np.mean(samples ** 2))
if rms > 10000:
print("Loud!", int(rms))
audio.init(channels=1, frequency=16000, gain_db=24)
audio.start_streaming(loudness)
while True:
pass
Wi-Fi¶
Das On-Board-NINA-W102-Modul wird über network — Netzwerkkonfiguration als Station-Schnittstelle bereitgestellt:
import network, time
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect("ssid", "password")
while not wlan.isconnected():
time.sleep(1)
print("Wi‑Fi IP:", wlan.ipconfig("addr4")[0])
Bluetooth¶
Dasselbe NINA-Modul stellt außerdem Bluetooth 4.2 LE bereit. Verwenden Sie aioble — Async BLE für asyncio-freundliches BLE — bewerben Sie sich beispielsweise als Peripheriegerät und warten Sie, bis sich ein Central verbindet:
import asyncio
import aioble
async def run():
while True:
conn = await aioble.advertise(250_000, name="Nano-RP2040")
print("Connected:", conn.device)
await conn.disconnected()
asyncio.run(run())
Bus-Referenz¶
GPIO¶
Verwenden Sie machine.Pin, um einen der bedruckten Pins zu lesen oder anzusteuern. Ausgänge sind 3,3-V-CMOS, 50 mA Gesamtsenke über alle GPIOs hinweg.
from machine import Pin
out = Pin("D2", Pin.OUT)
out.on()
out.off()
out.value(1)
inp = Pin("D3", Pin.IN, Pin.PULL_UP)
print(inp.value())
Jeder Eingangs-Pin kann außerdem bei Flankenwechseln einen Interrupt auslösen:
def handler(pin):
print("triggered:", pin)
Pin("D3", Pin.IN, Pin.PULL_UP).irq(
handler, Pin.IRQ_FALLING | Pin.IRQ_RISING,
)
UART¶
Bus |
TX |
RX |
|---|---|---|
UART0 |
TX |
RX |
Verwenden Sie die Siebdruckbezeichnungen TX/RX mit machine.UART:
from machine import UART
uart = UART(0, baudrate=115200)
uart.write("hello")
uart.read(5)
Bemerkung
machine.UART(1) existiert, ist aber für das On-Board-NINA-W102-Modul reserviert (die BLE-Verbindung); verwenden Sie es nicht direkt.
I²C¶
Bus |
SDA |
SCL |
|---|---|---|
I2C0 |
|
|
I2C1 |
|
|
Beiden Bussen müssen ihre Pins explizit an machine.I2C übergeben werden:
from machine import I2C, Pin
bus0 = I2C(0, scl=Pin("SCL"), sda=Pin("SDA"), freq=400_000)
bus0.scan()
bus1 = I2C(1, scl=Pin("A1"), sda=Pin("A0"), freq=400_000)
bus1.scan()
Bemerkung
Zwei On-Board-Chips teilen sich Bus 0 — Benutzergeräte an diesem Bus müssen deren Adressen meiden:
0x6A— LSM6DSOX-IMU0x60— ATECC608A-MAHDA-T
Die Verwendung von A0/A1 als I²C belegt diese für den Bus, sodass sie nicht gleichzeitig als ADC-Eingänge dienen können.
Bemerkung
Die SDA/SCL-Pads (Bus 0) verfügen über On-Board-Pull-up-Widerstände auf 3,3 V, sodass für Geräte an diesem Bus keine externen Pull-ups erforderlich sind. A0/A1 (Bus 1) tun dies nicht — fügen Sie bei der Verwendung von Bus 1 externe Pull-ups hinzu.
Dieselbe Hardware kann über machine.I2CTarget auch im Target-Modus (Slave) verwendet werden, um einem anderen I²C-Controller einen Speicherbereich bereitzustellen:
from machine import I2CTarget
buf = bytearray(32)
target = I2CTarget(0, addr=0x42, mem=buf)
SPI¶
Bus |
MOSI |
MISO |
SCK |
CS |
|---|---|---|---|---|
SPI0 |
D11 |
D12 |
D13 |
D10 |
Der rp2-Port konfiguriert die Pins von SPI0 auf diesem Board nicht vor, übergeben Sie daher beim Erstellen des Busses die bedruckten Pads explizit:
from machine import SPI, Pin
spi = SPI(0, baudrate=10_000_000,
sck=Pin("D13"), mosi=Pin("D11"), miso=Pin("D12"))
cs = Pin("D10", Pin.OUT, value=1) # CS is not driven by the SPI peripheral
cs.value(0)
spi.write(b"hello")
cs.value(1)
Bemerkung
D13 fungiert gleichzeitig als orangefarbene LED_BUILTIN — das Ansteuern von SPI an diesem Bus lässt die LED im Takt des Bus-Clocks blinken.
Bemerkung
machine.SPI(1) existiert, ist aber für das On-Board-NINA-W102-Modul reserviert (die Wi-Fi/BLE-SPI-Verbindung); verwenden Sie es nicht direkt.
ADC¶
Der RP2040 hat vier 12-Bit-ADC-Kanäle, die an A0–A3 herausgeführt sind, alle auf 3,3 V referenziert — read_u16 liefert 0–65535 über den Bereich 0–3,3 V am Pin. Der AREF-Pin des Boards ist nicht verdrahtet, sodass die Referenz immer 3,3 V beträgt:
from machine import ADC
import time
adc = ADC("A0")
while True:
voltage = adc.read_u16() * 3.3 / 65535
print(voltage)
time.sleep_ms(100)
PWM¶
Pin |
Slice / Kanal |
|---|---|
TX |
PWM0 A |
RX |
PWM0 B |
D2 |
PWM4 B |
D3 |
PWM7 B |
D4 |
PWM0 A |
D5 |
PWM0 B |
D6 |
PWM1 A |
D7 |
PWM1 B |
D8 |
PWM2 A |
D9 |
PWM2 B |
D10 |
PWM2 B |
D11 |
PWM3 B |
D12 |
PWM2 A |
D13 |
PWM3 A |
D14 / A0 |
PWM5 A |
D15 / A1 |
PWM5 B |
D16 / A2 |
PWM6 A |
D17 / A3 |
PWM6 B |
D18 / A4 / SDA |
PWM6 A |
D19 / A5 / SCL |
PWM6 B |
Steuern Sie einen davon über machine.PWM an:
from machine import Pin, PWM
pwm = PWM(Pin("D3"), freq=1_000, duty_u16=32768)
Bemerkung
Mehrere Pins teilen sich PWM-Slice-Kanäle:
PWM0 A liegt an
TXundD4.PWM0 B liegt an
RXundD5.PWM2 A liegt an
D8undD12.PWM2 B liegt an
D9undD10.PWM6 A liegt an
D16/A2undD18/A4/SDA.PWM6 B liegt an
D17/A3undD19/A5/SCL.
Wählen Sie pro Slice-Kanal nur einen Verbraucher. Die Kanäle A und B innerhalb desselben Slice teilen sich ihre Periode (Frequenz), haben aber jeweils ihren eigenen Tastgrad.
Software-Bit-Banging-Busse¶
machine.SoftI2C und machine.SoftSPI funktionieren an jedem GPIO, falls Sie einen zusätzlichen Bus benötigen.
Thermalsensor (extern)¶
Die Firmware enthält den fir — Wärmesensortreiber (fir == far infrared)-Treiber für eine extern verdrahtete AMG8833-8×8-Wärmebildkamera. Verbinden Sie das Modul mit dem nachfolgend aufgeführten I²C-Bus und lesen Sie dann Einzelbilder mit fir.init() + fir.snapshot():
import time
import image
import fir
fir.init() # auto‑detects the sensor
clock = time.clock()
while True:
clock.tick()
try:
img = fir.snapshot(x_scale=5, y_scale=5,
color_palette=image.PALETTE_IRONBOW,
hint=image.BICUBIC,
copy_to_fb=True)
except OSError:
continue
print(clock.fps())
Der fir-Treiber kommuniziert mit dem Sensor nur über I²C 0 — verdrahten Sie das Modul mit den bedruckten SCL/SDA-Pads. Die 7-Bit-Adresse des Sensors (0x69) darf von keinem anderen Gerät an diesem Bus verwendet werden.
Zeitsteuerung¶
time¶
Das time-Modul deckt blockierende Verzögerungen, monotone Ticks und die Messung der verstrichenen Zeit ab:
import time
time.sleep(1) # seconds
time.sleep_ms(500)
time.sleep_us(10)
start = time.ticks_ms()
# ...do work...
elapsed = time.ticks_diff(time.ticks_ms(), start)
Virtuelle Timer¶
machine.Timer plant periodische oder einmalige Callbacks, ohne einen Hardware-Timer-Slot zu belegen. Übergeben Sie -1 als id, um einen virtuellen (Software-)Timer zu verwenden:
from machine import Timer
one_shot = Timer(-1)
one_shot.init(period=5_000, mode=Timer.ONE_SHOT,
callback=lambda t: print("once"))
periodic = Timer(-1)
periodic.init(period=2_000, mode=Timer.PERIODIC,
callback=lambda t: print("tick"))
Periodenwerte werden in Millisekunden angegeben. Rufen Sie deinit() auf, um den Slot zu stoppen und freizugeben.
Echtzeituhr¶
machine.RTC hält die Wanduhrzeit über Resets hinweg. Die RTC des RP2040 ist an den On-Chip-Oszillator gebunden und übersteht keinen vollständigen Stromausfall — stellen Sie die Zeit bei jedem Kaltstart ein, falls dies für Ihre Anwendung relevant ist:
from machine import RTC
rtc = RTC()
rtc.datetime((2026, 4, 30, 4, 12, 0, 0, 0)) # Y, M, D, weekday, h, m, s, subsec
print(rtc.datetime())
Watchdog¶
machine.WDT setzt das Board zurück, wenn die Anwendung hängt. Einmal gestartet, kann er nicht mehr gestoppt oder neu konfiguriert werden — füttern Sie ihn regelmäßig innerhalb Ihrer Hauptschleife:
from machine import WDT
wdt = WDT(timeout=5_000) # 5 second window
while True:
# ...do work...
wdt.feed()
Boot- und Laufzeitinformationen¶
Firmware-Update (UF2)¶
Der Nano RP2040 Connect verwendet den standardmäßigen Doppeltipp-Reset von Arduino, um den Arduino-Bootloader zu starten. Drücken Sie die Reset-Taste schnell zweimal — das Board meldet sich über USB erneut als UF2-Gerät an, und OpenMV IDE kann ein neues Firmware-Image flashen.
Ein laufendes Skript kann den Bootloader bei Bedarf erneut starten, indem es machine.bootloader() aufruft:
import machine
machine.bootloader()
Dateisystem und Boot-Reihenfolge¶
Die Firmware des Nano RP2040 Connect bindet beim Booten ein einziges Dateisystem ein:
Interner Flash — immer unter
/flasheingebunden und als Arbeitsverzeichnis verwendet. Enthält standardmäßigmain.pyundREADME.txt; wird beim allerersten Booten erstellt.
Nach dem Einbinden führt der Interpreter anschließend Skripte aus /flash aus:
boot.pywird bei jedem Soft-Reset ausgeführt.main.pywird nur beim Kaltstart ausgeführt, unmittelbar nachboot.py.
Die standardmäßige main.py, die auf einem frisch geflashten Board ausgeliefert wird, lässt lediglich den blauen Kanal der Benutzer-RGB-LED als Herzschlag blinken (zwei kurze Impulse, kurze Pause), sodass Sie auch ohne angeschlossenen Host erkennen können, dass die Firmware sauber gebootet ist.
Bei einer USB-Verbindung meldet sich /flash als USB-Massenspeicherlaufwerk auf dem Host an, sodass Sie boot.py, main.py und alle anderen Dateien direkt bearbeiten können. Werfen Sie das Laufwerk aus, bevor Sie das Board zurücksetzen, damit der Host seine zwischengespeicherten Schreibvorgänge leert.
Bemerkung
Da das Betriebssystem das Laufwerk als passives Blockgerät behandelt, werden Dateien, die von auf der Kamera laufendem Code erstellt oder geändert werden, erst angezeigt, wenn der Host das Laufwerk erneut einbindet. Wenn sowohl das Betriebssystem als auch die Kamera gleichzeitig dasselbe Dateisystem beschreiben, gewinnt das Betriebssystem und überschreibt die von der Kamera vorgenommenen Änderungen. Verwenden Sie die SD-Karte für alle Daten, die das Skript zurückschreibt, und binden Sie das Laufwerk erneut ein, bevor Sie diese Dateien vom Host aus lesen.
Bemerkung
Der rote Kanal der Benutzer-RGB-LED leuchtet möglicherweise kurz auf, während der Host vom USB-Massenspeicherlaufwerk liest oder darauf schreibt — dies ist eine firmwaregesteuerte Aktivitätsanzeige, kein Fehler.
Speichergrößen¶
Der Nano RP2040 Connect wird ausgeliefert mit:
/flash— 14 MB FAT-Dateisystem, Lesen/Schreiben.
Der Nano-RP2040-Build enthält kein ROMFS; liefern Sie Python-Module und ML-Modelle direkt auf /flash aus.
Software-Bibliotheken¶
Im Bibliotheksindex finden Sie die vollständige Liste der Module — einschließlich derjenigen, die ausschließlich im Nano-RP2040-Connect-Build enthalten sind.