Arduino Nano 33 BLE Sense

Avertissement

Cette carte n’est plus prise en charge. La dernière version du micrologiciel OpenMV pour l’Arduino Nano 33 BLE Sense est la 4.7.0. Aucune mise à jour du micrologiciel, correction de bogue ou nouvelle fonctionnalité ne sera publiée pour cette cible. Les informations ci-dessous sont conservées pour les utilisateurs exécutant la version 4.7.0 ou antérieure.

L’Arduino Nano 33 BLE Sense est une carte de 45 × 18 mm au format Arduino-Nano construite autour du Nordic Semiconductor nRF52840 — un unique ARM Cortex-M4 avec FPU cadencé à 64 MHz, doté de 256 Ko de SRAM interne et de 1 Mo de mémoire flash interne. Le BLE provient de la radio intégrée à la puce, et la carte embarque une centrale inertielle 9 axes, un baromètre LPS22HB, un capteur de température / humidité HTS221 / HS3003, un capteur de lumière ambiante / couleur / proximité / gestes APDS9960 et un microphone PDM MP34DT05. Le micrologiciel OpenMV pilote tous ces éléments depuis MicroPython.

Arduino Nano 33 BLE Sense

Pour la fiche technique complète, les photos et les dimensions, consultez la page produit Arduino Nano 33 BLE Rev2.

Points forts

  • Nordic nRF52840 Cortex-M4 avec FPU à 64 MHz, doté de 256 Ko de SRAM interne et de 1 Mo de mémoire flash interne.

  • Bluetooth LE 5.0 via la radio intégrée à la puce et la Nordic SoftDevice s140.

  • Centrale inertielle 9 axesLSM9DS1 sur la Rev 1, BMI270 + BMM150 sur la Rev 2. Le pilote imu figé détecte les deux au démarrage.

  • Baromètre LPS22HB, capteur de température et d’humidité HTS221 / HS3003, capteur de lumière ambiante / couleur / proximité / gestes APDS9960 et microphone PDM MP34DT05.

  • Connecteur Micro USB pour l’alimentation, la programmation et un REPL CDC.

  • 22 broches d’E/S utilisateur sur les connecteurs Nano standard — TX/RX, D2D13 (numériques), A0A7 (analogiques).

Brochage

Brochage de l'Arduino Nano 33 BLE Sense

Référence des broches

Nom de la broche

Référence

Fonction

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

appuyez sur le bouton RESET intégré ou tirez vers GND pour réinitialiser

LED_BUILTIN

LED utilisateur orange sur D13

LED_RED

Canal rouge de la LED RGB (actif à l’état bas)

LED_GREEN

Canal vert de la LED RGB (actif à l’état bas)

LED_BLUE

Canal bleu de la LED RGB (actif à l’état bas)

Avertissement

Les broches d’E/S de la Nano 33 BLE Sense sont uniquement en 3,3 V — elles ne tolèrent pas le 5 V. Y injecter du 5 V endommagera le nRF52840.

Broches d’alimentation

  • VIN — entrée 4,5 – 21 V. Alimente la carte via le régulateur intégré. Également alimentée via une diode depuis le rail USB 5 V, de sorte que l’USB et VIN peuvent être présents simultanément sans se réinjecter mutuellement du courant.

  • +5V — non connectée par défaut.

  • +3V3 — sortie du régulateur 3,3 V.

  • AREF — broche de référence analogique. Non câblée au nRF52840 sur cette carte — l’ADC est toujours référencé à 3,3 V.

  • GND — masse commune.

La Nano 33 BLE Sense peut être alimentée par l’une ou l’autre de ces voies :

  • Micro USB — fournit 5 V au régulateur intégré.

  • Broche VIN — appliquez une alimentation régulée de 4,5 – 21 V.

Note

Un cavalier à souder sous la carte, étiqueté VUSB, relie +5V au rail USB 5 V. Fermez-le pour que la broche +5V du connecteur transporte effectivement le 5 V.

Note

Un cavalier à souder normalement fermé, placé sur la sortie du régulateur à découpage 4,5–21 V intégré, peut être coupé pour désactiver le régulateur, ce qui permet d’alimenter la carte directement depuis une alimentation externe 3,3 V sur +3V3.

Broches de récupération et de débogage

  • RESET — à la fois un plot exposé et un bouton RESET momentané sur le dessus de la carte, reliés à la ligne de réinitialisation du nRF52840. Tirez vers GND ou appuyez sur le bouton pour réinitialiser.

La Nano 33 BLE Sense utilise le double appui sur RESET standard d’Arduino pour entrer dans le programme d’amorçage d’Arduino. Appuyez rapidement deux fois sur le bouton RESET — la carte entre en mode programme d’amorçage et OpenMV IDE peut flasher une nouvelle image de micrologiciel.

Les signaux SWD du nRF52840 sont exposés sur des plots cuivrés à l’arrière de la carte. Tous les signaux de débogage sont référencés à 3,3 V.

Périphériques intégrés

LED

La Nano 33 BLE Sense dispose d’une LED RGB utilisateur — pilotée via les canaux sérigraphiés LED_RED, LED_GREEN et LED_BLUE — ainsi que d’une LED LED_BUILTIN orange distincte sur D13. Toutes les quatre sont contrôlables par logiciel via machine.LED

from machine import LED

LED("LED_RED").on()
LED("LED_GREEN").on()
LED("LED_BLUE").on()
LED("LED_BUILTIN").on()

Une LED d’alimentation verte distincte sur la carte s’allume dès que le rail +3,3 V est actif et n’est pas contrôlable par l’utilisateur.

Capteur de caméra

Le micrologiciel OpenMV sur la Nano 33 BLE Sense prend en charge le capteur CMOS parallèle OmniVision OV7670. La carte ne dispose d’aucun capteur d’image intégré — câblez un module OV7670 sur les broches sérigraphiées du connecteur listées ci-dessous et pilotez-le via le module csi — capteurs de caméra

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()

Note

L’OV7670 utilise 14 broches. Le micrologiciel les câble comme suit :

Signal du capteur

Broche 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)

Le bus de contrôle I²C de l’OV7670 est le même I²C 0 externe exposé sur A5/A4. Le capteur se trouve à l’adresse 7 bits 0x21 — les périphériques utilisateur sur ce bus doivent éviter cette adresse lorsque la caméra est câblée.

IMU

La centrale inertielle 9 axes est exposée via le module figé imu, qui détecte automatiquement si la carte possède le LSM9DS1 (Rev 1) ou le BMI270 + BMM150 (Rev 2) et présente une classe imu.IMU unifiée. Les capteurs se trouvent sur le bus I²C 1 interne (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)

Pour un accès direct à des fonctionnalités telles que la détection de tapotement ou la FIFO, importez le pilote figé correspondant (lsm9ds1, bmi270 ou bmm150) et instanciez-le sur le même bus.

Capteurs environnementaux

Le baromètre (LPS22HB) et le capteur de température / humidité (HTS221 sur la Rev 1, HS3003 sur la Rev 2) partagent le même bus I²C 1 interne que la centrale inertielle

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)

Lumière / couleur / proximité / gestes

Le APDS9960 de Broadcom se trouve sur le même bus I²C 1 interne et assure la détection de lumière ambiante, de couleur RGB, de proximité et de gestes

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)

Microphone

Le microphone PDM MP34DT05 intégré est capturé via audio — Module Audio. Chaque tampon arrive sous forme de PCM signé 16 bits dans un bytearray, prêt à être transmis à ulab/numpy pour le traitement du signal

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

La radio Bluetooth LE 5.0 du nRF52840 fonctionne sur la Nordic SoftDevice s140 et est exposée via le module hérité ubluepy — les API modernes bluetooth / aioble — BLE asynchrone ne sont pas activées dans cette version. Les rôles périphérique (serveur GATT, diffusion) et central (observateur / scanner GAP + connexion) sont tous deux disponibles.

Diffusez en tant que périphérique avec un unique service Environmental Sensing et une caractéristique de température notifiable — la fonction de rappel event_handler se déclenche lors de la connexion, de la déconnexion et des écritures 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])

Recherchez les appareils diffusant à proximité en rôle central

from ubluepy import Scanner

for entry in Scanner().scan(1_000):                  # 1 second window
    print(entry.addr(), entry.rssi(), "dBm")

Consultez la référence ubluepy pour l’API complète — UUID, Service, Characteristic, Peripheral, Scanner, ScanEntry, et l’espace de noms des constantes.

Référence des bus

GPIO

Utilisez machine.Pin pour lire ou piloter n’importe laquelle des broches sérigraphiées. Les sorties sont en CMOS 3,3 V — 15 mA par broche, 25 mA au total sur l’ensemble des GPIO.

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())

Toute broche d’entrée peut aussi déclencher une interruption sur les transitions de front

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

Utilisez les noms sérigraphiés TX/RX avec machine.UART

from machine import UART

uart = UART(1, baudrate=115200)
uart.write("hello")
uart.read(5)

I²C

Bus

SDA

SCL

I2C0

I2C_SDA / A4

I2C_SCL / A5

I2C1

P14

P15

Les deux bus nécessitent que leurs broches soient passées explicitement à 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()

Note

Le bus 1 est le bus de capteurs interne sur P14/P15 (pas sur les connecteurs utilisateur) — il dessert la centrale inertielle, le baromètre, le capteur environnemental et l’APDS9960. Les pilotes de capteurs figés l’utilisent directement ; le code utilisateur peut aussi le scanner, mais les adresses sont déjà occupées par les capteurs intégrés.

SPI

Bus

MOSI

MISO

SCK

CS

SPI0

D11

D12

D13

D10

La ligne CS n’est pas pilotée par le périphérique SPI — configurez D10 en sortie et basculez-la manuellement autour du transfert

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)

Note

D13 fait aussi office de LED_BUILTIN orange — piloter le SPI sur ce bus fera clignoter la LED au rythme de l’horloge du bus.

ADC

Le nRF52840 dispose de huit canaux ADC 12 bits (SAADC) exposés sur A0–A7, tous référencés à 3,3 Vread_u16 renvoie 0–65535 sur la plage 0–3,3 V à la broche. La broche AREF de la carte n’est pas câblée, la référence est donc toujours de 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

Le nRF52840 expose quatre périphériques PWM (PWM0PWM3), pilotant chacun quatre canaux, soit 16 emplacements PWM matériels au total. Contrairement aux ports à fonction fixe, ces périphériques sont routés via la matrice GPIOTE — n’importe quel GPIO peut être une sortie PWM, il n’y a donc pas de correspondance broche-vers-tranche. Le prix de cette flexibilité tient à deux contraintes gravées dans le silicium :

  • Les quatre canaux d’un même module partagent une période/fréquence unique.

  • Chaque canal a son propre rapport cyclique et sa propre polarité.

Conceptuellement, les 16 emplacements se présentent ainsi :

Module

Canal 0

Canal 1

Canal 2

Canal 3

PWM0

rapport cyclique

rapport cyclique

rapport cyclique

rapport cyclique

PWM1

rapport cyclique

rapport cyclique

rapport cyclique

rapport cyclique

PWM2

rapport cyclique

rapport cyclique

rapport cyclique

rapport cyclique

PWM3

rapport cyclique

rapport cyclique

rapport cyclique

rapport cyclique

Chaque ligne fonctionne à une seule fréquence ; les quatre cellules d’une ligne pilotent chacune une broche choisie indépendamment avec son propre rapport cyclique. Des lignes différentes peuvent fonctionner à des fréquences totalement différentes.

Pilotez n’importe quelle broche sérigraphiée (ou les LED intégrées) via machine.PWM

from machine import Pin, PWM

pwm = PWM(Pin("D3"), freq=1_000, duty_u16=32768)

Avertissement

L’allocation automatique consomme un module entier par appel. Lorsque vous créez un PWM sans les arguments nommés device=/channel=, le pilote saisit le premier module libre et lie votre broche à son canal 0 uniquement. Les trois canaux restants de ce module restent inactifs et ne sont accessibles que via device=/channel= explicites. Cela limite les appels PWM(Pin(...)) non assistés à quatre avant que le pilote ne lève ValueError: all PWM devices in use — alors même que douze emplacements sont techniquement encore libres.

Pour utiliser plus de quatre PWM, ou pour partager délibérément une fréquence entre plusieurs broches, passez device (0–3) et 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)

Le rapport cyclique accepte duty (0–100 %), duty_u16 (0–65535) ou duty_ns. Ajoutez invert=1 pour inverser la polarité de la sortie (pratique pour la LED RGB active à l’état bas).

Note

Comme la fréquence est une propriété propre au module, appeler pwm.freq(new_freq) sur n’importe quel canal d’un module relance nrfx_pwm_init pour l’ensemble du module et modifie la fréquence vue par tous les autres canaux qui le partagent.

Note

Les fréquences autorisées s’étendent à peu près de 4 Hz à 5,3 MHz, dérivées de l’horloge de base de 16 MHz avec des prédiviseurs 1/2/4/8/16/32/64/128 et un compteur de période 15 bits. Le pilote choisit automatiquement le diviseur le plus proche — freq() indique la valeur demandée, et non la valeur exacte réellement atteignable.

Bus émulés logiciellement (bit-banging)

machine.SoftI2C et machine.SoftSPI fonctionnent sur n’importe quel GPIO si vous avez besoin d’un bus supplémentaire.

Capteur thermique (externe)

Le micrologiciel inclut le pilote fir — pilote de capteur thermique (fir == infrarouge lointain) pour les imageurs thermiques câblés en externe :

  • MLX90621 — matrice IR 16 × 4

  • MLX90640 — matrice IR 32 × 24

  • MLX90641 — matrice IR 16 × 12

  • AMG8833 — matrice IR 8 × 8

Câblez le module au bus I²C de la carte et lisez les trames avec 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())

Le pilote fir ne communique avec le capteur que via l”I²C 0 — câblez le module sur les plots I2C_SCL / I2C_SDA (A5 / A4).

Temporisation

time

Le module time couvre les délais bloquants, les tics monotones et la mesure du temps écoulé

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)

Minuteurs virtuels

machine.Timer planifie des fonctions de rappel périodiques ou ponctuelles sans consommer d’emplacement de minuteur matériel. Passez -1 comme id pour utiliser un minuteur virtuel (logiciel)

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"))

Les valeurs de période sont en millisecondes. Appelez deinit() pour arrêter et libérer l’emplacement.

Horloge temps réel

machine.RTC conserve l’heure murale à travers les réinitialisations. Le RTC du nRF52840 est lié à l’oscillateur intégré à la puce et ne survit pas à une coupure totale d’alimentation — réglez l’heure à chaque démarrage à froid si cela importe pour votre application

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())

Chien de garde

machine.WDT réinitialise la carte si l’application se bloque. Une fois démarré, il ne peut être ni arrêté ni reconfiguré — alimentez-le périodiquement à l’intérieur de votre boucle principale

from machine import WDT

wdt = WDT(timeout=5_000)   # 5 second window
while True:
    # ...do work...
    wdt.feed()

Informations de démarrage et d’exécution

Mise à jour du micrologiciel

La Nano 33 BLE Sense utilise le double appui sur RESET standard d’Arduino pour entrer dans le programme d’amorçage d’Arduino. Appuyez rapidement deux fois sur le bouton RESET — la carte entre en mode programme d’amorçage et OpenMV IDE peut flasher une nouvelle image de micrologiciel.

Un script en cours d’exécution peut réentrer dans le programme d’amorçage à la demande en appelant machine.bootloader()

import machine

machine.bootloader()

Système de fichiers et ordre de démarrage

Le micrologiciel de la Nano 33 BLE Sense monte un seul système de fichiers au démarrage :

  • Mémoire flash interne — toujours montée sur /flash et utilisée comme répertoire de travail. Contient main.py et README.txt par défaut ; créée lors du tout premier démarrage.

Après le montage, l’interpréteur exécute alors les scripts depuis /flash :

  • boot.py est exécuté à chaque réinitialisation logicielle.

  • main.py est exécuté uniquement au démarrage à froid, immédiatement après boot.py.

Le main.py par défaut livré sur une carte fraîchement flashée se contente de faire clignoter le canal bleu de la LED RGB utilisateur comme battement de cœur (deux brèves impulsions, court intervalle), ce qui permet de savoir que le micrologiciel a démarré proprement sans aucun hôte connecté.

/flash n’est pas exposé comme lecteur de stockage de masse USB sur cette carte.

Tailles de stockage

La Nano 33 BLE Sense est livrée avec :

  • /flash — système de fichiers FAT de 64 Ko, en lecture/écriture.

La version pour la Nano 33 BLE Sense n’inclut pas de ROMFS ; déployez les modules Python directement sur /flash.

Bibliothèques logicielles

Consultez l”index de la bibliothèque pour la liste complète des modules — y compris ceux qui sont propres à la version pour la Nano 33 BLE Sense.