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.

OpenMV Cam M4

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

Rozkład pinów OpenMV Cam M4 OV7725

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_GREEN i LED_BLUE

    from 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_IR jest 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żyj low() / high() zamiast on() / 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 przechowuje main.py i README.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.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 zwróci sterowanie).

  • main.py jest wykonywany tylko przy zimnym rozruchu, bezpośrednio po boot.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.