OpenMV N6

OpenMV N6 jest zbudowany wokół układu STMicroelectronics STM32N657 (Cortex‑M55 @ 800 MHz) z taktowanym 1 GHz wbudowanym NPU o wydajności 600 GOPS INT8. Płytka łączy NPU z sensorem global‑shutter PAG7936 1 MP na wymiennym module nośnym, gigabitowym Ethernetem, USB‑C high‑speed, Wi‑Fi oraz Bluetooth 5.1 i wykonuje wnioskowanie YOLOv8/YOLOv11 z prędkością 30 FPS równolegle ze strumieniowaniem obrazu na żywo.

OpenMV N6

Pełną dokumentację techniczną, zdjęcia i wymiary znajdziesz na stronie produktu OpenMV N6.

Najważniejsze cechy

  • STM32N657 Cortex‑M55 taktowany 800 MHz (1280 DMIPS) z ARM Helium 128‑bitowym SIMD — przepustowość wektorowa 6,4 gigaopów.

  • NPU 1 GHz, 600 GOPS INT8 — wykonuje wykrywanie YOLOv8/YOLOv11 z prędkością 30 FPS.

  • ISP dla surowego obrazu Bayer RAW do 5MP, 2D GPU do skalowania i obrotu 3D, enkoder H.264 do 1080p oraz sprzętowy kodek JPEG.

  • 64 MB zewnętrznej pamięci SDRAM (16‑bit @ 200 MHz DDR, 800 MB/s) oraz 4,2 MB wewnętrznej pamięci SRAM i 32 MB pamięci octal flash (200 MHz DDR, 400 MB/s).

  • PAG7936 — kolorowy sensor global‑shutter 1 MP.

  • Wbudowane IMU (akcelerometr + żyroskop) oraz mikrofon do fuzji dźwięku i ruchu.

  • USB‑C high‑speed (480 Mb/s, limit prądu 1,5 A), gigabitowy Ethernet (obsługa PoE poprzez shield), Wi‑Fi a/b/g/n + Bluetooth 5.1 (antena na układzie lub opcjonalnie U.FL).

  • Gniazdo microSD — SD do 2 GB, SDHC do 32 GB, SDXC do 2 TB.

  • Ładowarka LiPo (szybkie ładowanie 500 mA), ADC napięcia baterii, RTC z 8 KB podtrzymywanej pamięci RAM oraz dedykowany pin baterii podtrzymującej.

  • 18 pinów I/O, wszystkie z wyjściem 3,3 V / tolerancją 3,3 V, 20 mA na pin, z obsługą przerwań.

  • Użytkowa dioda RGB LED, przycisk użytkownika oraz osobna dioda statusu dla ładowania / USB / zasilania VIN.

Ostrzeżenie

Piny I/O modelu N6 nie tolerują 5 V. Nie podłączaj urządzenia bezpośrednio do mikrokontrolera 5 V, takiego jak Arduino Mega. Zasilaj N6 wyłącznie przez VIN.

Rozmieszczenie wyprowadzeń

Rozmieszczenie wyprowadzeń OpenMV N6 PAG7936

Opis wyprowadzeń

Nazwa pinu

Funkcja

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 (brak ADC na tym pinie — zobacz P6_ADC)

P6_ADC

dedykowane 12‑bitowe wejście ADC (połączone wewnętrznie z P6)

P7

TIM4 CH1

P8

TIM4 CH2

P9

TIM17 CH1

P10

TIM15 CH2 / I/O synchronizacji ramki

P11

wybudzanie (aktywny stan niski, WKUP3)

P12

RESET — zwarcie do GND resetuje płytkę (nie jest to GPIO)

P13

UART7 RX

P14

UART7 TX

P15

SPI4 CS

P16

SPI4 SCK

P17

SPI4 MISO

P18

SPI4 MOSI

SW

przycisk użytkownika (aktywny stan niski)

ONOFF (SW2)

przycisk wybudzania z głębokiego uśpienia (aktywny stan niski, WKUP2)

ST

niski przy zasilaniu z VIN, wysoki przy zasilaniu z USB

CHG

aktywny w stanie niskim; niski podczas ładowania podłączonej baterii LiPo

PG

aktywny w stanie niskim; niski gdy obecne jest zasilanie VIN lub USB

BAT_ADC

wewnętrzny kanał ADC mierzący napięcie podłączonej baterii LiPo

LED_RED

czerwony kanał diody RGB LED (aktywny stan niski)

LED_GREEN

zielony kanał diody RGB LED (aktywny stan niski)

LED_BLUE

niebieski kanał diody RGB LED (aktywny stan niski)

Informacja

Linia synchronizacji ramki P10 jest współdzieloną magistralą. Jest podłączona jednocześnie do mikrokontrolera, pinu wyzwalania / ekspozycji sensora kamery oraz do złącza użytkownika. Kierunek jest definiowany przez aplikację — linię może sterować mikrokontroler, sensor lub sygnał zewnętrzny, w zależności od konfiguracji sensora (niektóre sensory mogą używać tego samego pinu jako wejścia wyzwalania lub wyjścia ekspozycji). Upewnij się, że w danej chwili aktywny jest tylko jeden sterownik.

Informacja

ONOFF i P11 są odniesione do zawsze aktywnej szyny RAW (a nie do przełączanej szyny 3,3 V), więc pozostają funkcjonalne, gdy reszta płytki znajduje się w trybie głębokiego uśpienia / niskiego poboru mocy. Oba wejścia są aktywne w stanie niskim.

Piny te przechodzą przez konwertery poziomów, dzięki czemu mogą pracować na szynie RAW. Jeśli koniecznie potrzebujesz zachowania GPIO bezpośrednio na 3,3 V na ONOFF lub P11 (na przykład aby sterować nimi z mikrokontrolera 3,3 V bez przechodzenia przez konwerter), płytka udostępnia pola lutownicze podciągające oraz zworki 0‑omowe pozwalające ominąć konwerter. Jest to zaawansowana modyfikacja sprzętowa — większość użytkowników powinna pozostawić ją bez zmian.

Informacja

Piny P15–P18 są współdzielone z gigabitowym PHY Ethernet, który jest podłączony i domyślnie aktywny. Aby używać tych pinów jako I/O użytkownika, należy przelutować rezystor 0‑omowy z tyłu płytki do pozycji GPIO. Wyłącza to wyłącznie gigabitowy Ethernet — Ethernet 10/100 Mb/s nadal działa na swoich dedykowanych pinach.

Piny zasilania

  • 3.3V — stabilizowana szyna 3,3 V. Tylko wyjście w modelu N6 — nie podawaj zasilania zewnętrznego na ten pin. Dostępne do 1 A dla shieldów.

  • VIN — wejście 5 V. Zasila płytkę oraz wbudowaną ładowarkę LiPo.

  • RAW — wejście/wyjście, zawsze aktywne (3,6 V – 5 V). Przenosi aktywne w danej chwili źródło (VIN, USB lub podłączoną baterię) i może też służyć jako wejście. Podając zasilanie na RAW, musisz sterować nim przez diodę szeregową — w przeciwnym razie prąd popłynie z powrotem do VIN/USB i uszkodzi zasilanie lub wbudowane zabezpieczenia.

  • GND — wspólna masa.

Informacja

Wbudowany układ zarządzania zasilaniem automatycznie wybiera wyższe z napięć USB lub VIN do zasilania płytki oraz ładowarki baterii. Jeśli podłączona jest bateria LiPo, jest ona ładowana z pozostałego zapasu mocy, a sterownik przełącza się na baterię, aby utrzymać działanie płytki, gdy VIN/USB spadnie lub zostanie odłączone.

Informacja

Z tyłu płytki znajdują się pola lutownicze dla zewnętrznej baterii podtrzymującej RTC 3,3 V. Podłączenie do nich baterii pastylkowej utrzymuje działanie RTC oraz 8 KB pamięci podtrzymywanej, gdy reszta płytki jest pozbawiona zasilania.

Wskazówka

Skorzystaj z kalkulatora żywotności baterii, aby oszacować, jak długo N6 będzie działać na baterii przy zadanym cyklu pracy aktywnej / głębokiego uśpienia.

Piny Ethernet

N6 udostępnia pary MDI układu PHY Ethernet na dedykowanych polach obok złącza GPIO. Pinów MDI nie wolno podłączać bezpośrednio do gniazda RJ45 — między PHY a kablem wymagane są elementy magnetyczne Ethernet (transformator izolujący, wbudowany w magjack lub umieszczony na shieldzie). Shield OpenMV PoE zawiera je; jeśli budujesz własne gniazdo, użyj RJ45 ze zintegrowanymi elementami magnetycznymi lub zewnętrznego transformatora.

  • ETH_LED — dioda statusu połączenia/aktywności. Aktywna w stanie niskim, gdy połączenie jest nawiązane; miga przy ruchu sieciowym.

  • DA P / DA N — para A (TX w 10/100, używana przy wszystkich prędkościach).

  • DB P / DB N — para B (RX w 10/100, używana przy wszystkich prędkościach).

  • DC P / DC N — para C, używana tylko przy gigabicie.

  • DD P / DD N — para D, używana tylko przy gigabicie.

10/100 Mb/s wymaga tylko par A i B. Gigabit wymaga wszystkich czterech par A–D.

Piny odzyskiwania i debugowania

  • RESET — zwarcie do GND resetuje płytkę. Zwolnienie pozwala mikrokontrolerowi normalnie się uruchomić.

  • BOOT0 — podciągnięcie do 3,3 V podczas włączania płytki uruchamia tryb bootloadera ROM. OpenMV IDE używa tego trybu do przeprogramowania wbudowanego bootloadera.

  • BOOT1 — przełącznik wprowadzający płytkę w tryb deweloperski do użytku z narzędziami ST (ST‑LINK podłączony do złącza ARM 10‑pin SWD/JTAG). Pozostaw go wyłączony przy normalnej pracy z oprogramowaniem układowym i narzędziami OpenMV.

Zamontowane jest dedykowane złącze ARM 10‑pin SWD/JTAG, zgodne z adapterami ST‑LINK oraz SEGGER J‑Link.

Wbudowane urządzenia peryferyjne

Diody LED

N6 posiada dwie diody RGB LED:

  • Użytkowa dioda RGB LED — sterowana programowo, udostępniona jako LED_RED, LED_GREEN i LED_BLUE

    from machine import LED
    
    LED("LED_RED").on()
    LED("LED_GREEN").on()
    LED("LED_BLUE").on()
    
  • Dioda zasilania — sterowana bezpośrednio przez wbudowany sprzęt zarządzania zasilaniem, bez sterowania programowego. Użyj jej, aby na pierwszy rzut oka odczytać stan zasilania.

    Podczas pracy:

    Kanał

    Znaczenie

    Niebieski

    VIN zasila płytkę (zgaszony przy USB)

    Zielony

    obecne zasilanie USB lub VIN

    Czerwony

    ładowanie podłączonej baterii LiPo

    W głębokim uśpieniu wszystkie kanały są zgaszone z wyjątkiem czerwonego, który nadal świeci podczas ładowania baterii LiPo.

Przyciski użytkownika

N6 posiada dwa przyciski:

  • SW — przycisk użytkownika ogólnego przeznaczenia. Aktywny po zwarciu do masy.

  • ONOFF (SW2) — przycisk wybudzania. Jedyny przycisk, który może wyprowadzić płytkę z głębokiego uśpienia.

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

Aby wprowadzić płytkę w głębokie uśpienie i pozwolić, by ONOFF (SW2) ją wybudził, wystarczy wywołać machine.deepsleep() — nie jest wymagana żadna konfiguracja wybudzania, przycisk jest podłączony bezpośrednio do wejścia WKUP2:

import machine

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

Możesz również podłączyć ONOFF jako programowy włącznik zasilania. Wyzwalaj na narastającym zboczu — linia ustala się w stanie wysokim po zwolnieniu przycisku przez użytkownika, więc kolejne naciśnięcie jest jednoznacznie zdarzeniem wybudzenia:

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.

Piny statusu zasilania

Trzy wejścia statusu aktywne w stanie niskim pozwalają oprogramowaniu układowemu sprawdzić, co robi wbudowany układ zarządzania zasilaniem:

  • ST — niski, gdy płytka pracuje na VIN, wysoki, gdy pracuje na zasilaniu USB.

  • CHG — niski podczas ładowania podłączonej baterii LiPo.

  • PG — niski, gdy obecne jest zasilanie VIN lub 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()

Sensor kamery

PAG7936 jest sterowany przez moduł csi — sensory kamery

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

Sensor znajduje się na wymiennym module — wymień go na dowolny z innych modułów kamery OpenMV (global shutter, termowizyjny, wyższej rozdzielczości itp.) bez zmiany reszty płytki.

PAG7936 obsługuje tryb wyzwalany — integracja pikseli jest precyzyjnie zsynchronizowana z każdym wywołaniem csi.CSI.snapshot zamiast z wolnobieżnym zegarem ramki, co jest przydatne do synchronizacji przechwytywania ze zdarzeniem zewnętrznym lub innym sensorem. Włącz go przez csi.CSI.ioctl z csi.IOCTL_SET_TRIGGERED_MODE. Liczba klatek spada do około połowy trybu wolnobieżnego, ponieważ odczyt nie nakłada się już potokowo z integracją kolejnej ramki:

cam.ioctl(csi.IOCTL_SET_TRIGGERED_MODE, True)

NPU

Taktowane 1 GHz NPU Neural‑ART modelu N6 (600 GOPS INT8) jest udostępnione przez moduł ml — Uczenie maszynowe. Modele przechowywane w systemie plików tylko do odczytu /rom ładują się bezpośrednio z pamięci flash bez kopiowania do RAM, więc nawet duże detektory mieszczą się wygodnie obok bufora ramki obrazu na żywo. Uruchom detektor YOLOv8 na każdej ramce i nanieś predykcje na obraz na żywo:

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

Mikrofon

Wbudowany mikrofon jest przechwytywany przez audio — Moduł Audio. Każdy bufor przychodzi jako 16‑bitowy ze znakiem PCM bytearray, co sprawia, że przekazanie go do ulab/numpy w celu szybkiego DSP jest banalne. Prosty detektor głośności — drukuje za każdym razem, gdy głośność RMS przekroczy próg:

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

Wbudowany akcelerometr + żyroskop pod modułem kamery jest udostępniony przez imu — sensor 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

Wbudowany CYW43439 jest udostępniony przez network — konfiguracja sieci jako interfejs stacji. Po połączeniu ipconfig("addr4") zwraca parę (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

Ten sam CYW43439 udostępnia również Bluetooth 5.1. Użyj aioble — Asynchroniczne BLE do przyjaznego dla asyncio BLE — na przykład rozgłaszaj się jako urządzenie peryferyjne i czekaj na połączenie ze strony centrali:

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

Gdy do pól MDI podłączone jest RJ45 (z elementami magnetycznymi), gigabitowy PHY pojawia się jako interfejs LAN. DHCP uruchamia się automatycznie po nawiązaniu połączenia:

import network, time

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

Karta microSD

Po włożeniu karta jest montowana automatycznie w /sdcard i jest dostępna przez zwykły system plików:

import os

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

Opis magistral

GPIO

Użyj machine.Pin, aby odczytać lub sterować dowolnym z opisanych na płytce pinów. Wyjścia to 3,3 V CMOS i mogą pobierać/dostarczać do 20 mA na 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())

Dowolny pin wejściowy może również wyzwolić przerwanie na zboczu sygnału:

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

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

UART

Magistrala

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

Magistrala

SCL

SDA

I2C2

P4

P5

from machine import I2C

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

Ten sam sprzęt może być również użyty w trybie docelowym (slave) przez machine.I2CTarget, aby udostępnić obszar pamięci innemu kontrolerowi I²C:

from machine import I2CTarget

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

SPI

Magistrala

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

Magistrala

TX

RX

CAN1

P2

P3

Informacja

CAN nie jest jeszcze obsługiwany na tej płytce w oprogramowaniu układowym 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

Oba kanały ADC przechodzą przez dzielnik napięcia buforowany wzmacniaczem operacyjnym, zanim dotrą do mikrokontrolera, więc read_u16() jest odwzorowane na inne napięcie wejściowe pełnej skali na każdym pinie.

Pin

Pełna skala

Uwagi

P6_ADC

~3,3 V

pole ogólnego przeznaczenia, połączone wewnętrznie z P6

BAT_ADC

~5,0 V

wewnętrzny kanał dla baterii 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

Licznik czasu (timer) / kanał

P4

TIM2 CH3

P5

TIM2 CH4

P6

TIM12 CH1

P7

TIM4 CH1

P8

TIM4 CH2

P9

TIM17 CH1

P10

TIM15 CH2

Steruj dowolnym z nich przez machine.PWM

from machine import Pin, PWM

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

Programowo emulowane magistrale (bit‑bang)

machine.SoftI2C oraz machine.SoftSPI działają na dowolnym GPIO, jeśli potrzebujesz dodatkowej magistrali.

Sensor termowizyjny (zewnętrzny)

Oprogramowanie układowe zawiera sterownik fir — sterownik sensora termicznego (fir == far infrared, daleka podczerwień) dla zewnętrznie podłączonych kamer termowizyjnych:

  • MLX90621 — matryca IR 16 × 4

  • MLX90640 — matryca IR 32 × 24

  • MLX90641 — matryca IR 16 × 12

  • AMG8833 — matryca IR 8 × 8

Podłącz moduł do magistrali I²C płytki i odczytuj ramki za pomocą 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())

Sterownik fir komunikuje się z sensorem wyłącznie przez I²C 2 — podłącz moduł do P4 (SCL) i P5 (SDA).

Synchronizacja czasowa

time

Moduł time obsługuje blokujące opóźnienia, monotoniczne tyknięcia oraz pomiar upływającego czasu:

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)

Wirtualne liczniki czasu (timery)

machine.Timer planuje okresowe lub jednorazowe wywołania zwrotne bez zajmowania sprzętowego slotu licznika czasu. Przekaż -1 jako id, aby użyć wirtualnego (programowego) licznika czasu:

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

Wartości okresu podawane są w milisekundach. Wywołaj deinit(), aby zatrzymać i zwolnić slot.

Zegar czasu rzeczywistego

machine.RTC utrzymuje czas zegarowy podczas resetów oraz (z opcjonalną baterią podtrzymującą 3,3 V podłączoną do tylnych pól, zobacz Piny zasilania) podczas całkowitego zaniku zasilania:

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

RTC działa również podczas głębokiego uśpienia, dzięki czemu możesz użyć go jako źródła wybudzenia dla machine.deepsleep().

Watchdog

machine.WDT resetuje płytkę, jeśli aplikacja się zawiesi. Po uruchomieniu nie można go zatrzymać ani przekonfigurować — odświeżaj go okresowo wewnątrz swojej głównej pętli:

from machine import WDT

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

Informacje o rozruchu i czasie działania

Okno bootloadera USB

Przy każdym włączeniu kamera uruchamia krótki bootloader (kilka sekund), który pozwala OpenMV IDE zaktualizować oprogramowanie układowe bez konieczności wchodzenia przez użytkownika w tryb DFU. Po wygaśnięciu okna bootloader przekazuje sterowanie do boot.py, a następnie main.py.

Działający skrypt może na żądanie ponownie wejść do bootloadera, wywołując machine.bootloader()

import machine

machine.bootloader()

System plików i kolejność rozruchu

Oprogramowanie układowe N6 montuje przy rozruchu do trzech systemów plików:

  • Wewnętrzna pamięć flash — zawsze montowana w /flash. Domyślnie przechowuje main.py i README.txt; tworzona przy pierwszym rozruchu.

  • Karta microSD — jeśli karta jest włożona, jest montowana w /sdcard.

  • ROMFS — system plików tylko do odczytu, mapowany w pamięci, w /rom, używany do dostarczania dużych zasobów danych (np. modeli AI), które korzystają z dostępu bez kopiowania. Montowany automatycznie przez MicroPython przy starcie, zanim uruchomi się jakikolwiek kod Python użytkownika.

Po zamontowaniu katalog roboczy jest ustawiany na /sdcard, gdy karta jest obecna, w przeciwnym razie na /flash. Interpreter uruchamia następnie skrypty z tego katalogu:

  • boot.py jest wykonywany przy każdym miękkim resecie (zimny rozruch, Ctrl‑D z REPL lub za każdym razem, gdy działający skrypt zakończy działanie).

  • main.py jest wykonywany tylko przy zimnym rozruchu, bezpośrednio po boot.py. Kolejne miękkie resety ponownie uruchamiają boot.py, ale przechodzą prosto do REPL — aby ponownie uruchomić main.py, musisz w pełni zresetować płytkę.

Umieszczenie boot.py lub main.py na karcie SD nadpisuje kopię w pamięci flash bez jej naruszania — oba pliki są wyszukiwane w katalogu rozruchowym (/sdcard, gdy karta jest zamontowana, w przeciwnym razie /flash).

Domyślny main.py dostarczany na świeżo przeprogramowanej płytce po prostu miga niebieskim kanałem użytkowej diody RGB LED jako sygnał działania (dwa krótkie błyski, krótka przerwa), więc możesz stwierdzić, że oprogramowanie układowe uruchomiło się poprawnie bez podłączonego hosta.

sys.path jest rozszerzony o wszystkie trzy systemy plików oraz ich podkatalogi lib/, dzięki czemu importowalne moduły mogą znajdować się w /flash/lib, /sdcard/lib lub /rom/lib.

Aby zmusić system do ignorowania włożonej karty SD (na przykład w celu uruchomienia main.py z pamięci flash mimo obecnej karty), utwórz pusty plik o nazwie SKIPSD w katalogu głównym /flash.

Po podłączeniu przez USB rozruchowy system plików (/sdcard, jeśli karta jest obecna, w przeciwnym razie /flash) jest również wykrywany na hoście jako dysk pamięci masowej USB, co pozwala bezpośrednio edytować boot.py, main.py oraz wszelkie inne pliki. Wysuń dysk przed zresetowaniem kamery, aby host opróżnił buforowane zapisy.

Informacja

Ponieważ system operacyjny traktuje dysk jako pasywne urządzenie blokowe, pliki utworzone lub zmodyfikowane przez kod działający na OpenMV Cam nie pojawią się, dopóki host ponownie nie zamontuje dysku. Jeśli zarówno system operacyjny, jak i OpenMV Cam zapisują ten sam system plików w tym samym czasie, system operacyjny wygra i nadpisze zmiany wprowadzone przez kamerę. Używaj karty SD dla wszelkich danych zapisywanych przez skrypt i ponownie montuj ją przed odczytem tych plików z hosta.

Informacja

Czerwony kanał użytkowej diody RGB LED może na krótko zaświecić się, gdy host odczytuje z dysku pamięci masowej USB lub na niego zapisuje — jest to sterowany przez oprogramowanie układowe wskaźnik aktywności, a nie usterka.

Rozmiary pamięci masowej

N6 jest dostarczany z:

  • /flash — system plików FAT o pojemności 4 MB, do odczytu/zapisu.

  • /rom — mapowany w pamięci ROMFS tylko do odczytu o pojemności 24 MB, używany do dostarczania skryptów i modeli ML, które korzystają z dostępu mmap bez kopiowania.

  • /sdcard — pełny rozmiar włożonej karty microSD (gdy jest obecna), do odczytu/zapisu.

Wskaźnik twardego błędu (hard fault)

Jeśli użytkowa dioda RGB LED szybko przełącza się przez wszystkie kolory — na tyle szybko, że zwykle wygląda jak migoczący biały LED, a nie odrębne barwy — oznacza to, że oprogramowanie układowe napotkało nieodwracalny twardy błąd (hard fault). Przeprogramuj oprogramowanie układowe, aby odzyskać sprawność; jeśli przeprogramowanie nie pomaga, płytka może być fizycznie uszkodzona.

Biblioteki programowe

Pełną listę modułów — w tym te unikalne dla wersji N6 — znajdziesz w indeksie bibliotek.