OpenMV Cam M4¶
OpenMV Cam M4 to kompaktowa płytka wizji maszynowej oparta na rdzeniu Cortex‑M4, zbudowana wokół układu STMicroelectronics STM32F427 taktowanego zegarem 180 MHz, z 256 KB wewnętrznej pamięci SRAM i 1 MB wewnętrznej pamięci flash. Dołączony sensor OV7725 przechwytuje ramki 320×240 w skali szarości lub RGB565, a 9‑pinowe złącze użytkownika udostępnia urządzenia peryferyjne UART, I²C, SPI, CAN, ADC/DAC i PWM.
Informacja
OV7725 był standardowym sensorem w produkcyjnych płytkach M4. Bardzo wczesne warianty M4 były dostarczane z układem OmniVision OV2640 — z tym samym potokiem podglądu QVGA, ale OV2640 może dodatkowo przechwytywać ramki JPEG o rozdzielczości do UXGA (1600×1200). Oba sensory są obsługiwane przez to samo API csi — sensory kamery.
Pełną kartę katalogową, zdjęcia i wymiary znajdziesz na stronie produktu OpenMV Cam M4.
Najważniejsze cechy¶
STMicroelectronics STM32F427 Cortex‑M4 taktowany zegarem 180 MHz.
256 KB wewnętrznej pamięci SRAM — brak zewnętrznej pamięci SDRAM.
1 MB wewnętrznej pamięci flash (brak zewnętrznej pamięci flash QSPI).
Sensor OV7725 (lub OV2640 w bardzo wczesnych wariantach M4) — 320×240 w 8‑bitowej skali szarości lub RGB565; OV2640 może dodatkowo przechwytywać obraz JPEG o rozdzielczości do UXGA (1600×1200).
USB Full‑speed (12 Mb/s) — widoczne dla hosta jako VCP + pamięć masowa USB.
Gniazdo microSD — SD do 2 GB, SDHC do 32 GB, SDXC do 2 TB.
9 pinów I/O, tolerancja 5 V z wyjściem 3,3 V, 25 mA na pin (łącznie 120 mA na całym złączu), z obsługą przerwań. P6 nie toleruje 5 V, gdy jest używany w trybie ADC lub DAC.
Dioda LED RGB użytkownika oraz dwie diody LED IR 850 nm dużej mocy do aktywnego oświetlenia w warunkach słabego światła.
Informacja
M4 nie ma wbudowanego układu zarządzania zasilaniem: nie ma złącza baterii, ładowarki baterii, ADC napięcia baterii, diod LED stanu ładowania / zasilania ani sprzętowego przycisku zasilania. Płytkę zasilaj przez USB lub VIN.
Rozkład pinów¶
Opis pinów¶
Nazwa pinu |
Funkcja |
|---|---|
P0 |
SPI2 MOSI |
P1 |
SPI2 MISO |
P2 |
SPI2 SCK / CAN2 TX |
P3 |
SPI2 NSS (CS) / CAN2 RX |
P4 |
I2C2 SCL / UART3 TX / TIM2 CH3 |
P5 |
I2C2 SDA / UART3 RX / TIM2 CH4 |
P6 |
ADC / DAC / TIM2 CH1 |
P7 |
TIM4 CH1 |
P8 |
TIM4 CH2 |
RESET |
zewrzyj do GND, aby zresetować płytkę |
BOOT0 |
podciągnij do 3,3 V przy włączaniu zasilania, aby uruchomić DFU / bootloader ROM |
SWCLK |
zegar ARM SWD (dostęp dla debugera) |
SWDIO |
dane ARM SWD (dostęp dla debugera) |
LED_RED |
kanał czerwony diody LED RGB (aktywny stanem niskim) |
LED_GREEN |
kanał zielony diody LED RGB (aktywny stanem niskim) |
LED_BLUE |
kanał niebieski diody LED RGB (aktywny stanem niskim) |
LED_IR |
diody LED IR dużej mocy (oba kanały sterowane razem) |
Piny zasilania¶
3.3V — stabilizowana szyna 3,3 V. Dostępne do 250 mA dla rozszerzeń (mniej, jeśli używana jest karta microSD). W odróżnieniu od nowszych kamer ten pin jest dwukierunkowy — zobacz ostrzeżenie poniżej.
VIN — wejście 3,6 – 5 V. Zasila płytkę przez wbudowany stabilizator.
GND — wspólna masa.
Informacja
Gdy obecne są jednocześnie USB i VIN, płytkę zasila to źródło, które ma wyższe napięcie — wbudowane diody po prostu wybierają mocniejszą szynę.
Ostrzeżenie
Możesz zasilać M4, podając 3,3 V bezpośrednio na pin 3.3V, jeśli nie chcesz korzystać z wbudowanego stabilizatora. W takim przypadku nie podawaj jednocześnie zasilania VIN ani USB — wsteczne zasilanie stabilizatora, gdy aktywne jest inne źródło, może trwale uszkodzić i zniszczyć kamerę.
Wskazówka
Skorzystaj z kalkulatora czasu pracy baterii, aby oszacować, jak długo M4 będzie działać na baterii przy danym cyklu pracy aktywny / głęboki uśpienie.
Piny odzyskiwania i debugowania¶
RESET — zewrzyj do GND, aby zresetować płytkę. Zwolnienie pozwala MCU uruchomić się normalnie.
BOOT0 — podciągnij do 3,3 V podczas zasilania płytki, aby wejść w bootloader ROM STM32 (tryb DFU). OpenMV IDE używa tego trybu do ponownego programowania wbudowanego bootloadera.
SWCLK i SWDIO są wyprowadzone jako zwykłe piny złącza (nie jako dedykowane złącze SWD). Podłącz RESET, SWCLK, SWDIO, GND i 3,3 V do adaptera ST‑LINK lub SEGGER J‑Link, aby debugować płytkę.
Wbudowane urządzenia peryferyjne¶
Diody LED¶
M4 ma pojedynczą diodę LED RGB użytkownika oraz parę diod LED IR 850 nm dużej mocy:
Dioda LED RGB użytkownika — sterowana programowo, udostępniona jako
LED_RED,LED_GREENiLED_BLUEfrom machine import LED LED("LED_RED").on() LED("LED_GREEN").on() LED("LED_BLUE").on()
Diody LED IR — obie diody są sterowane razem przez pin
LED_IR.LED_IRjest sprzętowo połączony jako aktywny stanem wysokim, podczas gdy oprogramowanie układowe traktuje każdą inną wbudowaną diodę LED jako aktywną stanem niskim, więc użyjlow()/high()zamiaston()/off()(które odwróciłyby logikę):from machine import LED ir = LED("LED_IR") ir.low() # turn IR illumination ON ir.high() # turn IR illumination OFF
Sensor kamery¶
Dołączony sensor (OV7725 na standardowych płytkach, OV2640 na bardzo wczesnych wariantach) jest obsługiwany przez moduł csi — sensory kamery
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()
Sensor w M4 jest przylutowany do płytki — nie znajduje się na wymiennym module.
Informacja
Na płytkach OV7725 pin FSIN (synchronizacji ramki) sensora jest podłączony do MCU, ale obsługa w oprogramowaniu układowym nie została dodana.
Na płytkach OV2640 piny sensora STROBE, FREX (ekspozycja ramki) i EXPST (reset ekspozycji) są podłączone do MCU, ale obsługa w oprogramowaniu układowym nie została dla nich dodana.
Złącza serwo¶
Na tylnej stronie płytki znajdują się dwa pola lutownicze złączy serwo, które wyprowadzają standardowe 3‑pinowe złącze serwo (sygnał / VIN / GND) dla P7 i P8. Piny sygnałowe są mapowane bezpośrednio na kanały 1 i 2 TIM4 (te same kanały, których używa pyb.Servo), a pin V+ na każdym złączu jest podłączony bezpośrednio do VIN, więc serwa pobierają prąd z szyny wejściowej, a nie ze stabilizatora 3,3 V.
Wlutuj parę kątowych 3‑pinowych złączy w pola lutownicze i podłącz dwa serwa modelarskie, aby sterować uchwytem typu pan‑and‑tilt:
from pyb import Servo
pan = Servo(1) # P7 — TIM4 CH1
tilt = Servo(2) # P8 — TIM4 CH2
pan.angle(0)
tilt.angle(0)
Karta microSD¶
Po włożeniu karty jest ona automatycznie montowana w /sdcard i można jej używać przez zwykły system plików:
import os
for entry in os.listdir("/sdcard"):
print(entry)
Opis magistral¶
GPIO¶
Użyj machine.Pin, aby odczytywać lub sterować dowolnym z opisanych na nadruku pinów. Wyjścia są typu 3,3 V CMOS, tolerują 5 V po stronie wejścia i mogą pobierać/dostarczać do 25 mA na pin (łącznie 120 mA na całym złączu).
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())
Każdy pin wejściowy może też wyzwalać przerwanie przy zmianach zbocza:
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 |
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żywany w trybie urządzenia docelowego (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 |
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 |
|---|---|---|
CAN2 |
P2 |
P3 |
from machine import CAN
can = CAN(2, 500_000)
can.set_filters(None)
can.send(0x123, b"\xDE\xAD\xBE\xEF")
print(can.recv())
ADC i DAC¶
P6 jest jedynym analogowym pinem użytkownika. Może być używany jako 12‑bitowe wejście ADC lub wyjście DAC.
ADC — pełna skala przy 3,3 V na pinie:
from machine import ADC import time adc = ADC("P6") while True: voltage = adc.read_u16() * 3.3 / 65535 print(voltage) time.sleep_ms(100)
DAC — przez
pyb.DAC. Wartość 8‑bitowa obejmuje zakres 0–3,3 V:from pyb import DAC dac = DAC("P6") voltage = 1.65 dac.write(int(voltage / 3.3 * 255))
W trybie ADC lub DAC P6 toleruje tylko 3,3 V — nie podawaj na niego 5 V.
PWM¶
Pin |
Licznik czasu / kanał |
|---|---|
P4 |
TIM2 CH3 |
P5 |
TIM2 CH4 |
P6 |
TIM2 CH1 |
P7 |
TIM4 CH1 |
P8 |
TIM4 CH2 |
Informacja
TIM1 jest zarezerwowany przez oprogramowanie układowe do generowania zegara pikseli sensora kamery, więc kanały TIM1 fizycznie obecne na P0/P1/P2 nie mogą być używane do PWM użytkownika bez zakłócenia działania kamery.
TIM4 jest współdzielony z pyb.Servo — utworzenie instancji serwa rekonfiguruje cały licznik czasu do pracy z częstotliwością 50 Hz, więc nie mieszaj machine.PWM na P7/P8 z pyb.Servo w tym samym skrypcie.
Steruj dowolnym z nich przez machine.PWM
from machine import Pin, PWM
pwm = PWM(Pin("P7"), freq=1_000, duty_u16=32768)
Programowo emulowane magistrale (bit‑bang)¶
machine.SoftI2C i machine.SoftSPI działają na dowolnym GPIO, jeśli potrzebujesz dodatkowej magistrali.
Sensor termiczny (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).
Pomiar czasu¶
time¶
Moduł time obejmuje blokujące opóźnienia, monotoniczne takty 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¶
machine.Timer planuje okresowe lub jednorazowe wywołania zwrotne bez zajmowania slotu sprzętowego 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 są podawane w milisekundach. Wywołaj deinit(), aby zatrzymać i zwolnić slot.
Zegar czasu rzeczywistego¶
machine.RTC utrzymuje czas zegarowy pomiędzy resetami:
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 resetuje płytkę, jeśli aplikacja się zawiesi. Po uruchomieniu nie można go zatrzymać ani zmienić jego konfiguracji — karm go okresowo wewnątrz 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 wykonania¶
Okno bootloadera USB¶
Przy każdym włączeniu zasilania 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 upływie tego okna bootloader przekazuje sterowanie do boot.py, a następnie do main.py.
Działający skrypt może ponownie wejść w bootloader na żądanie, wywołując machine.bootloader()
import machine
machine.bootloader()
System plików i kolejność rozruchu¶
Oprogramowanie układowe M4 montuje przy rozruchu do trzech systemów plików:
Wewnętrzna pamięć flash — zawsze montowana w
/flash. Domyślnie przechowujemain.pyiREADME.txt; tworzona przy pierwszym rozruchu.Karta microSD — jeśli karta jest włożona, jest montowana w
/sdcard.ROMFS — tylko do odczytu, mapowany w pamięci system plików w
/rom, używany do dostarczania dużych zasobów danych (np. modeli AI), które korzystają z dostępu bez kopiowania (zero‑copy). Montowany automatycznie przez MicroPython przy starcie, przed uruchomieniem jakiegokolwiek kodu 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.pyjest wykonywany przy każdym miękkim resecie (zimny rozruch,Ctrl‑Dz REPL lub za każdym razem, gdy działający skrypt zwróci sterowanie).main.pyjest wykonywany tylko przy zimnym rozruchu, bezpośrednio poboot.py. Kolejne miękkie resety ponownie uruchamiająboot.py, ale przechodzą od razu 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 zaprogramowanej płytce po prostu miga niebieskim kanałem diody LED RGB użytkownika jako sygnał pulsu (dwa krótkie impulsy, krótka przerwa), dzięki czemu możesz stwierdzić, że oprogramowanie układowe uruchomiło się poprawnie, bez podłączania jakiegokolwiek hosta.
sys.path jest rozszerzony tak, aby obejmował wszystkie trzy systemy plików i ich podkatalogi lib/, więc 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 by uruchomić main.py z pamięci flash nawet przy obecnej karcie), 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ż wyliczany na hoście jako napęd pamięci masowej USB, co pozwala edytować boot.py, main.py i wszelkie inne pliki bezpośrednio. Wysuń napęd przed zresetowaniem kamery, aby host opróżnił buforowane zapisy.
Informacja
Ponieważ system operacyjny traktuje napęd jako pasywne urządzenie blokowe, pliki utworzone lub zmodyfikowane przez kod działający na OpenMV Cam nie pojawią się, dopóki host nie zamontuje ponownie napędu. Jeśli zarówno system operacyjny, jak i OpenMV Cam zapisują do tego samego systemu plików jednocześnie, system operacyjny wygra i nadpisze zmiany wprowadzone przez kamerę. Użyj karty SD dla wszelkich danych zapisywanych przez skrypt i zamontuj ją ponownie przed odczytaniem tych plików z hosta.
Informacja
Czerwony kanał diody LED RGB użytkownika może na krótko zaświecić się, gdy host odczytuje lub zapisuje napęd pamięci masowej USB — jest to sterowany przez oprogramowanie układowe wskaźnik aktywności, a nie usterka.
Rozmiary pamięci¶
M4 jest dostarczany z:
/flash— system plików FAT o pojemności 32 KB, do odczytu/zapisu./rom— mapowany w pamięci ROMFS tylko do odczytu o pojemności 128 KB./sdcard— pełny rozmiar dowolnej włożonej karty microSD (gdy jest obecna), do odczytu/zapisu.
Wskaźnik błędu krytycznego (hard fault)¶
Jeśli dioda LED RGB użytkownika szybko przełącza się przez wszystkie kolory — na tyle szybko, że wygląda raczej jak migocząca biała dioda LED niż wyraźne barwy — oprogramowanie układowe napotkało nieodwracalny błąd krytyczny (hard fault). Aby przywrócić działanie, przeprogramuj oprogramowanie układowe; jeśli to nie pomoże, płytka może być fizycznie uszkodzona.
Biblioteki programowe¶
Pełną listę modułów — w tym tych, które są unikalne dla wersji M4 — znajdziesz w indeksie biblioteki.