Arduino Nano 33 BLE Sense¶
Waarschuwing
Dit board wordt niet langer ondersteund. De laatste OpenMV-firmwarerelease voor de Arduino Nano 33 BLE Sense is 4.7.0. Er worden geen verdere firmware-updates, bugfixes of nieuwe functies meer uitgebracht voor dit doel. De onderstaande informatie is bewaard gebleven voor gebruikers die 4.7.0 of eerder draaien.
De Arduino Nano 33 BLE Sense is een 45 × 18 mm board in Arduino-Nano-formfactor, gebouwd rond de Nordic Semiconductor nRF52840 — een enkele ARM Cortex‑M4 met FPU op 64 MHz met 256 KB intern SRAM en 1 MB intern flashgeheugen. BLE komt van de on‑die radio, en het board bevat een 9‑assige IMU, een LPS22HB-barometer, een HTS221 / HS3003 temperatuur- / vochtigheidssensor, een APDS9960 omgevingslicht- / kleur- / nabijheids- / gebarensensor, en een MP34DT05 PDM-microfoon. De OpenMV-firmware stuurt al deze aan vanuit MicroPython.
Voor het volledige datasheet, foto’s en afmetingen zie de productpagina van de Arduino Nano 33 BLE Rev2.
Hoogtepunten¶
Nordic nRF52840 Cortex‑M4 met FPU op 64 MHz met 256 KB intern SRAM en 1 MB intern flashgeheugen.
Bluetooth LE 5.0 via de on‑die radio en de Nordic SoftDevice s140.
9‑assige IMU —
LSM9DS1op Rev 1,BMI270+BMM150op Rev 2. De vastgelegdeimu-driver detecteert beide bij het opstarten.LPS22HB-barometer,HTS221/HS3003temperatuur- en vochtigheidssensor,APDS9960omgevingslicht- / kleur- / nabijheids- / gebarensensor, en MP34DT05 PDM-microfoon.Micro USB-connector voor voeding, programmeren en een CDC-REPL.
22 gebruikers-I/O-pinnen op de standaard Nano-headers —
TX/RX,D2–D13(digitaal),A0–A7(analoog).
Pinout¶
Pinreferentie¶
Pinnaam |
Referentie |
Functie |
|---|---|---|
TX |
3.3 V |
UART1 TX |
RX |
3.3 V |
UART1 RX |
D2 |
3.3 V |
PWM |
D3 |
3.3 V |
PWM |
D4 |
3.3 V |
PWM |
D5 |
3.3 V |
PWM |
D6 |
3.3 V |
PWM |
D7 |
3.3 V |
PWM |
D8 |
3.3 V |
PWM |
D9 |
3.3 V |
PWM |
D10 |
3.3 V |
PWM |
D11 |
3.3 V |
PWM / SPI0 MOSI |
D12 |
3.3 V |
PWM / SPI0 MISO |
D13 |
3.3 V |
PWM / SPI0 SCK |
A0 |
3.3 V |
ADC / PWM |
A1 |
3.3 V |
ADC / PWM |
A2 |
3.3 V |
ADC / PWM |
A3 |
3.3 V |
ADC / PWM |
A4 / I2C_SDA |
3.3 V |
ADC / PWM / I2C0 SDA |
A5 / I2C_SCL |
3.3 V |
ADC / PWM / I2C0 SCL |
A6 |
3.3 V |
ADC / PWM |
A7 |
3.3 V |
ADC / PWM |
RESET |
3.3 V |
druk op de RESET-knop op het board of trek naar GND om te resetten |
LED_BUILTIN |
— |
Oranje gebruikers-LED op |
LED_RED |
— |
Rood kanaal van de RGB-LED (actief laag) |
LED_GREEN |
— |
Groen kanaal van de RGB-LED (actief laag) |
LED_BLUE |
— |
Blauw kanaal van de RGB-LED (actief laag) |
Waarschuwing
De I/O-pinnen van de Nano 33 BLE Sense zijn uitsluitend 3.3 V — ze zijn niet 5 V-tolerant. Het aanleggen van 5 V op deze pinnen beschadigt de nRF52840.
Voedingspinnen¶
VIN — 4.5 – 21 V ingang. Voedt het board via de regelaar op het board. Wordt ook via een diode gevoed vanaf de USB 5 V-rail, zodat USB en
VINtegelijk aanwezig kunnen zijn zonder elkaar terug te voeden.+5V — standaard niet aangesloten.
+3V3 — uitgang van de 3.3 V-regelaar.
AREF — analoge referentiepin. Op dit board niet bedraad naar de nRF52840 — de ADC wordt altijd gerefereerd aan 3.3 V.
GND — gemeenschappelijke massa.
De Nano 33 BLE Sense kan via beide paden gevoed worden:
Micro USB — levert 5 V aan de regelaar op het board.
VIN-pin — leg een gestabiliseerde voeding van 4.5 – 21 V aan.
Notitie
Een soldeerbrug aan de onderkant van het board met het label VUSB verbindt +5V met de USB 5 V-rail. Sluit deze om de +5V-headerpin daadwerkelijk 5 V te laten voeren.
Notitie
Een normaal gesloten soldeerbrug op de uitgang van de 4.5–21 V-schakelregelaar op het board kan worden doorgesneden om de regelaar uit te schakelen, zodat het board rechtstreeks gevoed kan worden vanaf een externe 3.3 V-voeding op +3V3.
Herstel- en debugpinnen¶
RESET — zowel een blootliggende pad als een tijdelijke RESET-knop aan de bovenkant van het board, verbonden met de resetlijn van de nRF52840. Trek naar GND of druk op de knop om te resetten.
De Nano 33 BLE Sense gebruikt de standaard dubbele tik-reset van Arduino om de bootloader van Arduino te starten. Druk snel tweemaal op de RESET-knop — het board gaat in bootloadermodus en OpenMV IDE kan een nieuwe firmware-image flashen.
De SWD-signalen van de nRF52840 liggen blootliggend op vertinde pads aan de achterkant van het board. Alle debugsignalen zijn 3.3 V-gerefereerd.
Randapparaten op het board¶
LEDs¶
De Nano 33 BLE Sense heeft een RGB-gebruikers-LED — aangestuurd via de op de print gemarkeerde kanalen LED_RED, LED_GREEN en LED_BLUE — plus een aparte oranje LED_BUILTIN op D13. Alle vier zijn softwarematig bestuurbaar via machine.LED
from machine import LED
LED("LED_RED").on()
LED("LED_GREEN").on()
LED("LED_BLUE").on()
LED("LED_BUILTIN").on()
Een aparte groene power-LED op het board brandt zodra de +3.3 V-rail actief is en is niet door de gebruiker te besturen.
Camerasensor¶
De OpenMV-firmware op de Nano 33 BLE Sense ondersteunt de OmniVision OV7670 parallelle CMOS-sensor. Het board heeft geen ingebouwde beeldsensor — bedraad een OV7670-module naar de hieronder vermelde, op de print gemarkeerde headerpinnen en stuur deze aan via de csi — camerasensoren-module:
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()
Notitie
De OV7670 gebruikt 14 pinnen. De firmware bedraadt ze als volgt:
Sensorsignaal |
Nano 33 BLE Sense-pin |
|---|---|
D0 |
|
D1 |
|
D2 |
|
D3 |
|
D4 |
|
D5 |
|
D6 |
|
D7 |
|
HSYNC |
|
VSYNC |
|
PXCLK |
|
MXCLK |
|
POWER |
|
RESET |
|
SCL |
|
SDA |
|
De I²C-besturingsbus van de OV7670 is dezelfde externe I²C 0 die op A5/A4 is uitgevoerd. De sensor bevindt zich op het 7‑bits adres 0x21 — gebruikersapparaten op die bus moeten dit adres vermijden wanneer de camera is aangesloten.
IMU¶
De 9‑assige IMU wordt blootgesteld via de vastgelegde imu-module, die automatisch detecteert of het board de LSM9DS1 (Rev 1) of de BMI270 + BMM150 (Rev 2) heeft en een uniforme imu.IMU-klasse presenteert. De sensoren zitten op de interne I²C 1-bus (P14 / P15):
import time
from machine import I2C, Pin
from imu import IMU
bus = I2C(1, scl=Pin("P15"), sda=Pin("P14"))
sensor = IMU(bus)
while True:
print(sensor.accel()) # (x, y, z) in g
print(sensor.gyro()) # (x, y, z) in deg/s
print(sensor.magnet()) # (x, y, z) magnetometer
time.sleep_ms(100)
Voor directe toegang tot functies zoals tikdetectie of de FIFO, importeer de bijbehorende vastgelegde driver (lsm9ds1, bmi270 of bmm150) en instantieer deze op dezelfde bus.
Omgevingssensoren¶
De barometer (LPS22HB) en de temperatuur- / vochtigheidssensor (HTS221 op Rev 1, HS3003 op Rev 2) delen dezelfde interne I²C 1-bus als de IMU:
import time
from machine import I2C, Pin
from lps22h import LPS22H
from hts221 import HTS221
bus = I2C(1, scl=Pin("P15"), sda=Pin("P14"))
lps = LPS22H(bus)
try:
hts = HTS221(bus)
except OSError:
from hs3003 import HS3003
hts = HS3003(bus)
while True:
print("pressure: %.2f hPa" % lps.pressure())
print("temperature: %.2f C" % lps.temperature())
print("humidity: %.2f %%" % hts.humidity())
time.sleep_ms(500)
Licht / kleur / nabijheid / gebaren¶
De Broadcom APDS9960 zit op dezelfde interne I²C 1-bus en biedt detectie van omgevingslicht, RGB-kleur, nabijheid en gebaren:
import time
from machine import I2C, Pin
from apds9960 import uAPDS9960 as APDS9960
bus = I2C(1, scl=Pin("P15"), sda=Pin("P14"))
apds = APDS9960(bus)
apds.enableLightSensor()
while True:
print("ambient light:", apds.readAmbientLight())
time.sleep_ms(250)
Microfoon¶
De MP34DT05 PDM-microfoon op het board wordt vastgelegd via audio — Audio Module. Elke buffer komt binnen als signed‑16‑bits PCM-bytearray, klaar om in te voeren in ulab/numpy voor DSP:
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
Bluetooth¶
De Bluetooth LE 5.0-radio van de nRF52840 draait op de Nordic SoftDevice s140 en wordt blootgesteld via de verouderde ubluepy-module — de moderne bluetooth / aioble — Async BLE-API’s zijn niet ingeschakeld in deze build. Zowel de rol peripheral (GATT-server, adverteren) als central (GAP-observer / scanner + verbinden) zijn beschikbaar.
Adverteer als peripheral met een enkele Environmental Sensing-service en een notificeerbaar temperatuurkenmerk — de event_handler-callback wordt geactiveerd bij verbinden, verbreken en CCCD-writes:
from ubluepy import Service, Characteristic, UUID, Peripheral, constants
from machine import LED
def event_handler(event_id, handle, data):
if event_id == constants.EVT_GAP_CONNECTED:
LED("LED_GREEN").on()
elif event_id == constants.EVT_GAP_DISCONNECTED:
LED("LED_GREEN").off()
periph.advertise(device_name="Nano 33", services=[svc])
svc = Service(UUID("181A")) # Environmental Sensing
char = Characteristic(UUID("2A6E"), # Temperature
props=Characteristic.PROP_NOTIFY | Characteristic.PROP_READ,
attrs=Characteristic.ATTR_CCCD)
svc.addCharacteristic(char)
periph = Peripheral()
periph.addService(svc)
periph.setConnectionHandler(event_handler)
periph.advertise(device_name="Nano 33", services=[svc])
Scan in central-rol naar nabijgelegen adverterende apparaten:
from ubluepy import Scanner
for entry in Scanner().scan(1_000): # 1 second window
print(entry.addr(), entry.rssi(), "dBm")
Zie de ubluepy-referentie voor de volledige API — UUID, Service, Characteristic, Peripheral, Scanner, ScanEntry, en de constants-namespace.
Busreferentie¶
GPIO¶
Gebruik machine.Pin om een van de op de print gemarkeerde pinnen te lezen of aan te sturen. Uitgangen zijn 3.3 V CMOS — 15 mA per pin, 25 mA totaal over alle GPIO’s.
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())
Elke ingangspin kan ook een interrupt activeren bij flankovergangen:
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 |
|---|---|---|
UART1 |
TX |
RX |
Gebruik de printnamen TX/RX met machine.UART
from machine import UART
uart = UART(1, baudrate=115200)
uart.write("hello")
uart.read(5)
I²C¶
Bus |
SDA |
SCL |
|---|---|---|
I2C0 |
|
|
I2C1 |
|
|
Beide bussen vereisen dat hun pinnen expliciet worden doorgegeven aan machine.I2C
from machine import I2C, Pin
bus0 = I2C(0, scl=Pin("I2C_SCL"), sda=Pin("I2C_SDA"), freq=400_000)
bus0.scan()
bus1 = I2C(1, scl=Pin("P15"), sda=Pin("P14"), freq=400_000)
bus1.scan()
Notitie
Bus 1 is de interne sensorbus op P14/P15 (niet op de gebruikers-headers) — deze bedient de IMU, barometer, omgevingssensor en APDS9960. De vastgelegde sensordrivers gebruiken deze rechtstreeks; gebruikerscode kan deze ook scannen, maar de adressen zijn al in gebruik door de sensoren op het board.
SPI¶
Bus |
MOSI |
MISO |
SCK |
CS |
|---|---|---|---|---|
SPI0 |
D11 |
D12 |
D13 |
D10 |
De CS-lijn wordt niet aangestuurd door het SPI-randapparaat — configureer D10 als uitgang en schakel deze handmatig rond de overdracht:
from machine import SPI, Pin
spi = SPI(0, baudrate=10_000_000)
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)
Notitie
D13 fungeert tevens als de oranje LED_BUILTIN — het aansturen van SPI op deze bus laat de LED knipperen op het ritme van de busklok.
ADC¶
De nRF52840 heeft acht 12‑bits ADC-kanalen (SAADC) uitgevoerd op A0–A7, alle 3.3 V-gerefereerd — read_u16 retourneert 0–65535 over 0–3.3 V op de pin. De AREF-pin van het board is niet bedraad, dus de referentie is altijd 3.3 V:
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¶
De nRF52840 stelt vier PWM-randapparaten beschikbaar (PWM0–PWM3), die elk vier kanalen aansturen, voor in totaal 16 hardware-PWM-slots. Anders dan bij poorten met vaste functie lopen de randapparaten via de GPIOTE-matrix — elke GPIO kan een PWM-uitgang zijn, dus er is geen pin-naar-slice-toewijzing. De prijs van die flexibiliteit zijn twee in het silicium ingebakken beperkingen:
Alle vier kanalen binnen een module delen een enkele periode/frequentie.
Elk kanaal heeft zijn eigen duty cycle en polariteit.
Conceptueel zien de 16 slots er zo uit:
Module |
Kn 0 |
Kn 1 |
Kn 2 |
Kn 3 |
|---|---|---|---|---|
PWM0 |
duty |
duty |
duty |
duty |
PWM1 |
duty |
duty |
duty |
duty |
PWM2 |
duty |
duty |
duty |
duty |
PWM3 |
duty |
duty |
duty |
duty |
Elke rij draait op één frequentie; de vier cellen in een rij sturen elk een onafhankelijk gekozen pin aan met een eigen duty cycle. Verschillende rijen kunnen op volledig verschillende frequenties draaien.
Stuur een willekeurige op de print gemarkeerde pin (of de LED’s op het board) aan via machine.PWM
from machine import Pin, PWM
pwm = PWM(Pin("D3"), freq=1_000, duty_u16=32768)
Waarschuwing
Automatische toewijzing verbruikt een hele module per aanroep. Wanneer u een PWM aanmaakt zonder de kwargs device=/channel=, pakt de driver de eerste vrije module en bindt uw pin alleen aan diens kanaal 0. De overige drie kanalen van die module blijven ongebruikt en zijn alleen bereikbaar via expliciete device=/channel=. Dat beperkt ongeholpen PWM(Pin(...))-aanroepen tot vier voordat de driver ValueError: all PWM devices in use opwerpt — ook al zijn er technisch nog twaalf slots vrij.
Om meer dan vier PWM’s te gebruiken, of om bewust een frequentie te delen over pinnen, geeft u device (0–3) en channel (0–3) door:
# Two PWMs on the same module → forced to share frequency,
# but each gets its own duty cycle.
pwm_a = PWM(Pin("D3"), device=0, channel=0,
freq=1_000, duty_u16=32768)
pwm_b = PWM(Pin("D5"), device=0, channel=1,
freq=1_000, duty_u16=16384)
# A third PWM on a separate module, free to pick any frequency.
pwm_c = PWM(Pin("D6"), device=1, channel=0,
freq=20_000, duty_u16=49152)
Duty cycle accepteert duty (0–100%), duty_u16 (0–65535) of duty_ns. Voeg invert=1 toe om de uitgangspolariteit om te keren (handig voor de actief-lage RGB-LED).
Notitie
Omdat frequentie een eigenschap per module is, zorgt het aanroepen van pwm.freq(new_freq) op een willekeurig kanaal van een module ervoor dat nrfx_pwm_init voor de hele module opnieuw wordt uitgevoerd en de frequentie verandert die elk ander kanaal dat de module deelt waarneemt.
Notitie
Toegestane frequenties bestrijken ruwweg 4 Hz tot 5.3 MHz, afgeleid van de basisklok van 16 MHz met prescalers 1/2/4/8/16/32/64/128 en een 15‑bits periodeteller. De driver kiest automatisch de dichtstbijzijnde deler — freq() rapporteert de gevraagde waarde, niet de exact haalbare.
Softwarematig bit-banged bussen¶
machine.SoftI2C en machine.SoftSPI werken op elke GPIO als u een extra bus nodig hebt.
Thermische sensor (extern)¶
De firmware bevat de fir — thermische sensor-driver (fir == far infrared)-driver voor extern bedrade thermische beeldsensoren:
MLX90621 — 16 × 4 IR-array
MLX90640 — 32 × 24 IR-array
MLX90641 — 16 × 12 IR-array
AMG8833 — 8 × 8 IR-array
Bedraad de module naar de I²C-bus van het board en lees frames met 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())
De fir-driver communiceert alleen met de sensor via I²C 0 — bedraad de module naar de I2C_SCL / I2C_SDA-pads (A5 / A4).
Timing¶
time¶
De time-module behandelt blokkerende vertragingen, monotone ticks en het meten van verstreken tijd:
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)
Virtuele timers¶
machine.Timer plant periodieke of eenmalige callbacks zonder een hardware-timerslot te verbruiken. Geef -1 door als id om een virtuele (software-)timer te gebruiken:
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"))
Periodewaarden zijn in milliseconden. Roep deinit() aan om te stoppen en het slot vrij te geven.
Real-time klok¶
machine.RTC houdt de kloktijd bij over resets heen. De RTC van de nRF52840 is verbonden met de on‑chip oscillator en overleeft volledig spanningsverlies niet — stel de tijd in bij elke koude start als dat belangrijk is voor uw toepassing:
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 reset het board als de toepassing vastloopt. Eenmaal gestart kan deze niet worden gestopt of geherconfigureerd — voed hem periodiek binnen uw hoofdlus:
from machine import WDT
wdt = WDT(timeout=5_000) # 5 second window
while True:
# ...do work...
wdt.feed()
Boot- en runtime-informatie¶
Firmware-update¶
De Nano 33 BLE Sense gebruikt de standaard dubbele tik-reset van Arduino om de bootloader van Arduino te starten. Druk snel tweemaal op de RESET-knop — het board gaat in bootloadermodus en OpenMV IDE kan een nieuwe firmware-image flashen.
Een draaiend script kan op verzoek opnieuw de bootloader binnengaan door machine.bootloader() aan te roepen:
import machine
machine.bootloader()
Bestandssysteem en bootvolgorde¶
De firmware van de Nano 33 BLE Sense koppelt bij het opstarten één bestandssysteem:
Intern flashgeheugen — altijd gekoppeld op
/flashen gebruikt als werkmap. Bevat standaardmain.pyenREADME.txt; aangemaakt bij de allereerste boot.
Na het koppelen draait de interpreter vervolgens scripts vanaf /flash:
boot.pywordt uitgevoerd bij elke soft reset.main.pywordt alleen bij een koude start uitgevoerd, direct naboot.py.
De standaard main.py die op een vers geflasht board wordt geleverd, laat alleen het blauwe kanaal van de RGB-gebruikers-LED knipperen als hartslag (twee korte pulsen, korte pauze), zodat u kunt zien dat de firmware schoon is opgestart zonder dat er een host is aangesloten.
/flash wordt op dit board niet beschikbaar gesteld als USB-massaopslagschijf.
Opslaggroottes¶
De Nano 33 BLE Sense wordt geleverd met:
/flash— 64 KB FAT-bestandssysteem, lezen/schrijven.
De build van de Nano 33 BLE Sense bevat geen ROMFS; lever Python-modules rechtstreeks op /flash.
Softwarebibliotheken¶
Zie de bibliotheekindex voor de volledige lijst met modules — inclusief welke uniek zijn voor de build van de Nano 33 BLE Sense.