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.

Arduino Nano 33 BLE Sense

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 axeLSM9DS1 pe Rev 1, BMI270 + BMM150 pe Rev 2. Driverul înghețat imu le detectează pe ambele la pornire.

  • Barometru LPS22HB, senzor de temperatură și umiditate HTS221 / HS3003, senzor de lumină ambientală / culoare / proximitate / gesturi APDS9960 ș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, D2D13 (digitali), A0A7 (analogici).

Pinout

Pinout Arduino Nano 33 BLE Sense

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 D13

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 Vnu 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 VIN pot 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

D10

D1

TX

D2

RX

D3

D2

D4

D3

D5

D5

D6

D6

D7

D4

HSYNC

A1

VSYNC

D8

PXCLK

A0

MXCLK

D9

POWER

A3

RESET

A2

SCL

A5 (I²C 0)

SDA

A4 (I²C 0)

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

I2C_SDA / A4

I2C_SCL / A5

I2C1

P14

P15

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 Vread_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 (PWM0PWM3), 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 implicit main.py și README.txt; creată la prima pornire.

După montare, interpretorul rulează apoi scripturile din /flash:

  • boot.py este executat la fiecare resetare soft.

  • main.py este 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.