OpenMV N6

L’OpenMV N6 è costruito attorno allo STMicroelectronics STM32N657 (Cortex‑M55 @ 800 MHz) con una NPU on‑chip a 1 GHz da 600 GOPS INT8. La scheda abbina la NPU al sensore global‑shutter PAG7936 da 1 MP montato su un supporto rimovibile, Ethernet gigabit, USB‑C high‑speed, Wi‑Fi e Bluetooth 5.1, ed esegue inferenza YOLOv8/YOLOv11 a 30 FPS contemporaneamente allo streaming video in tempo reale.

OpenMV N6

Per il datasheet completo, le foto e le dimensioni consulta la pagina prodotto OpenMV N6.

Caratteristiche principali

  • STM32N657 Cortex‑M55 a 800 MHz (1280 DMIPS) con SIMD ARM Helium a 128 bit — 6,4 gigaops di throughput vettoriale.

  • NPU a 1 GHz, 600 GOPS INT8 — esegue il rilevamento YOLOv8/YOLOv11 a 30 FPS.

  • ISP per RAW Bayer fino a 5 MP, GPU 2D per scaling e rotazione 3D, codifica H.264 fino a 1080p e codec JPEG hardware.

  • 64 MB di SDRAM esterna (16 bit @ 200 MHz DDR, 800 MB/s) oltre a 4,2 MB di SRAM interna e 32 MB di flash octal (200 MHz DDR, 400 MB/s).

  • Sensore PAG7936 global‑shutter a colori da 1 MP.

  • IMU integrata (accelerometro + giroscopio) e microfono per la fusione di audio e movimento.

  • USB‑C high‑speed (480 Mb/s, limite di corrente 1,5 A), Ethernet gigabit (compatibile PoE tramite shield), Wi‑Fi a/b/g/n + Bluetooth 5.1 (antenna chip o opzione U.FL).

  • Slot microSD — SD fino a 2 GB, SDHC fino a 32 GB, SDXC fino a 2 TB.

  • Caricabatterie LiPo (ricarica rapida a 500 mA), ADC per la tensione della batteria, RTC con 8 KB di RAM di backup e un pin dedicato per la batteria di backup.

  • 18 pin di I/O, tutti con uscita a 3,3 V / tolleranti 3,3 V, 20 mA per pin, in grado di generare interrupt.

  • LED RGB utente, pulsante utente e un LED di stato separato per la ricarica / USB / alimentazione VIN.

Avvertimento

I pin di I/O dell’N6 non sono tolleranti a 5 V. Non collegare il dispositivo direttamente a un MCU a 5 V come l’Arduino Mega. Alimenta l’N6 solo tramite VIN.

Pinout

Pinout OpenMV N6 PAG7936

Riferimento dei pin

Nome del pin

Funzione

P0

SPI2 MOSI / I2S2 SDO

P1

SPI2 MISO / I2S2 SDI

P2

SPI2 SCLK / UART4 TX / CAN1 TX / I2S2 CK

P3

SPI2 SS / UART4 RX / CAN1 RX / I2S2 WS

P4

I2C2 SCL / UART3 TX / TIM2 CH3 / I3C2 SCL

P5

I2C2 SDA / UART3 RX / TIM2 CH4 / I3C2 SDA

P6

TIM12 CH1 (nessun ADC su questo pin — vedi P6_ADC)

P6_ADC

ingresso ADC dedicato a 12 bit (collegato internamente a P6)

P7

TIM4 CH1

P8

TIM4 CH2

P9

TIM17 CH1

P10

TIM15 CH2 / I/O di frame sync

P11

wakeup (attivo basso, WKUP3)

P12

RESET — collegare a GND per resettare la scheda (non è un GPIO)

P13

UART7 RX

P14

UART7 TX

P15

SPI4 CS

P16

SPI4 SCK

P17

SPI4 MISO

P18

SPI4 MOSI

SW

pulsante utente (attivo basso)

ONOFF (SW2)

pulsante di wakeup da deep‑sleep (attivo basso, WKUP2)

ST

basso con alimentazione VIN, alto con alimentazione USB

CHG

attivo basso; basso mentre una batteria LiPo collegata è in carica

PG

attivo basso; basso quando è presente l’alimentazione VIN o USB

BAT_ADC

canale ADC interno che misura la tensione della batteria LiPo collegata

LED_RED

canale rosso del LED RGB (attivo basso)

LED_GREEN

canale verde del LED RGB (attivo basso)

LED_BLUE

canale blu del LED RGB (attivo basso)

Nota

La linea di frame‑sync P10 è un bus condiviso. È cablata contemporaneamente all’MCU, al pin di trigger / esposizione del sensore della camera e all’header utente. La direzione è definita dall’applicazione — l’MCU, il sensore o un segnale esterno possono pilotarla a seconda di come è configurato il sensore (alcuni sensori possono usare lo stesso pin come ingresso di trigger oppure come uscita di esposizione). Assicurati che sia attivo un solo driver alla volta.

Nota

ONOFF e P11 sono riferiti al rail RAW sempre attivo (non al rail commutato a 3,3 V), quindi restano funzionali mentre il resto della scheda è in deep sleep / modalità a basso consumo. Entrambi gli ingressi sono attivi bassi.

Questi pin passano attraverso level shifter in modo da poter funzionare sul rail RAW. Se hai assolutamente bisogno di un comportamento GPIO diretto a 3,3 V su ONOFF o P11 (per esempio per pilotarli da un MCU a 3,3 V senza passare per lo shifter), la scheda espone piazzole di pull‑up e jumper da 0 ohm che permettono di bypassare lo shifter. Si tratta di una modifica hardware avanzata — la maggior parte degli utenti dovrebbe lasciarla così com’è.

Nota

I pin P15–P18 sono condivisi con il PHY Gigabit Ethernet, che è cablato e attivo per impostazione predefinita. Per usare questi pin come I/O utente devi risaldare la resistenza da 0 ohm sul retro della scheda nella posizione GPIO. Questo disabilita solo l’Ethernet gigabit — l’Ethernet 10/100 Mb/s continua a funzionare sui suoi pin dedicati.

Pin di alimentazione

  • 3.3V — rail regolato a 3,3 V. Solo uscita sull’N6 — non alimentare questo pin con sorgenti esterne. Disponibili fino a 1 A per gli shield.

  • VIN — ingresso a 5 V. Alimenta la scheda e il caricabatterie LiPo integrato.

  • RAW — ingresso/uscita, sempre attivo (3,6 V – 5 V). Trasporta qualunque sorgente sia attiva (VIN, USB o batteria collegata) e può essere usato anche come ingresso. Devi pilotare RAW attraverso un diodo in serie quando vi immetti alimentazione — altrimenti la corrente rifluirà verso VIN/USB danneggiando l’alimentatore o la protezione integrata.

  • GND — massa comune.

Nota

Il chip di gestione dell’alimentazione integrato sceglie automaticamente tra USB o VIN quella con la tensione più alta per alimentare la scheda e il caricabatterie. Se è collegata una batteria LiPo, questa viene caricata con il margine residuo, e il controller passa alla batteria per mantenere la scheda in funzione se VIN/USB calano o vengono scollegati.

Nota

Il retro della scheda dispone di piazzole di saldatura per una batteria di backup RTC esterna da 3,3 V. Collegando una pila a bottone a queste piazzole si mantengono in funzione l’RTC e gli 8 KB di RAM di backup mentre il resto della scheda è privo di alimentazione.

Suggerimento

Usa lo stimatore della durata della batteria per modellare per quanto tempo l’N6 funzionerà a batteria con un dato duty cycle attivo / deep‑sleep.

Pin Ethernet

L’N6 espone le coppie MDI del PHY Ethernet su piazzole dedicate accanto all’header GPIO. I pin MDI non possono essere cablati direttamente a un RJ45 — tra il PHY e il cavo sono necessari i magnetici Ethernet (un trasformatore di isolamento, integrato in un magjack o presente sullo shield). Lo shield OpenMV PoE li include; se ti costruisci il tuo connettore, usa un RJ45 con magnetici integrati o un trasformatore esterno.

  • ETH_LED — LED di link/attività. Attivo basso quando il link è attivo; lampeggia in presenza di traffico.

  • DA P / DA N — coppia A (TX in 10/100, usata a tutte le velocità).

  • DB P / DB N — coppia B (RX in 10/100, usata a tutte le velocità).

  • DC P / DC N — coppia C, usata solo in gigabit.

  • DD P / DD N — coppia D, usata solo in gigabit.

Il 10/100 Mb/s richiede solo le coppie A e B. Il gigabit richiede tutte e quattro le coppie A–D.

Pin di recovery e debug

  • RESET — collegare a GND per resettare la scheda. Rilasciandolo l’MCU si avvia normalmente.

  • BOOT0 — collegare a 3,3 V durante l’alimentazione della scheda per entrare in modalità ROM bootloader. OpenMV IDE usa questa modalità per riflashare il bootloader integrato.

  • BOOT1 — switch che mette la scheda in modalità sviluppatore per l’uso con gli strumenti di ST (un ST‑LINK collegato all’header ARM SWD/JTAG a 10 pin). Lascialo disabilitato per il funzionamento normale con firmware e strumenti OpenMV.

È presente un header ARM SWD/JTAG a 10 pin dedicato, compatibile con gli adattatori ST‑LINK e SEGGER J‑Link.

Periferiche integrate

LED

L’N6 ha due LED RGB:

  • LED RGB utente — controllabile via software, esposto come LED_RED, LED_GREEN e LED_BLUE

    from machine import LED
    
    LED("LED_RED").on()
    LED("LED_GREEN").on()
    LED("LED_BLUE").on()
    
  • LED di alimentazione — pilotato direttamente dall’hardware di gestione dell’alimentazione integrato, senza controllo software. Usalo per capire a colpo d’occhio cosa sta facendo l’alimentazione.

    Durante il funzionamento:

    Canale

    Significato

    Blu

    VIN sta alimentando la scheda (spento su USB)

    Verde

    alimentazione USB o VIN presente

    Rosso

    ricarica di una batteria LiPo collegata

    In deep sleep tutti i canali sono spenti tranne il rosso, che resta acceso mentre una batteria LiPo è in carica.

Pulsanti utente

L’N6 ha due pulsanti:

  • SW — pulsante utente generico. Attivo quando viene portato a livello basso.

  • ONOFF (SW2) — pulsante di wakeup. L’unico pulsante in grado di far uscire la scheda dal deep sleep.

from machine import Pin

sw    = Pin("SW",    Pin.IN)   # user button
onoff = Pin("ONOFF", Pin.IN)   # SW2 — wakes from deep sleep
print(sw.value(), onoff.value())

Per mettere la scheda in deep sleep e farla risvegliare con ONOFF (SW2), basta chiamare machine.deepsleep() — non è richiesta alcuna configurazione di wakeup, il pulsante è cablato direttamente all’ingresso WKUP2:

import machine

machine.deepsleep()   # press ONOFF (SW2) to wake the board

Puoi anche cablare ONOFF come interruttore di accensione soft. Attiva sul fronte di salita — la linea si stabilizza alta dopo che l’utente rilascia il pulsante, così la pressione successiva è inequivocabilmente un evento di wakeup:

import machine
from machine import Pin

def power_off(_):
    machine.deepsleep()

Pin("ONOFF", Pin.IN).irq(power_off, Pin.IRQ_RISING)

# ...rest of the application runs here. Press ONOFF once to sleep,
# press it again to wake.

Pin di stato dell’alimentazione

Tre ingressi di stato attivi bassi permettono al firmware di vedere cosa sta facendo il chip di gestione dell’alimentazione integrato:

  • ST — basso quando la scheda funziona su VIN, alto quando funziona su alimentazione USB.

  • CHG — basso mentre una batteria LiPo collegata è in carica.

  • PG — basso quando è presente l’alimentazione VIN o USB.

from machine import Pin

on_vin    = not Pin("ST",  Pin.IN).value()
charging  = not Pin("CHG", Pin.IN).value()
power_ok  = not Pin("PG",  Pin.IN).value()

Sensore della camera

Il PAG7936 è pilotato tramite il modulo csi — sensori camera

import csi

cam = csi.CSI()
cam.reset()
cam.pixformat(csi.RGB565)
cam.framesize(csi.HD)         # 1280×800
cam.snapshot(time=2000)       # let auto‑exposure settle

while True:
    img = cam.snapshot()

Il sensore è montato su un modulo rimovibile — sostituiscilo con uno qualsiasi degli altri moduli camera OpenMV (global shutter, termico, risoluzione superiore, ecc.) senza modificare il resto della scheda.

Il PAG7936 supporta la modalità triggered — l’integrazione dei pixel viene allineata esattamente a ogni chiamata csi.CSI.snapshot invece che al clock di frame free‑running, utile per sincronizzare l’acquisizione con un evento esterno o un altro sensore. Abilitala tramite csi.CSI.ioctl con csi.IOCTL_SET_TRIGGERED_MODE. Il frame rate scende a circa la metà rispetto alla modalità free‑running, perché la lettura non è più in pipeline con l’integrazione del frame successivo:

cam.ioctl(csi.IOCTL_SET_TRIGGERED_MODE, True)

NPU

La NPU Neural‑ART a 1 GHz dell’N6 (600 GOPS INT8) è esposta tramite il modulo ml — Machine Learning. I modelli memorizzati sul filesystem di sola lettura /rom vengono caricati direttamente dalla flash senza copiarli in RAM, così anche i detector di grandi dimensioni trovano comodamente posto accanto al framebuffer in tempo reale. Esegui un detector YOLOv8 su ogni frame e disegna le predizioni sopra l’immagine in tempo reale:

import csi
import time
import ml
from ml.postprocessing.ultralytics import YoloV8

# Initialize the sensor.
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.VGA)

# Load YOLO V8 model from ROM FS.
model = ml.Model("/rom/yolov8n_192.tflite", postprocess=YoloV8(threshold=0.4))
print(model)

# Visualization parameters.
n = len(model.labels)
model_class_colors = [
    (int(255 * i // n), int(255 * (n - i - 1) // n), 255)
    for i in range(n)
]

clock = time.clock()
while True:
    clock.tick()
    img = csi0.snapshot()

    # boxes is a list of list per class of ((x, y, w, h), score) tuples
    boxes = model.predict([img])

    # Draw bounding boxes around the detected objects
    for i, class_detections in enumerate(boxes):
        rects = [r for r, score in class_detections]
        labels = [model.labels[i] for j in range(len(rects))]
        colors = [model_class_colors[i] for j in range(len(rects))]
        ml.utils.draw_predictions(img, rects, labels, colors, format=None)

    print(clock.fps(), "fps")

Microfono

Il microfono integrato viene acquisito tramite audio — Modulo Audio. Ogni buffer arriva come un bytearray PCM con segno a 16 bit, il che rende banale passarlo a ulab/numpy per un rapido DSP. Un semplice rilevatore di intensità sonora — stampa ogni volta che il volume RMS supera una soglia:

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

IMU

L’accelerometro + giroscopio integrato sotto il modulo camera è esposto tramite imu — sensore imu

import imu
import time

while True:
    print(imu.acceleration_mg())   # (x, y, z) in milli‑g
    print(imu.angular_rate_mdps()) # (x, y, z) in milli‑deg/s
    time.sleep_ms(100)

Wi‑Fi

Il CYW43439 integrato è esposto tramite network — configurazione di rete come interfaccia station. Dopo la connessione, ipconfig("addr4") restituisce la coppia (ip, netmask)

import network, time

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect("ssid", "password")
while not wlan.isconnected():
    time.sleep(1)
print("Wi‑Fi IP:", wlan.ipconfig("addr4")[0])

Bluetooth

Lo stesso CYW43439 espone anche il Bluetooth 5.1. Usa aioble — BLE asincrono per BLE compatibile con asyncio — per esempio, fai pubblicità come periferica e aspetta che un central si connetta:

import asyncio
import aioble

async def run():
    while True:
        conn = await aioble.advertise(250_000, name="OpenMV-N6")
        print("Connected:", conn.device)
        await conn.disconnected()

asyncio.run(run())

Ethernet

Quando un RJ45 (con magnetici) è collegato alle piazzole MDI, il PHY gigabit appare come interfaccia LAN. Il DHCP viene eseguito automaticamente non appena il link si attiva:

import network, time

lan = network.LAN()
lan.active(True)
while not lan.isconnected():
    time.sleep(1)
print("Ethernet IP:", lan.ipconfig("addr4")[0])

Scheda microSD

Quando viene inserita una scheda, questa viene montata automaticamente su /sdcard ed è utilizzabile tramite il normale file system:

import os

for entry in os.listdir("/sdcard"):
    print(entry)

Riferimento dei bus

GPIO

Usa machine.Pin per leggere o pilotare uno qualsiasi dei pin serigrafati. Le uscite sono CMOS a 3,3 V e possono assorbire/erogare fino a 20 mA per pin.

from machine import Pin

out = Pin("P0", Pin.OUT)
out.on()
out.off()
out.value(1)

inp = Pin("P1", Pin.IN, Pin.PULL_UP)
print(inp.value())

Qualsiasi pin di ingresso può anche generare un interrupt sulle transizioni di fronte:

def handler(pin):
    print("triggered:", pin)

Pin("P1", Pin.IN, Pin.PULL_UP).irq(
    handler, Pin.IRQ_FALLING | Pin.IRQ_RISING,
)

UART

Bus

TX

RX

UART3

P4

P5

UART4

P2

P3

UART7

P14

P13

from machine import UART

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

I²C

Bus

SCL

SDA

I2C2

P4

P5

from machine import I2C

i2c = I2C(2, freq=400_000)
i2c.scan()
i2c.writeto(0x76, b"hi")

Lo stesso hardware può essere usato anche in modalità target (slave) tramite machine.I2CTarget per esporre una regione di memoria a un altro controller I²C:

from machine import I2CTarget

buf = bytearray(32)
target = I2CTarget(2, addr=0x42, mem=buf)

SPI

Bus

MOSI

MISO

SCK

CS

SPI2

P0

P1

P2

P3

SPI4

P18

P17

P16

P15

from machine import SPI
from machine import Pin

spi = SPI(2, baudrate=10_000_000)
cs = Pin("P3", Pin.OUT, value=1)   # CS is not driven by the SPI peripheral

cs.value(0)
spi.write(b"hello")
cs.value(1)

CAN

Bus

TX

RX

CAN1

P2

P3

Nota

Il CAN non è ancora supportato su questa scheda nel firmware v5.0.0.

from machine import CAN

can = CAN(1, 500_000)
can.set_filters(None)
can.send(0x123, b"\xDE\xAD\xBE\xEF")
print(can.recv())

ADC

Entrambi i canali ADC passano attraverso un partitore di tensione bufferizzato con op‑amp prima di raggiungere l’MCU, quindi read_u16() è mappato su una diversa tensione di ingresso a fondo scala per ciascun pin.

Pin

Fondo scala

Note

P6_ADC

~3,3 V

piazzola generica, collegata internamente a P6

BAT_ADC

~5,0 V

canale interno per la batteria LiPo

from machine import ADC
import time

adc = ADC("P6_ADC")
bat = ADC("BAT_ADC")

while True:
    print("P6:", adc.read_u16() * 3.3 / 65535, "V")
    print("BAT:", bat.read_u16() * 5.0 / 65535, "V")
    time.sleep_ms(100)

PWM

Pin

Timer / canale

P4

TIM2 CH3

P5

TIM2 CH4

P6

TIM12 CH1

P7

TIM4 CH1

P8

TIM4 CH2

P9

TIM17 CH1

P10

TIM15 CH2

Pilotane uno qualsiasi tramite machine.PWM

from machine import Pin, PWM

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

Bus bit‑banged via software

machine.SoftI2C e machine.SoftSPI funzionano su qualsiasi GPIO se ti serve un bus aggiuntivo.

Sensore termico (esterno)

Il firmware include il driver fir — driver del sensore termico (fir == far infrared) per imager termici cablati esternamente:

  • MLX90621 — array IR 16 × 4

  • MLX90640 — array IR 32 × 24

  • MLX90641 — array IR 16 × 12

  • AMG8833 — array IR 8 × 8

Collega il modulo al bus I²C della scheda e leggi i frame con 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())

Il driver fir comunica con il sensore solo tramite I²C 2 — collega il modulo a P4 (SCL) e P5 (SDA).

Temporizzazione

time

Il modulo time copre i ritardi bloccanti, i tick monotoni e la misurazione del tempo trascorso:

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 virtuali

machine.Timer pianifica callback periodiche o one‑shot senza occupare uno slot di timer hardware. Passa -1 come id per usare un timer virtuale (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"))

I valori di periodo sono in millisecondi. Chiama deinit() per fermarlo e liberare lo slot.

Orologio in tempo reale

machine.RTC mantiene l’ora di sistema attraverso i reset e (con la batteria di backup opzionale da 3,3 V cablata alle piazzole posteriori, vedi Pin di alimentazione) attraverso la perdita totale di alimentazione:

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

L’RTC funziona anche durante il deep sleep, quindi puoi usarlo come sorgente di wakeup per machine.deepsleep().

Watchdog

machine.WDT resetta la scheda se l’applicazione si blocca. Una volta avviato non può essere fermato o riconfigurato — alimentalo periodicamente all’interno del tuo loop principale:

from machine import WDT

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

Informazioni su boot e runtime

Finestra del bootloader USB

A ogni accensione la camera esegue un breve bootloader (qualche secondo) che permette a OpenMV IDE di aggiornare il firmware senza che l’utente debba entrare in modalità DFU. Allo scadere della finestra il bootloader passa il controllo a boot.py e poi a main.py.

Uno script in esecuzione può rientrare nel bootloader su richiesta chiamando machine.bootloader()

import machine

machine.bootloader()

Filesystem e ordine di boot

Il firmware dell’N6 monta fino a tre filesystem all’avvio:

  • Flash interna — sempre montata su /flash. Contiene per impostazione predefinita main.py e README.txt; creata al primissimo avvio.

  • Scheda microSD — se è inserita una scheda, viene montata su /sdcard.

  • ROMFS — filesystem di sola lettura, mappato in memoria su /rom, usato per distribuire grandi asset di dati (per esempio modelli AI) che beneficiano dell’accesso zero‑copy. Montato automaticamente da MicroPython all’avvio, prima dell’esecuzione di qualsiasi codice Python utente.

Dopo il montaggio, la directory di lavoro viene impostata su /sdcard quando la scheda è presente, altrimenti su /flash. L’interprete esegue poi gli script da quella directory:

  • boot.py viene eseguito a ogni soft reset (avvio a freddo, Ctrl‑D dal REPL o ogni volta che lo script in esecuzione termina).

  • main.py viene eseguito solo all’avvio a freddo, subito dopo boot.py. I soft reset successivi rieseguono boot.py ma passano direttamente al REPL — per rieseguire main.py devi resettare completamente la scheda.

Inserire un boot.py o un main.py sulla scheda SD sovrascrive la copia in flash senza toccarla — entrambi i file vengono cercati nella directory di boot (/sdcard quando la scheda è montata, altrimenti /flash).

Il main.py predefinito fornito su una scheda appena flashata si limita a far lampeggiare il canale blu del LED RGB utente come heartbeat (due brevi impulsi, breve pausa), così puoi capire che il firmware si è avviato correttamente senza alcun host collegato.

sys.path viene esteso per includere tutti e tre i filesystem e le loro sottodirectory lib/, così i moduli importabili possono risiedere in /flash/lib, /sdcard/lib o /rom/lib.

Per forzare il sistema a ignorare una scheda SD inserita (per esempio per eseguire il main.py della flash anche con una scheda presente), crea un file vuoto chiamato SKIPSD nella radice di /flash.

Quando è connessa via USB, il filesystem di boot (/sdcard se è presente una scheda, altrimenti /flash) viene enumerato anche come unità di archiviazione di massa USB sull’host, permettendoti di modificare direttamente boot.py, main.py e qualsiasi altro file. Espelli l’unità prima di resettare la camera così che l’host scarichi le sue scritture in cache.

Nota

Poiché il sistema operativo tratta l’unità come un dispositivo a blocchi passivo, i file creati o modificati dal codice in esecuzione sull’OpenMV Cam non compariranno finché l’host non rimonta l’unità. Se sia il sistema operativo che l’OpenMV Cam scrivono sullo stesso filesystem contemporaneamente, il sistema operativo prevarrà e sovrascriverà le modifiche fatte dalla camera. Usa la scheda SD per qualsiasi dato che lo script scrive, e rimonta prima di leggere quei file dall’host.

Nota

Il canale rosso del LED RGB utente può accendersi brevemente mentre l’host legge o scrive sull’unità di archiviazione di massa USB — è un indicatore di attività pilotato dal firmware, non un guasto.

Dimensioni di archiviazione

L’N6 viene fornito con:

  • /flash — filesystem FAT da 4 MB, lettura/scrittura.

  • /rom — ROMFS di sola lettura mappato in memoria da 24 MB, usato per distribuire script e modelli ML che beneficiano dell’accesso mmap zero‑copy.

  • /sdcard — dimensione completa della scheda microSD inserita (quando presente), lettura/scrittura.

Indicatore di hard fault

Se il LED RGB utente sta ciclando rapidamente attraverso tutti i colori — abbastanza velocemente da sembrare un LED bianco scintillante anziché tinte distinte — il firmware ha incontrato un hard fault irrecuperabile. Riflasha il firmware per recuperare; se il riflash non aiuta, la scheda potrebbe essere danneggiata fisicamente.

Librerie software

Consulta l”indice delle librerie per l’elenco completo dei moduli — inclusi quelli esclusivi della build N6.