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.

Arduino Nano RP2040 Connect

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, D2D13 (digital), A0A7 (analog).

Pinbelegung

Pinbelegung des Arduino Nano RP2040 Connect

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 D13

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 VIN gleichzeitig 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 REC beim 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 Namen RPI-RP2 an 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

D3

D1

D4

D2

D5

D3

D6

D4

D7

D5

D8

D6

D9

D7

D2

HSYNC

A1

VSYNC

A0

PXCLK

A3

MXCLK

A2

POWER

TX

RESET

RX

SCL

SDA (I²C 0)

SDA

SCL (I²C 0)

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

SDA / A4

SCL / A5

I2C1

A0

A1

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-IMU

  • 0x60 — 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 referenziertread_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 TX und D4.

  • PWM0 B liegt an RX und D5.

  • PWM2 A liegt an D8 und D12.

  • PWM2 B liegt an D9 und D10.

  • PWM6 A liegt an D16/A2 und D18/A4/SDA.

  • PWM6 B liegt an D17/A3 und D19/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 /flash eingebunden und als Arbeitsverzeichnis verwendet. Enthält standardmäßig main.py und README.txt; wird beim allerersten Booten erstellt.

Nach dem Einbinden führt der Interpreter anschließend Skripte aus /flash aus:

  • boot.py wird bei jedem Soft-Reset ausgeführt.

  • main.py wird nur beim Kaltstart ausgeführt, unmittelbar nach boot.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:

  • /flash14 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.