Arduino Nano 33 BLE Sense¶
Peringatan
Papan ini tidak lagi didukung. Rilis firmware OpenMV terakhir untuk Arduino Nano 33 BLE Sense adalah 4.7.0. Tidak ada pembaruan firmware, perbaikan bug, atau fitur baru yang akan diterbitkan untuk target ini. Informasi di bawah ini dipertahankan untuk pengguna yang menjalankan versi 4.7.0 atau sebelumnya.
Arduino Nano 33 BLE Sense adalah papan berukuran 45 × 18 mm berformat Arduino‑Nano yang dibangun di sekitar Nordic Semiconductor nRF52840 — sebuah ARM Cortex‑M4 tunggal dengan FPU yang berjalan pada 64 MHz dengan 256 KB SRAM internal dan 1 MB flash internal. BLE berasal dari radio on‑die, dan papan ini dilengkapi dengan IMU 9 sumbu, barometer LPS22HB, sensor suhu/kelembapan HTS221/HS3003, sensor cahaya ambien/warna/proksimitas/gestur APDS9960, dan mikrofon PDM MP34DT05. Firmware OpenMV mengontrol semuanya dari MicroPython.
Untuk datasheet lengkap, foto, dan dimensi, lihat halaman produk Arduino Nano 33 BLE Rev2.
Sorotan¶
Nordic nRF52840 Cortex‑M4 dengan FPU pada 64 MHz dengan 256 KB SRAM internal dan 1 MB flash internal.
Bluetooth LE 5.0 melalui radio on‑die dan Nordic SoftDevice s140.
IMU 9 sumbu —
LSM9DS1pada Rev 1,BMI270+BMM150pada Rev 2. Driver bekuimumendeteksi keduanya saat boot.LPS22HBbarometer,HTS221/HS3003sensor suhu dan kelembapan,APDS9960sensor cahaya ambien / warna / proksimitas / gestur, dan mikrofon PDM MP34DT05.Konektor Micro USB untuk daya, pemrograman, dan REPL CDC.
22 pin I/O pengguna pada header Nano standar —
TX/RX,D2–D13(digital),A0–A7(analog).
Pinout¶
Referensi pin¶
Nama pin |
Referensi |
Fungsi |
|---|---|---|
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 |
tekan tombol RESET di papan atau tarik ke GND untuk mereset |
LED_BUILTIN |
— |
LED pengguna oranye pada |
LED_RED |
— |
Saluran merah LED RGB (aktif rendah) |
LED_GREEN |
— |
Saluran hijau LED RGB (aktif rendah) |
LED_BLUE |
— |
Saluran biru LED RGB (aktif rendah) |
Peringatan
Pin I/O Nano 33 BLE Sense hanya 3.3 V — tidak toleran terhadap 5 V. Menerapkan 5 V ke pin tersebut akan merusak nRF52840.
Pin daya¶
VIN — input 4.5 – 21 V. Memberi daya pada papan melalui regulator on‑board. Juga diumpankan melalui dioda dari rel 5 V USB, sehingga USB dan
VINdapat hadir secara bersamaan tanpa saling mengemudi balik.+5V — tidak terhubung secara default.
+3V3 — output regulator 3.3 V.
AREF — pin referensi analog. Tidak terhubung ke nRF52840 pada papan ini — ADC selalu direferensikan ke 3.3 V.
GND — ground bersama.
Nano 33 BLE Sense dapat diberi daya melalui salah satu jalur berikut:
Micro USB — menyuplai 5 V ke regulator on‑board.
Pin VIN — gunakan catu daya teregulasi 4.5 – 21 V.
Catatan
Jumper solder di bagian bawah papan berlabel VUSB menjembatani +5V ke rel 5 V USB. Tutup untuk membuat pin header +5V benar‑benar membawa 5 V.
Catatan
Jumper solder yang biasanya tertutup pada output regulator switching 4.5–21 V on‑board dapat dipotong untuk menonaktifkan regulator, sehingga papan dapat diberi daya langsung dari catu daya eksternal 3.3 V pada +3V3.
Pin pemulihan dan debug¶
RESET — baik pad yang terekspos maupun tombol RESET sesaat di bagian atas papan, terhubung ke jalur reset nRF52840. Tarik ke GND atau tekan tombol untuk mereset.
Nano 33 BLE Sense menggunakan double‑tap reset standar Arduino untuk masuk ke bootloader Arduino. Tekan tombol RESET dua kali dengan cepat — papan memasuki mode bootloader dan OpenMV IDE dapat mem-flash citra firmware baru.
Sinyal SWD nRF52840 terekspos pada pad berlapis di bagian belakang papan. Semua sinyal debug direferensikan ke 3.3 V.
Periferal on‑board¶
LED¶
Nano 33 BLE Sense memiliki LED RGB pengguna — dikendalikan melalui saluran LED_RED, LED_GREEN, dan LED_BLUE yang tertera di silkscreen — ditambah LED_BUILTIN oranye terpisah pada D13. Keempat LED dapat dikontrol melalui perangkat lunak menggunakan machine.LED
from machine import LED
LED("LED_RED").on()
LED("LED_GREEN").on()
LED("LED_BLUE").on()
LED("LED_BUILTIN").on()
LED daya hijau terpisah pada papan menyala setiap kali rel +3.3 V aktif dan tidak dapat dikontrol oleh pengguna.
Sensor kamera¶
Firmware OpenMV pada Nano 33 BLE Sense mendukung sensor CMOS paralel OmniVision OV7670. Papan ini tidak memiliki sensor citra on‑board — hubungkan modul OV7670 ke pin header yang tertera di silkscreen di bawah ini dan kendalikan melalui modul csi --- sensor kamera
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()
Catatan
OV7670 membutuhkan 14 pin. Firmware menghubungkannya sebagai berikut:
Sinyal sensor |
Pin Nano 33 BLE Sense |
|---|---|
D0 |
|
D1 |
|
D2 |
|
D3 |
|
D4 |
|
D5 |
|
D6 |
|
D7 |
|
HSYNC |
|
VSYNC |
|
PXCLK |
|
MXCLK |
|
POWER |
|
RESET |
|
SCL |
|
SDA |
|
Bus kontrol I²C OV7670 adalah I²C 0 eksternal yang sama yang terekspos pada A5/A4. Sensor berada di alamat 7‑bit 0x21 — perangkat pengguna pada bus tersebut harus menghindari alamat ini saat kamera terhubung.
IMU¶
IMU 9 sumbu diekspos melalui modul beku imu, yang secara otomatis mendeteksi apakah papan memiliki LSM9DS1 (Rev 1) atau BMI270 + BMM150 (Rev 2) dan menyajikan kelas imu.IMU yang terpadu. Sensor berada pada bus I²C 1 internal (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)
Untuk akses langsung ke fitur seperti deteksi ketukan atau FIFO, impor driver beku yang sesuai (lsm9ds1, bmi270, atau bmm150) dan instansikan pada bus yang sama.
Sensor lingkungan¶
Barometer (LPS22HB) dan sensor suhu / kelembapan (HTS221 pada Rev 1, HS3003 pada Rev 2) berbagi bus I²C 1 internal yang sama dengan 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)
Cahaya / warna / proksimitas / gestur¶
Broadcom APDS9960 berada pada bus I²C 1 internal yang sama dan menyediakan cahaya ambien, warna RGB, proksimitas, dan penginderaan gestur:
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)
Mikrofon¶
Mikrofon PDM MP34DT05 on‑board diambil melalui audio --- Modul Audio. Setiap buffer tiba sebagai PCM 16‑bit bertanda bytearray, siap diumpankan ke ulab/numpy untuk 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¶
Radio Bluetooth LE 5.0 nRF52840 berjalan di atas Nordic SoftDevice s140 dan diekspos melalui modul warisan ubluepy — API modern bluetooth / aioble --- Async BLE tidak diaktifkan dalam build ini. Peran periferal (server GATT, iklan) dan sentral (pengamat GAP / pemindai + sambung) keduanya tersedia.
Iklankan sebagai periferal dengan satu layanan Environmental Sensing dan karakteristik suhu yang dapat dinotifikasi — callback event_handler terpicu saat sambung, putus, dan penulisan 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])
Pindai perangkat yang sedang mengiklan di dekatnya dalam peran sentral:
from ubluepy import Scanner
for entry in Scanner().scan(1_000): # 1 second window
print(entry.addr(), entry.rssi(), "dBm")
Lihat referensi ubluepy untuk API lengkap — UUID, Service, Characteristic, Peripheral, Scanner, ScanEntry, dan namespace constants.
Referensi bus¶
GPIO¶
Gunakan machine.Pin untuk membaca atau menggerakkan salah satu pin yang tertera di silkscreen. Output adalah CMOS 3.3 V — 15 mA per pin, 25 mA total di seluruh 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())
Pin input mana pun juga dapat memicu interupsi pada transisi tepi:
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 |
Gunakan nama silkscreen TX/RX dengan machine.UART
from machine import UART
uart = UART(1, baudrate=115200)
uart.write("hello")
uart.read(5)
I²C¶
Bus |
SDA |
SCL |
|---|---|---|
I2C0 |
|
|
I2C1 |
|
|
Kedua bus membutuhkan pin yang diteruskan secara eksplisit ke 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()
Catatan
Bus 1 adalah bus sensor internal pada P14/P15 (tidak pada header pengguna) — melayani IMU, barometer, sensor lingkungan, dan APDS9960. Driver sensor beku menggunakannya langsung; kode pengguna dapat memindainya juga tetapi alamat sudah digunakan oleh sensor on‑board.
SPI¶
Bus |
MOSI |
MISO |
SCK |
CS |
|---|---|---|---|---|
SPI0 |
D11 |
D12 |
D13 |
D10 |
Jalur CS tidak dikendalikan oleh periferal SPI — konfigurasikan D10 sebagai output dan toggle secara manual di sekitar transfer:
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)
Catatan
D13 juga berfungsi sebagai LED_BUILTIN oranye — menjalankan SPI pada bus ini akan membuat LED berkedip sesuai dengan clock bus.
ADC¶
nRF52840 memiliki delapan saluran ADC 12‑bit (SAADC) yang terekspos pada A0–A7, semuanya direferensikan ke 3.3 V — read_u16 mengembalikan 0–65535 di rentang 0–3.3 V pada pin. Pin AREF papan tidak terhubung, sehingga referensi selalu 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 mengekspos empat periferal PWM (PWM0–PWM3), masing‑masing menggerakkan empat saluran, sehingga total 16 slot PWM hardware. Tidak seperti port dengan fungsi tetap, periferal merutekan melalui matriks GPIOTE — GPIO mana pun dapat menjadi output PWM, sehingga tidak ada pemetaan pin-ke-slice. Biaya dari fleksibilitas tersebut adalah dua batasan yang tertanam dalam silikon:
Keempat saluran dalam satu modul berbagi satu periode/frekuensi.
Setiap saluran memiliki siklus kerja dan polaritasnya sendiri.
Secara konseptual, 16 slot terlihat seperti ini:
Modul |
Ch 0 |
Ch 1 |
Ch 2 |
Ch 3 |
|---|---|---|---|---|
PWM0 |
duty |
duty |
duty |
duty |
PWM1 |
duty |
duty |
duty |
duty |
PWM2 |
duty |
duty |
duty |
duty |
PWM3 |
duty |
duty |
duty |
duty |
Setiap baris berjalan pada satu frekuensi; keempat sel dalam satu baris masing‑masing menggerakkan pin yang dipilih secara independen dengan siklus kerjanya sendiri. Baris yang berbeda dapat berjalan pada frekuensi yang sangat berbeda.
Gerakkan pin yang tertera di silkscreen mana pun (atau LED on‑board) melalui machine.PWM
from machine import Pin, PWM
pwm = PWM(Pin("D3"), freq=1_000, duty_u16=32768)
Peringatan
Alokasi otomatis mengonsumsi seluruh modul per panggilan. Saat Anda membuat PWM tanpa argumen device=/channel=, driver mengambil modul bebas pertama dan mengikat pin Anda ke saluran 0-nya saja. Tiga saluran lainnya dari modul tersebut tidak aktif dan hanya dapat dijangkau melalui device=/channel= eksplisit. Hal ini membatasi panggilan PWM(Pin(...)) tanpa bantuan hingga empat sebelum driver memunculkan ValueError: all PWM devices in use — meskipun secara teknis masih ada dua belas slot yang kosong.
Untuk menggunakan lebih dari empat PWM, atau untuk sengaja berbagi frekuensi di seluruh pin, teruskan device (0–3) dan 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)
Siklus kerja menerima duty (0–100%), duty_u16 (0–65535), atau duty_ns. Tambahkan invert=1 untuk membalik polaritas output (berguna untuk LED RGB aktif rendah).
Catatan
Karena frekuensi adalah properti per‑modul, memanggil pwm.freq(new_freq) pada saluran mana pun dari sebuah modul akan menjalankan ulang nrfx_pwm_init untuk seluruh modul dan mengubah frekuensi yang terlihat oleh setiap saluran lain yang berbaginya.
Catatan
Frekuensi yang diizinkan berkisar dari sekitar 4 Hz hingga 5.3 MHz, diturunkan dari clock dasar 16 MHz dengan prescaler 1/2/4/8/16/32/64/128 dan counter periode 15‑bit. Driver memilih pembagi terdekat secara otomatis — freq() melaporkan nilai yang diminta, bukan nilai yang tepat dapat dicapai.
Bus bit‑banged perangkat lunak¶
machine.SoftI2C dan machine.SoftSPI bekerja pada GPIO mana pun jika Anda membutuhkan bus tambahan.
Sensor termal (off‑board)¶
Firmware menyertakan driver fir --- driver sensor termal (fir == far infrared) untuk thermal imager yang terhubung secara eksternal:
MLX90621 — array IR 16 × 4
MLX90640 — array IR 32 × 24
MLX90641 — array IR 16 × 12
AMG8833 — array IR 8 × 8
Hubungkan modul ke bus I²C papan dan baca bingkai dengan 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())
Driver fir hanya berkomunikasi dengan sensor melalui I²C 0 — hubungkan modul ke pad I2C_SCL / I2C_SDA (A5 / A4).
Pengaturan waktu¶
time¶
Modul time mencakup penundaan pemblokiran, tick monotonic, dan pengukuran waktu yang telah berlalu:
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)
Timer virtual¶
machine.Timer menjadwalkan callback periodik atau sekali tembak tanpa mengonsumsi slot timer hardware. Teruskan -1 sebagai id untuk menggunakan timer virtual (perangkat lunak):
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"))
Nilai periode dalam milidetik. Panggil deinit() untuk menghentikan dan melepaskan slot.
Jam real‑time¶
machine.RTC menjaga waktu jam dinding di seluruh reset. RTC nRF52840 terikat ke osilator on‑chip dan tidak bertahan setelah kehilangan daya penuh — atur waktu pada setiap cold boot jika hal itu penting untuk aplikasi Anda:
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 mereset papan jika aplikasi hang. Setelah dimulai, tidak dapat dihentikan atau dikonfigurasi ulang — umpankan secara berkala di dalam loop utama Anda:
from machine import WDT
wdt = WDT(timeout=5_000) # 5 second window
while True:
# ...do work...
wdt.feed()
Info boot dan runtime¶
Pembaruan firmware¶
Nano 33 BLE Sense menggunakan double‑tap reset standar Arduino untuk masuk ke bootloader Arduino. Tekan tombol RESET dua kali dengan cepat — papan memasuki mode bootloader dan OpenMV IDE dapat mem-flash citra firmware baru.
Skrip yang berjalan dapat masuk kembali ke bootloader sesuai permintaan dengan memanggil machine.bootloader()
import machine
machine.bootloader()
Filesystem dan urutan boot¶
Firmware Nano 33 BLE Sense memasang satu filesystem saat boot:
Flash internal — selalu dipasang di
/flashdan digunakan sebagai direktori kerja. Berisimain.pydanREADME.txtsecara default; dibuat pada boot pertama.
Setelah pemasangan, interpreter kemudian menjalankan skrip dari /flash:
boot.pydieksekusi pada setiap soft reset.main.pydieksekusi hanya pada cold boot, segera setelahboot.py.
main.py default yang dikirimkan pada papan yang baru di-flash hanya membuat saluran biru LED RGB pengguna berkedip sebagai heartbeat (dua pulsa pendek, jeda pendek), sehingga Anda dapat mengetahui firmware telah boot dengan bersih tanpa host yang terhubung.
/flash tidak diekspos sebagai drive penyimpanan massal USB pada papan ini.
Ukuran penyimpanan¶
Nano 33 BLE Sense dikirimkan dengan:
/flash— filesystem FAT 64 KB, baca/tulis.
Build Nano 33 BLE Sense tidak menyertakan ROMFS; kirimkan modul Python di /flash langsung.
Pustaka perangkat lunak¶
Lihat indeks pustaka untuk daftar lengkap modul — termasuk modul mana yang unik untuk build Nano 33 BLE Sense.