Arduino Nano 33 BLE Sense¶
Попередження
Ця плата більше не підтримується. Остання версія мікропрограми OpenMV для Arduino Nano 33 BLE Sense — 4.7.0. Для цієї цілі більше не буде виходити оновлень мікропрограми, виправлень помилок або нових функцій. Наведена нижче інформація збережена для користувачів, які використовують версію 4.7.0 або більш ранні.
Arduino Nano 33 BLE Sense — це плата формфактору Arduino Nano розміром 45 × 18 мм, побудована на основі Nordic Semiconductor nRF52840 — одноядерного ARM Cortex‑M4 з FPU, що працює на частоті 64 МГц із 256 КБ внутрішньої SRAM та 1 МБ внутрішньої флеш-пам’яті. Зв’язок Bluetooth забезпечується вбудованим радіомодулем; плата також оснащена 9-осьовим IMU, барометром LPS22HB, датчиком температури та вологості HTS221/HS3003, датчиком освітленості/кольору/наближення/жестів APDS9960 і PDM-мікрофоном MP34DT05. Мікропрограма OpenMV керує всіма цими пристроями через MicroPython.
Повну документацію, фотографії та розміри дивіться на сторінці продукту Arduino Nano 33 BLE Rev2.
Основні характеристики¶
Nordic nRF52840 Cortex‑M4 з FPU на частоті 64 МГц із 256 КБ внутрішньої SRAM та 1 МБ внутрішньої флеш-пам’яті.
Bluetooth LE 5.0 через вбудований радіомодуль і Nordic SoftDevice s140.
9-осьовий IMU —
LSM9DS1у Rev 1,BMI270+BMM150у Rev 2. Вморожений драйверimuвизначає тип при завантаженні.LPS22HBбарометр,HTS221/HS3003датчик температури та вологості,APDS9960датчик освітленості / кольору / наближення / жестів і MP34DT05 PDM-мікрофон.Micro USB роз’єм для живлення, програмування та CDC REPL.
22 користувацьких виводи введення/виведення на стандартних роз’ємах Nano —
TX/RX,D2–D13(цифрові),A0–A7(аналогові).
Розпіновка¶
Довідник з виводів¶
Назва виводу |
Довідник |
Функція |
|---|---|---|
TX |
3.3 В |
UART1 TX |
RX |
3.3 В |
UART1 RX |
D2 |
3.3 В |
PWM |
D3 |
3.3 В |
PWM |
D4 |
3.3 В |
PWM |
D5 |
3.3 В |
PWM |
D6 |
3.3 В |
PWM |
D7 |
3.3 В |
PWM |
D8 |
3.3 В |
PWM |
D9 |
3.3 В |
PWM |
D10 |
3.3 В |
PWM |
D11 |
3.3 В |
PWM / SPI0 MOSI |
D12 |
3.3 В |
PWM / SPI0 MISO |
D13 |
3.3 В |
PWM / SPI0 SCK |
A0 |
3.3 В |
ADC / PWM |
A1 |
3.3 В |
ADC / PWM |
A2 |
3.3 В |
ADC / PWM |
A3 |
3.3 В |
ADC / PWM |
A4 / I2C_SDA |
3.3 В |
ADC / PWM / I2C0 SDA |
A5 / I2C_SCL |
3.3 В |
ADC / PWM / I2C0 SCL |
A6 |
3.3 В |
ADC / PWM |
A7 |
3.3 В |
ADC / PWM |
RESET |
3.3 В |
натисніть кнопку RESET на платі або підключіть до GND для скидання |
LED_BUILTIN |
— |
Помаранчевий користувацький світлодіод на |
LED_RED |
— |
Червоний канал RGB-світлодіода (активний низький рівень) |
LED_GREEN |
— |
Зелений канал RGB-світлодіода (активний низький рівень) |
LED_BLUE |
— |
Синій канал RGB-світлодіода (активний низький рівень) |
Попередження
Виводи введення/виведення Nano 33 BLE Sense розраховані лише на 3.3 В — вони несумісні з рівнями 5 В. Подача 5 В на них пошкодить nRF52840.
Виводи живлення¶
VIN — вхід 4.5–21 В. Живить плату через вбудований регулятор. Також підключений через діод від шини USB 5 В, тому USB та
VINможуть бути присутніми одночасно без зворотного живлення.+5V — не підключений за замовчуванням.
+3V3 — вихід регулятора 3.3 В.
AREF — вивід аналогового опорного сигналу. Не підключений до nRF52840 на цій платі — АЦП завжди прив’язаний до 3.3 В.
GND — спільна земля.
Nano 33 BLE Sense може живитися двома способами:
Micro USB — подає 5 В на вбудований регулятор.
Вивід VIN — підключіть регульоване джерело 4.5–21 В.
Примітка
Паяний перемичка на нижній стороні плати з маркуванням VUSB з’єднує +5V з шиною USB 5 В. Замкніть її, щоб вивід +5V справді передавав 5 В.
Примітка
Нормально замкнена паяна перемичка на виході вбудованого імпульсного регулятора 4.5–21 В може бути розрізана, щоб відключити регулятор і живити плату безпосередньо від зовнішнього джерела 3.3 В через +3V3.
Виводи відновлення та налагодження¶
RESET — як відкритий контактний майданчик, так і кнопка миттєвої дії RESET на верхній стороні плати, підключені до лінії скидання nRF52840. Підключіть до GND або натисніть кнопку для скидання.
Nano 33 BLE Sense використовує стандартне для Arduino подвійне натискання RESET для входу в завантажувач Arduino. Швидко натисніть кнопку RESET двічі — плата увійде в режим завантажувача, і OpenMV IDE зможе прошити новий образ мікропрограми.
Сигнали SWD nRF52840 виведені на контактні майданчики на зворотній стороні плати. Усі сигнали налагодження мають рівень 3.3 В.
Вбудовані периферійні пристрої¶
Світлодіоди¶
Nano 33 BLE Sense має RGB-світлодіод для користувача — керований через канали LED_RED, LED_GREEN і LED_BLUE, позначені на шовкографії — а також окремий помаранчевий LED_BUILTIN на D13. Усі чотири програмно керуються через machine.LED
from machine import LED
LED("LED_RED").on()
LED("LED_GREEN").on()
LED("LED_BLUE").on()
LED("LED_BUILTIN").on()
Окремий зелений світлодіод живлення на платі світиться завжди, коли шина +3.3 В активна, і не підлягає програмному керуванню.
Датчик камери¶
Мікропрограма OpenMV для Nano 33 BLE Sense підтримує паралельний CMOS-датчик OmniVision OV7670. На платі немає вбудованого датчика зображення — підключіть модуль OV7670 до виводів заголовка, позначених на шовкографії нижче, і керуйте ним через модуль csi — датчики камери
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()
Примітка
OV7670 потребує 14 виводів. Мікропрограма підключає їх таким чином:
Сигнал датчика |
Вивід Nano 33 BLE Sense |
|---|---|
D0 |
|
D1 |
|
D2 |
|
D3 |
|
D4 |
|
D5 |
|
D6 |
|
D7 |
|
HSYNC |
|
VSYNC |
|
PXCLK |
|
MXCLK |
|
POWER |
|
RESET |
|
SCL |
|
SDA |
|
Шина керування I²C датчика OV7670 — це та сама зовнішня I²C 0, що виведена на A5/A4. Датчик має 7-бітну адресу 0x21 — пристрої користувача на цій шині повинні уникати цієї адреси, коли камера підключена.
IMU¶
9-осьовий IMU доступний через вморожений модуль imu, який автоматично визначає, чи встановлено на платі LSM9DS1 (Rev 1) або BMI270 + BMM150 (Rev 2), і надає уніфікований клас imu.IMU. Датчики підключені до внутрішньої шини 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)
Для безпосереднього доступу до функцій, наприклад виявлення поштовхів або FIFO, імпортуйте відповідний вморожений драйвер (lsm9ds1, bmi270 або bmm150) та інстанціюйте його на тій самій шині.
Датчики середовища¶
Барометр (LPS22HB) і датчик температури/вологості (HTS221 у Rev 1, HS3003 у Rev 2) використовують ту саму внутрішню шину I²C 1, що й 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)
Освітленість / колір / наближення / жести¶
Broadcom APDS9960 підключений до тієї самої внутрішньої шини I²C 1 і забезпечує вимірювання освітленості, RGB-кольору, наближення та жестів:
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)
Мікрофон¶
Вбудований PDM-мікрофон MP34DT05 зчитується через audio — Аудіомодуль. Кожен буфер надходить як знакові 16-бітні PCM bytearray, готові для передачі в ulab/numpy для ЦОС:
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¶
Радіомодуль Bluetooth LE 5.0 nRF52840 працює на Nordic SoftDevice s140 і доступний через застарілий модуль ubluepy — сучасні API bluetooth / aioble — Async BLE у цій збірці не підтримуються. Доступні обидва режими: периферійного пристрою (GATT-сервер, оголошення) та центрального пристрою (спостерігач/сканер GAP + підключення).
Оголошення як периферійний пристрій із єдиним сервісом Environmental Sensing і характеристикою температури з підтримкою сповіщень — зворотний виклик event_handler спрацьовує при підключенні, відключенні та записах 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])
Сканування поблизу рекламованих пристроїв у режимі центрального пристрою:
from ubluepy import Scanner
for entry in Scanner().scan(1_000): # 1 second window
print(entry.addr(), entry.rssi(), "dBm")
Повний API описано в довіднику ubluepy — UUID, Service, Characteristic, Peripheral, Scanner, ScanEntry і простір імен constants.
Довідник по шинах¶
GPIO¶
Використовуйте machine.Pin для читання або керування будь-яким з виводів, позначених на шовкографії. Виходи — 3.3 В CMOS — 15 мА на вивід, 25 мА загалом по всіх 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())
Будь-який вхідний вивід також може генерувати переривання при переходах фронтів:
def handler(pin):
print("triggered:", pin)
Pin("D3", Pin.IN, Pin.PULL_UP).irq(
handler, Pin.IRQ_FALLING | Pin.IRQ_RISING,
)
UART¶
Шина |
TX |
RX |
|---|---|---|
UART1 |
TX |
RX |
Використовуйте назви шовкографії TX/RX з machine.UART
from machine import UART
uart = UART(1, baudrate=115200)
uart.write("hello")
uart.read(5)
I²C¶
Шина |
SDA |
SCL |
|---|---|---|
I2C0 |
|
|
I2C1 |
|
|
Для обох шин потрібно явно передавати виводи в 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()
Примітка
Шина 1 — це внутрішня шина датчиків на P14/P15 (не на призначених для користувача заголовках) — вона обслуговує IMU, барометр, датчик середовища та APDS9960. Вморожені драйвери датчиків використовують її безпосередньо; код користувача також може виконувати сканування, але адреси вже зайняті вбудованими датчиками.
SPI¶
Шина |
MOSI |
MISO |
SCK |
CS |
|---|---|---|---|---|
SPI0 |
D11 |
D12 |
D13 |
D10 |
Лінія CS не керується периферійним пристроєм SPI — налаштуйте D10 як вихід і перемикайте його вручну навколо передачі:
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)
Примітка
D13 також є помаранчевим LED_BUILTIN — керування SPI на цій шині буде блимати світлодіодом у такт із тактовим сигналом шини.
ADC¶
nRF52840 має вісім 12-бітних каналів АЦП (SAADC), виведених на A0–A7, усі прив’язані до 3.3 В — read_u16 повертає 0–65535 в діапазоні 0–3.3 В на виводі. Вивід AREF плати не підключений, тому опорна напруга завжди 3.3 В:
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 має чотири PWM-периферійні пристрої (PWM0–PWM3), кожен керує чотирма каналами, що дає 16 апаратних PWM-слотів загалом. На відміну від портів з фіксованою функцією, периферійні пристрої маршрутизуються через матрицю GPIOTE — будь-який GPIO може бути виходом PWM, тому немає прив’язки вивід-до-зрізу. За цю гнучкість доводиться платити двома обмеженнями, закладеними в кремній:
Усі чотири канали всередині модуля мають один спільний період/частоту.
Кожен канал має власний робочий цикл та полярність.
Концептуально 16 слотів виглядають так:
Модуль |
Кан. 0 |
Кан. 1 |
Кан. 2 |
Кан. 3 |
|---|---|---|---|---|
PWM0 |
робочий цикл |
робочий цикл |
робочий цикл |
робочий цикл |
PWM1 |
робочий цикл |
робочий цикл |
робочий цикл |
робочий цикл |
PWM2 |
робочий цикл |
робочий цикл |
робочий цикл |
робочий цикл |
PWM3 |
робочий цикл |
робочий цикл |
робочий цикл |
робочий цикл |
Кожен рядок працює на одній частоті; чотири комірки в рядку кожна керують незалежно обраним виводом із власним робочим циклом. Різні рядки можуть працювати на зовсім різних частотах.
Керуйте будь-яким виводом шовкографії (або вбудованими світлодіодами) через machine.PWM
from machine import Pin, PWM
pwm = PWM(Pin("D3"), freq=1_000, duty_u16=32768)
Попередження
Автоматичне виділення займає цілий модуль за виклик. Коли ви створюєте PWM без аргументів device=/channel=, драйвер займає перший вільний модуль і прив’язує ваш вивід лише до каналу 0. Три канали, що залишаються, стоять без діла і доступні лише через явне device=/channel=. Це обмежує некеровані виклики PWM(Pin(...)) до чотирьох, після чого драйвер викидає ValueError: all PWM devices in use — хоча технічно ще дванадцять слотів вільні.
Щоб використовувати більше чотирьох PWM або навмисно розділити частоту між виводами, передайте device (0–3) і 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)
Робочий цикл задається через duty (0–100%), duty_u16 (0–65535) або duty_ns. Додайте invert=1, щоб змінити полярність виходу (зручно для активного низького рівня RGB-світлодіода).
Примітка
Оскільки частота є властивістю всього модуля, виклик pwm.freq(new_freq) для будь-якого каналу модуля повторно запускає nrfx_pwm_init для всього модуля і змінює частоту для кожного іншого каналу, що ним користується.
Примітка
Допустимі частоти охоплюють приблизно від 4 Гц до 5.3 МГц, що визначаються базовим тактовим сигналом 16 МГц із попередніми дільниками 1/2/4/8/16/32/64/128 і 15-бітним лічильником періоду. Драйвер автоматично вибирає найближчий дільник — freq() повертає запитане значення, а не точно досяжне.
Програмно емульовані шини¶
machine.SoftI2C і machine.SoftSPI працюють на будь-якому GPIO, якщо вам потрібна додаткова шина.
Тепловий датчик (зовнішній)¶
Мікропрограма включає драйвер fir — драйвер теплового датчика (fir == далекий інфрачервоний діапазон) для зовнішньо підключених теплових сенсорів:
MLX90621 — ІЧ-матриця 16 × 4
MLX90640 — ІЧ-матриця 32 × 24
MLX90641 — ІЧ-матриця 16 × 12
AMG8833 — ІЧ-матриця 8 × 8
Підключіть модуль до шини I²C плати та зчитуйте кадри за допомогою 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())
Драйвер fir спілкується з датчиком лише через I²C 0 — підключіть модуль до майданчиків I2C_SCL / I2C_SDA (A5 / A4).
Тайминг¶
time¶
Модуль time охоплює блокуючі затримки, монотонні тіки та вимірювання часу, що минув:
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)
Віртуальні таймери¶
machine.Timer планує циклічні або одноразові зворотні виклики без використання апаратного слоту таймера. Передайте -1 як ідентифікатор, щоб використовувати віртуальний (програмний) таймер:
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"))
Значення періоду задаються в мілісекундах. Викличте deinit() для зупинки та звільнення слоту.
Годинник реального часу¶
machine.RTC зберігає астрономічний час між скиданнями. RTC nRF52840 прив’язаний до внутрішнього осцилятора і не зберігає значення при повному відключенні живлення — встановлюйте час при кожному холодному завантаженні, якщо це важливо для вашого застосунку:
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())
Сторожовий таймер¶
machine.WDT скидає плату, якщо застосунок зависає. Після запуску його не можна зупинити або переналаштувати — регулярно скидайте його всередині головного циклу:
from machine import WDT
wdt = WDT(timeout=5_000) # 5 second window
while True:
# ...do work...
wdt.feed()
Інформація про завантаження та виконання¶
Оновлення мікропрограми¶
Nano 33 BLE Sense використовує стандартне для Arduino подвійне натискання RESET для входу в завантажувач Arduino. Швидко натисніть кнопку RESET двічі — плата увійде в режим завантажувача, і OpenMV IDE зможе прошити новий образ мікропрограми.
Запущений скрипт може повернутися до завантажувача на вимогу, викликавши machine.bootloader()
import machine
machine.bootloader()
Файлова система та порядок завантаження¶
Мікропрограма Nano 33 BLE Sense монтує єдину файлову систему при завантаженні:
Внутрішня флеш-пам’ять — завжди монтується в
/flashі використовується як робочий каталог. За замовчуванням міститьmain.pyтаREADME.txt; створюється при першому завантаженні.
Після монтування інтерпретатор запускає скрипти з /flash:
boot.pyвиконується при кожному м’якому скиданні.main.pyвиконується лише при холодному завантаженні, одразу післяboot.py.
Стандартний main.py, що поставляється на щойно прошитій платі, просто блимає синім каналом RGB-світлодіода у ритмі серцебиття (два короткі спалахи, коротка пауза), щоб можна було переконатися в успішному завантаженні мікропрограми без підключення до хосту.
/flash не відображається як USB-накопичувач на цій платі.
Розміри сховищ¶
Nano 33 BLE Sense постачається з:
/flash— FAT-файлова система розміром 64 КБ, читання/запис.
Збірка Nano 33 BLE Sense не включає ROMFS; розміщуйте модулі Python безпосередньо в /flash.
Програмні бібліотеки¶
Повний список модулів, включно з тими, що унікальні для збірки Nano 33 BLE Sense, дивіться в індексі бібліотек.