Arduino Nano 33 BLE Sense¶
Atenționare
Această placă nu mai este suportată. Ultima versiune de firmware OpenMV pentru Arduino Nano 33 BLE Sense este 4.7.0. Nu vor mai fi lansate actualizări de firmware, corectări de erori sau funcționalități noi pentru acest target. Informațiile de mai jos sunt păstrate pentru utilizatorii care rulează versiunea 4.7.0 sau anterioară.
Arduino Nano 33 BLE Sense este o placă de 45 × 18 mm în format Arduino‑Nano, construită în jurul circuitului Nordic Semiconductor nRF52840 — un singur ARM Cortex‑M4 cu FPU care rulează la 64 MHz, cu 256 KB de SRAM internă și 1 MB de memorie flash internă. BLE provine de la radioul integrat pe cip, iar placa include un IMU pe 9 axe, un barometru LPS22HB, un senzor de temperatură / umiditate HTS221 / HS3003, un senzor APDS9960 de lumină ambientală / culoare / proximitate / gesturi și un microfon PDM MP34DT05. Firmware-ul OpenMV controlează toate acestea din MicroPython.
Pentru fișa tehnică completă, fotografii și dimensiuni, consultați pagina de produs Arduino Nano 33 BLE Rev2.
Caracteristici principale¶
Nordic nRF52840 Cortex‑M4 cu FPU la 64 MHz, cu 256 KB SRAM internă și 1 MB memorie flash internă.
Bluetooth LE 5.0 prin radioul integrat pe cip și Nordic SoftDevice s140.
IMU pe 9 axe —
LSM9DS1pe Rev 1,BMI270+BMM150pe Rev 2. Driverul înghețatimule detectează pe ambele la pornire.Barometru
LPS22HB, senzor de temperatură și umiditateHTS221/HS3003, senzor de lumină ambientală / culoare / proximitate / gesturiAPDS9960și microfon PDM MP34DT05.Conector Micro USB pentru alimentare, programare și un REPL CDC.
22 de pini I/O de utilizator pe headerele Nano standard —
TX/RX,D2–D13(digitali),A0–A7(analogici).
Pinout¶
Referință pini¶
Nume pin |
Referință |
Funcție |
|---|---|---|
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 |
apăsați butonul RESET de pe placă sau conectați la GND pentru a reseta |
LED_BUILTIN |
— |
LED de utilizator portocaliu pe |
LED_RED |
— |
Canalul roșu al LED-ului RGB (activ pe nivel jos) |
LED_GREEN |
— |
Canalul verde al LED-ului RGB (activ pe nivel jos) |
LED_BLUE |
— |
Canalul albastru al LED-ului RGB (activ pe nivel jos) |
Atenționare
Pinii I/O ai plăcii Nano 33 BLE Sense sunt doar de 3.3 V — nu tolerează 5 V. Aplicarea a 5 V pe aceștia va deteriora circuitul nRF52840.
Pini de alimentare¶
VIN — intrare 4.5 – 21 V. Alimentează placa prin regulatorul de pe placă. Este alimentat și printr-o diodă de pe magistrala USB de 5 V, astfel încât USB și
VINpot fi prezente simultan fără a se influența reciproc.+5V — neconectat în mod implicit.
+3V3 — ieșirea regulatorului de 3.3 V.
AREF — pin de referință analogică. Nu este conectat la nRF52840 pe această placă — ADC-ul este întotdeauna raportat la 3.3 V.
GND — masa comună.
Placa Nano 33 BLE Sense poate fi alimentată pe oricare dintre căi:
Micro USB — furnizează 5 V regulatorului de pe placă.
Pinul VIN — aplicați o sursă regulată de 4.5 – 21 V.
Notă
Un jumper de lipire pe partea inferioară a plăcii, etichetat VUSB, conectează +5V la magistrala USB de 5 V. Închideți-l pentru ca pinul header +5V să transporte efectiv 5 V.
Notă
Un jumper de lipire în mod normal închis, aflat pe ieșirea regulatorului de comutație de 4.5–21 V de pe placă, poate fi tăiat pentru a dezactiva regulatorul, astfel încât placa să poată fi alimentată direct de la o sursă externă de 3.3 V pe +3V3.
Pini de recuperare și depanare¶
RESET — atât un pad expus, cât și un buton momentan RESET pe partea superioară a plăcii, conectate la linia de reset a nRF52840. Conectați la GND sau apăsați butonul pentru a reseta.
Placa Nano 33 BLE Sense folosește resetarea prin dublă apăsare standard Arduino pentru a intra în bootloaderul Arduino. Apăsați rapid butonul RESET de două ori — placa intră în modul bootloader, iar OpenMV IDE poate scrie o nouă imagine de firmware.
Semnalele SWD ale nRF52840 sunt expuse pe pad-uri placate pe spatele plăcii. Toate semnalele de depanare sunt raportate la 3.3 V.
Periferice de pe placă¶
LED-uri¶
Placa Nano 33 BLE Sense are un LED RGB de utilizator — controlat prin canalele LED_RED, LED_GREEN și LED_BLUE serigrafiate — plus un LED portocaliu separat LED_BUILTIN pe D13. Toate cele patru pot fi controlate prin software cu machine.LED
from machine import LED
LED("LED_RED").on()
LED("LED_GREEN").on()
LED("LED_BLUE").on()
LED("LED_BUILTIN").on()
Un LED verde separat de alimentare de pe placă se aprinde ori de câte ori magistrala de +3.3 V este activă și nu poate fi controlat de utilizator.
Senzor de cameră¶
Firmware-ul OpenMV de pe Nano 33 BLE Sense suportă senzorul CMOS paralel OmniVision OV7670. Placa nu are senzor de imagine pe placă — conectați un modul OV7670 la pinii header serigrafiați enumerați mai jos și controlați-l prin modulul csi — senzori de cameră
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()
Notă
OV7670 ocupă 14 pini. Firmware-ul îi conectează după cum urmează:
Semnal senzor |
Pin Nano 33 BLE Sense |
|---|---|
D0 |
|
D1 |
|
D2 |
|
D3 |
|
D4 |
|
D5 |
|
D6 |
|
D7 |
|
HSYNC |
|
VSYNC |
|
PXCLK |
|
MXCLK |
|
POWER |
|
RESET |
|
SCL |
|
SDA |
|
Magistrala de control I²C a OV7670 este aceeași magistrală externă I²C 0 expusă pe A5/A4. Senzorul se află la adresa pe 7 biți 0x21 — dispozitivele de utilizator de pe acea magistrală trebuie să evite această adresă atunci când camera este conectată.
IMU¶
IMU-ul pe 9 axe este expus prin modulul înghețat imu, care detectează automat dacă placa are LSM9DS1 (Rev 1) sau BMI270 + BMM150 (Rev 2) și prezintă o clasă unificată imu.IMU. Senzorii se află pe magistrala internă I²C 1 (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)
Pentru acces direct la funcții precum detectarea atingerilor sau FIFO, importați driverul înghețat corespunzător (lsm9ds1, bmi270 sau bmm150) și instanțiați-l pe aceeași magistrală.
Senzori de mediu¶
Barometrul (LPS22HB) și senzorul de temperatură / umiditate (HTS221 pe Rev 1, HS3003 pe Rev 2) partajează aceeași magistrală internă I²C 1 ca și IMU-ul:
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)
Lumină / culoare / proximitate / gesturi¶
Senzorul Broadcom APDS9960 se află pe aceeași magistrală internă I²C 1 și oferă detectarea luminii ambientale, a culorii RGB, a proximității și a gesturilor:
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)
Microfon¶
Microfonul PDM MP34DT05 de pe placă este capturat prin audio — Modulul Audio. Fiecare tampon sosește ca PCM bytearray pe 16 biți cu semn, gata pentru a fi transmis către ulab/numpy pentru 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¶
Radioul Bluetooth LE 5.0 al nRF52840 rulează pe Nordic SoftDevice s140 și este expus prin modulul moștenit ubluepy — API-urile moderne bluetooth / aioble — BLE asincron nu sunt activate în acest build. Sunt disponibile atât rolurile de periferic (server GATT, advertising), cât și de central (observator / scanner GAP + conectare).
Faceți advertising ca periferic cu un singur serviciu Environmental Sensing și o caracteristică de temperatură notificabilă — funcția de retroapelare (callback) event_handler se declanșează la conectare, deconectare și scrieri CCCD:
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])
Scanați dispozitivele care fac advertising în apropiere în rol de central:
from ubluepy import Scanner
for entry in Scanner().scan(1_000): # 1 second window
print(entry.addr(), entry.rssi(), "dBm")
Consultați referința ubluepy pentru API-ul complet — UUID, Service, Characteristic, Peripheral, Scanner, ScanEntry și spațiul de nume constants.
Referință magistrale¶
GPIO¶
Folosiți machine.Pin pentru a citi sau controla oricare dintre pinii serigrafiați. Ieșirile sunt CMOS de 3.3 V — 15 mA per pin, 25 mA în total pe toate GPIO-urile.
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())
Orice pin de intrare poate, de asemenea, declanșa o întrerupere la tranzițiile pe muchie:
def handler(pin):
print("triggered:", pin)
Pin("D3", Pin.IN, Pin.PULL_UP).irq(
handler, Pin.IRQ_FALLING | Pin.IRQ_RISING,
)
UART¶
Magistrală |
TX |
RX |
|---|---|---|
UART1 |
TX |
RX |
Folosiți numele serigrafiate TX/RX cu machine.UART
from machine import UART
uart = UART(1, baudrate=115200)
uart.write("hello")
uart.read(5)
I²C¶
Magistrală |
SDA |
SCL |
|---|---|---|
I2C0 |
|
|
I2C1 |
|
|
Ambele magistrale necesită ca pinii lor să fie transmiși explicit către 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()
Notă
Magistrala 1 este magistrala internă a senzorilor pe P14/P15 (nu pe headerele de utilizator) — deservește IMU-ul, barometrul, senzorul de mediu și APDS9960. Driverele înghețate ale senzorilor o folosesc direct; codul de utilizator o poate scana de asemenea, dar adresele sunt deja ocupate de senzorii de pe placă.
SPI¶
Magistrală |
MOSI |
MISO |
SCK |
CS |
|---|---|---|---|---|
SPI0 |
D11 |
D12 |
D13 |
D10 |
Linia CS nu este controlată de perifericul SPI — configurați D10 ca ieșire și comutați-l manual în jurul transferului:
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)
Notă
D13 funcționează totodată ca LED_BUILTIN portocaliu — controlul SPI pe această magistrală va face LED-ul să clipească în ritmul ceasului magistralei.
ADC¶
nRF52840 are opt canale ADC pe 12 biți (SAADC) expuse pe A0–A7, toate raportate la 3.3 V — read_u16 returnează 0–65535 pentru intervalul 0–3.3 V la pin. Pinul AREF al plăcii nu este conectat, deci referința este întotdeauna 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¶
nRF52840 expune patru periferice PWM (PWM0–PWM3), fiecare controlând patru canale, pentru un total de 16 sloturi PWM hardware. Spre deosebire de porturile cu funcție fixă, perifericele se rutează prin matricea GPIOTE — orice GPIO poate fi o ieșire PWM, deci nu există o mapare pin-la-slice. Costul acestei flexibilități constă în două constrângeri integrate în siliciu:
Toate cele patru canale dintr-un modul partajează o singură perioadă/frecvență.
Fiecare canal are propriul factor de umplere și polaritate.
Conceptual, cele 16 sloturi arată astfel:
Modul |
Ch 0 |
Ch 1 |
Ch 2 |
Ch 3 |
|---|---|---|---|---|
PWM0 |
factor de umplere |
factor de umplere |
factor de umplere |
factor de umplere |
PWM1 |
factor de umplere |
factor de umplere |
factor de umplere |
factor de umplere |
PWM2 |
factor de umplere |
factor de umplere |
factor de umplere |
factor de umplere |
PWM3 |
factor de umplere |
factor de umplere |
factor de umplere |
factor de umplere |
Fiecare rând rulează la o singură frecvență; cele patru celule dintr-un rând controlează fiecare un pin ales independent, cu propriul factor de umplere. Rândurile diferite pot rula la frecvențe complet diferite.
Controlați orice pin serigrafiat (sau LED-urile de pe placă) prin machine.PWM
from machine import Pin, PWM
pwm = PWM(Pin("D3"), freq=1_000, duty_u16=32768)
Atenționare
Alocarea automată consumă un modul întreg per apel. Când creați un PWM fără argumentele device=/channel=, driverul preia primul modul liber și leagă pinul dvs. doar la canalul 0 al acestuia. Celelalte trei canale ale acelui modul rămân inactive și pot fi accesate doar prin device=/channel= explicite. Acest lucru limitează apelurile PWM(Pin(...)) neasistate la patru înainte ca driverul să genereze ValueError: all PWM devices in use — chiar dacă douăsprezece sloturi sunt tehnic încă libere.
Pentru a folosi mai mult de patru PWM-uri sau pentru a partaja deliberat o frecvență între pini, transmiteți device (0–3) și channel (0–3):
# 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)
Factorul de umplere acceptă duty (0–100%), duty_u16 (0–65535) sau duty_ns. Adăugați invert=1 pentru a inversa polaritatea ieșirii (util pentru LED-ul RGB activ pe nivel jos).
Notă
Deoarece frecvența este o proprietate per modul, apelarea pwm.freq(new_freq) pe oricare canal al unui modul re-rulează nrfx_pwm_init pentru întregul modul și modifică frecvența percepută de fiecare alt canal care îl partajează.
Notă
Frecvențele permise acoperă aproximativ 4 Hz până la 5.3 MHz, derivate din ceasul de bază de 16 MHz cu prescalere 1/2/4/8/16/32/64/128 și un contor de perioadă pe 15 biți. Driverul alege automat divizorul cel mai apropiat — freq() raportează valoarea solicitată, nu pe cea exactă realizabilă.
Magistrale software bit-banged¶
machine.SoftI2C și machine.SoftSPI funcționează pe orice GPIO dacă aveți nevoie de o magistrală suplimentară.
Senzor termic (extern plăcii)¶
Firmware-ul include driverul fir — driver pentru senzori termici (fir == far infrared) pentru imagistici termice conectate extern:
MLX90621 — matrice IR 16 × 4
MLX90640 — matrice IR 32 × 24
MLX90641 — matrice IR 16 × 12
AMG8833 — matrice IR 8 × 8
Conectați modulul la magistrala I²C a plăcii și citiți cadre cu 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())
Driverul fir comunică cu senzorul doar prin I²C 0 — conectați modulul la pad-urile I2C_SCL / I2C_SDA (A5 / A4).
Temporizare¶
time¶
Modulul time acoperă întârzieri blocante, tick-uri monotone și măsurarea timpului scurs:
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)
Temporizatoare virtuale¶
machine.Timer programează funcții de retroapelare periodice sau unice fără a consuma un slot de temporizator hardware. Transmiteți -1 ca id pentru a folosi un temporizator virtual (software):
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"))
Valorile perioadei sunt exprimate în milisecunde. Apelați deinit() pentru a opri și a elibera slotul.
Ceas în timp real¶
machine.RTC menține ora curentă peste resetări. RTC-ul nRF52840 este legat de oscilatorul de pe cip și nu supraviețuiește unei pierderi totale de alimentare — setați ora la fiecare pornire la rece dacă acest lucru contează pentru aplicația dvs.:
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 resetează placa dacă aplicația se blochează. Odată pornit, nu poate fi oprit sau reconfigurat — alimentați-l periodic în interiorul buclei principale:
from machine import WDT
wdt = WDT(timeout=5_000) # 5 second window
while True:
# ...do work...
wdt.feed()
Informații despre pornire și execuție¶
Actualizare firmware¶
Placa Nano 33 BLE Sense folosește resetarea prin dublă apăsare standard Arduino pentru a intra în bootloaderul Arduino. Apăsați rapid butonul RESET de două ori — placa intră în modul bootloader, iar OpenMV IDE poate scrie o nouă imagine de firmware.
Un script în execuție poate re-intra în bootloader la cerere apelând machine.bootloader()
import machine
machine.bootloader()
Sistem de fișiere și ordinea de pornire¶
Firmware-ul Nano 33 BLE Sense montează un singur sistem de fișiere la pornire:
Memoria flash internă — montată întotdeauna la
/flashși folosită ca director de lucru. Conține în mod implicitmain.pyșiREADME.txt; creată la prima pornire.
După montare, interpretorul rulează apoi scripturile din /flash:
boot.pyeste executat la fiecare resetare soft.main.pyeste executat doar la pornirea la rece, imediat dupăboot.py.
Fișierul main.py implicit livrat pe o placă proaspăt scrisă doar face să clipească canalul albastru al LED-ului RGB de utilizator ca un puls de viață (două pulsuri scurte, pauză scurtă), astfel încât să puteți observa că firmware-ul a pornit corect fără niciun host atașat.
/flash nu este expus ca unitate de stocare în masă USB pe această placă.
Dimensiuni de stocare¶
Placa Nano 33 BLE Sense este livrată cu:
/flash— sistem de fișiere FAT de 64 KB, citire/scriere.
Build-ul Nano 33 BLE Sense nu include un ROMFS; livrați modulele Python direct pe /flash.
Biblioteci software¶
Consultați indexul bibliotecii pentru lista completă de module — inclusiv cele care sunt unice pentru build-ul Nano 33 BLE Sense.