OpenMV N6

OpenMV N6 สร้างขึ้นบน STMicroelectronics STM32N657 (Cortex‑M55 @ 800 MHz) พร้อม NPU บนชิปความเร็ว 1 GHz ที่รองรับ 600 GOPS INT8 บอร์ดนี้จับคู่ NPU กับเซนเซอร์ชัตเตอร์โกลบอล PAG7936 ขนาด 1 MP บนตัวพาแบบถอดได้, Gigabit Ethernet, USB‑C ความเร็วสูง, Wi‑Fi และ Bluetooth 5.1 พร้อมรัน YOLOv8/YOLOv11 การอนุมานที่ 30 FPS ควบคู่กับการสตรีมวิดีโอสด

OpenMV N6

สำหรับข้อมูลทางเทคนิคฉบับเต็ม ภาพถ่าย และขนาด ดูได้ที่ หน้าผลิตภัณฑ์ OpenMV N6

ไฮไลต์

  • STM32N657 Cortex‑M55 ที่ 800 MHz (1280 DMIPS) พร้อม ARM Helium 128‑bit SIMD — ปริมาณงานเวกเตอร์ 6.4 gigaops

  • NPU 1 GHz, 600 GOPS INT8 — รัน YOLOv8/YOLOv11 การตรวจจับที่ 30 FPS

  • ISP สำหรับ RAW Bayer สูงถึง 5MP, 2D GPU สำหรับการปรับขนาดและการหมุน 3D, การเข้ารหัส H.264 ถึง 1080p และ JPEG codec แบบฮาร์ดแวร์

  • SDRAM ภายนอก 64 MB (16‑bit @ 200 MHz DDR, 800 MB/s) บวก SRAM ภายใน 4.2 MB และ ออคทัลแฟลช 32 MB (200 MHz DDR, 400 MB/s)

  • เซนเซอร์ชัตเตอร์โกลบอลสี 1 MP PAG7936

  • IMU บนบอร์ด (มาตรวัดความเร่ง + ไจโรสโคป) และ ไมโครโฟน สำหรับเสียง + การรวมการเคลื่อนไหว

  • USB‑C ความเร็วสูง (480 Mb/s, จำกัดกระแส 1.5 A), Gigabit Ethernet (รองรับ PoE ผ่านชีลด์), Wi‑Fi a/b/g/n + Bluetooth 5.1 (เสาอากาศบนชิปหรือตัวเลือก U.FL)

  • ช่อง microSD — SD สูงถึง 2 GB, SDHC สูงถึง 32 GB, SDXC สูงถึง 2 TB

  • เครื่องชาร์จ LiPo (ชาร์จเร็ว 500 mA), ADC วัดแรงดันแบตเตอรี่, RTC พร้อม RAM สำรอง 8 KB และพินแบตเตอรี่สำรองแบบเฉพาะ

  • พิน I/O 18 พิน ทั้งหมดเป็นเอาต์พุต 3.3 V / ทนต่อ 3.3 V, 20 mA ต่อพิน รองรับอินเทอร์รัปต์

  • RGB LED สำหรับผู้ใช้, ปุ่มผู้ใช้ และ LED สถานะแยกต่างหากสำหรับการชาร์จ / USB / พลังงาน VIN

Warning

พิน I/O ของ N6 ไม่ทนต่อ 5 V อย่าเชื่อมต่ออุปกรณ์โดยตรงกับ MCU 5 V เช่น Arduino Mega จ่ายไฟ N6 ผ่าน VIN เท่านั้น

ผังพิน

OpenMV N6 PAG7936 Pinout

อ้างอิงพิน

ชื่อพิน

ฟังก์ชัน

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 (ไม่มี ADC บนพินนี้ — ดู P6_ADC)

P6_ADC

อินพุต ADC 12‑bit แบบเฉพาะ (เชื่อมต่อภายในกับ P6)

P7

TIM4 CH1

P8

TIM4 CH2

P9

TIM17 CH1

P10

TIM15 CH2 / เฟรม sync I/O

P11

ปลุกการทำงาน (active low, WKUP3)

P12

RESET — ดึงลง GND เพื่อรีเซ็ตบอร์ด (ไม่ใช่ GPIO)

P13

UART7 RX

P14

UART7 TX

P15

SPI4 CS

P16

SPI4 SCK

P17

SPI4 MISO

P18

SPI4 MOSI

SW

ปุ่มผู้ใช้ (active low)

ONOFF (SW2)

ปุ่มปลุกการทำงานจากโหมดสลีปลึก (active low, WKUP2)

ST

ต่ำเมื่อใช้พลังงาน VIN สูงเมื่อใช้พลังงาน USB

CHG

active‑low; ต่ำขณะที่แบตเตอรี่ LiPo ที่เชื่อมต่อกำลังชาร์จ

PG

active‑low; ต่ำเมื่อมีพลังงาน VIN หรือ USB

BAT_ADC

ช่อง ADC ภายในที่วัดแรงดันแบตเตอรี่ LiPo ที่เชื่อมต่อ

LED_RED

ช่องสีแดงของ RGB LED (active low)

LED_GREEN

ช่องสีเขียวของ RGB LED (active low)

LED_BLUE

ช่องสีน้ำเงินของ RGB LED (active low)

Note

สาย P10 frame‑sync เป็นบัสร่วมกัน เชื่อมต่อกับ MCU, พินทริกเกอร์/การรับแสงของเซนเซอร์กล้อง และเฮดเดอร์ผู้ใช้พร้อมกัน ทิศทางถูกกำหนดโดยแอปพลิเคชัน — MCU, เซนเซอร์ หรือสัญญาณภายนอกสามารถขับได้ขึ้นอยู่กับการกำหนดค่าเซนเซอร์ (บางเซนเซอร์สามารถใช้พินเดียวกันเป็นอินพุตทริกเกอร์ หรือ เอาต์พุตการรับแสง) ตรวจสอบให้แน่ใจว่ามีไดรเวอร์ที่ทำงานอยู่เพียงตัวเดียวในแต่ละเวลา

Note

ONOFF และ P11 อ้างอิงกับรางไฟ RAW ที่เปิดตลอดเวลา (ไม่ใช่รางไฟ 3.3 V ที่มีสวิตช์) ดังนั้นจึงยังคงใช้งานได้ขณะที่ส่วนที่เหลือของบอร์ดอยู่ในโหมดสลีปลึก/ประหยัดพลังงาน อินพุตทั้งสองเป็น active low

พินเหล่านี้ผ่านตัวแปลงระดับสัญญาณจึงสามารถอยู่บนรางไฟ RAW ได้ หากคุณต้องการพฤติกรรม GPIO โดยตรงที่ 3.3 V บน ONOFF หรือ P11 (เช่น เพื่อขับจาก MCU 3.3 V โดยไม่ผ่านตัวแปลง) บอร์ดมีแผ่นบัดกรีแบบ pull‑up และแบบ 0‑โอห์มที่ให้คุณข้ามตัวแปลงได้ นี่คือการดัดแปลงฮาร์ดแวร์ขั้นสูง — ผู้ใช้ส่วนใหญ่ควรปล่อยทิ้งไว้

Note

P15–P18 ใช้ร่วมกับ Gigabit Ethernet PHY ซึ่งเชื่อมต่อและเปิดใช้งานโดยค่าเริ่มต้น เพื่อใช้พินเหล่านี้เป็น I/O ผู้ใช้ คุณต้องรีโฟลว์ตัวต้านทาน 0‑โอห์มบนด้านหลังของบอร์ดไปยังตำแหน่ง GPIO การทำเช่นนี้จะปิดใช้งาน Gigabit Ethernet เท่านั้น — Ethernet 10/100 Mb/s ยังคงทำงานบนพินเฉพาะของตัวเอง

พินไฟฟ้า

  • 3.3V — ราง 3.3 V ที่ควบคุมแล้ว เอาต์พุตเท่านั้น บน N6 — ห้ามป้อนพลังงานภายนอกเข้าพินนี้ มีกระแสสูงถึง 1 A สำหรับชีลด์

  • VIN — อินพุต 5 V จ่ายไฟให้บอร์ดและเครื่องชาร์จ LiPo บนบอร์ด

  • RAW — อินพุต/เอาต์พุต เปิดตลอดเวลา (3.6 V – 5 V) รับแหล่งไฟที่ใช้งานอยู่ (VIN, USB หรือแบตเตอรี่ที่เชื่อมต่อ) และยังสามารถใช้เป็นอินพุตได้ คุณต้องขับ RAW ผ่านไดโอดแบบอนุกรม เมื่อจ่ายพลังงานเข้า — มิฉะนั้นกระแสจะไหลกลับเข้า VIN/USB และทำให้แหล่งจ่ายหรือการป้องกันบนบอร์ดเสียหาย

  • GND — กราวด์ร่วม

Note

ชิปจัดการพลังงานบนบอร์ดเลือก USB หรือ VIN ที่มีแรงดันสูงกว่า โดยอัตโนมัติเพื่อจ่ายไฟให้บอร์ดและเครื่องชาร์จแบตเตอรี่ หากมี LiPo เชื่อมต่อจะชาร์จด้วยพลังงานที่เหลือ และตัวควบคุมจะเปลี่ยนมาใช้แบตเตอรี่เพื่อให้บอร์ดทำงานต่อไปหาก VIN/USB ลดลงหรือถูกถอดออก

Note

ด้านหลังของบอร์ดมีแผ่นบัดกรีสำหรับ แบตเตอรี่สำรอง RTC 3.3 V ภายนอก การเชื่อมต่อแบตเตอรี่แบบเหรียญกับแผ่นเหล่านี้จะทำให้ RTC และ RAM สำรอง 8 KB ทำงานต่อไปขณะที่บอร์ดส่วนที่เหลือไม่มีไฟ

Tip

ใช้ ตัวประมาณอายุการใช้งานแบตเตอรี่ เพื่อคำนวณว่า N6 จะทำงานได้นานแค่ไหนบนแบตเตอรี่สำหรับรอบการทำงาน active/deep-sleep ที่กำหนด

พิน Ethernet

N6 เปิดเผยคู่ MDI ของ Ethernet PHY บนแผ่นเฉพาะถัดจากเฮดเดอร์ GPIO พิน MDI ไม่ปลอดภัยที่จะต่อตรงกับ RJ45 — ต้องใช้แม่เหล็ก Ethernet (หม้อแปลงไฟฟ้าแยกกัน ไม่ว่าจะติดอยู่ใน magjack หรือบนชีลด์) จำเป็น ระหว่าง PHY และสายเคเบิล ชีลด์ OpenMV PoE มีอยู่แล้ว หากคุณทำแจ็คเองให้ใช้ RJ45 แบบรวมแม่เหล็กหรือหม้อแปลงภายนอก

  • ETH_LED — LED แสดงลิงก์/กิจกรรม Active low เมื่อลิงก์เชื่อมต่อ; กะพริบเมื่อมีการรับส่งข้อมูล

  • DA P / DA N — คู่ A (TX ใน 10/100 ใช้ที่ทุกความเร็ว)

  • DB P / DB N — คู่ B (RX ใน 10/100 ใช้ที่ทุกความเร็ว)

  • DC P / DC N — คู่ C ใช้เฉพาะที่ Gigabit

  • DD P / DD N — คู่ D ใช้เฉพาะที่ Gigabit

10/100 Mb/s ต้องการเพียงคู่ A และ B Gigabit ต้องการทั้งสี่คู่ A–D

พินกู้คืนและดีบัก

  • RESET — ดึงลง GND เพื่อรีเซ็ตบอร์ด การปล่อยให้ MCU เริ่มทำงานตามปกติ

  • BOOT0 — ดึงขึ้น 3.3 V ขณะเปิดเครื่องเพื่อเข้าสู่โหมด ROM bootloader OpenMV IDE ใช้โหมดนี้เพื่อเขียน bootloader บนบอร์ดใหม่

  • BOOT1 — สวิตช์ที่ทำให้บอร์ดเข้าสู่โหมดนักพัฒนาสำหรับใช้กับเครื่องมือของ ST (ST‑LINK ที่เชื่อมต่อกับเฮดเดอร์ ARM 10‑pin SWD/JTAG) ปล่อยให้ปิดใช้งานสำหรับการทำงานปกติกับเฟิร์มแวร์และเครื่องมือ OpenMV

มีเฮดเดอร์ ARM 10‑pin SWD/JTAG แบบเฉพาะติดมาด้วย เข้ากันได้กับอะแดปเตอร์ ST‑LINK และ SEGGER J‑Link

อุปกรณ์ต่อพ่วงบนบอร์ด

LED

N6 มี RGB LED สองตัว:

  • RGB LED ผู้ใช้ — ควบคุมได้ด้วยซอฟต์แวร์ เปิดเผยเป็น LED_RED, LED_GREEN และ LED_BLUE

    from machine import LED
    
    LED("LED_RED").on()
    LED("LED_GREEN").on()
    LED("LED_BLUE").on()
    
  • LED พลังงาน — ขับโดยฮาร์ดแวร์จัดการพลังงานบนบอร์ดโดยตรง ไม่สามารถควบคุมด้วยซอฟต์แวร์ได้ ใช้เพื่ออ่านสถานะการจ่ายไฟแบบรวดเร็ว

    ขณะทำงาน:

    ช่อง

    ความหมาย

    สีน้ำเงิน

    VIN กำลังจ่ายไฟให้บอร์ด (ดับเมื่อใช้ USB)

    สีเขียว

    มีพลังงาน USB หรือ VIN

    สีแดง

    กำลังชาร์จแบตเตอรี่ LiPo ที่เชื่อมต่อ

    ในโหมดสลีปลึก ทุกช่องดับ ยกเว้นสีแดง ซึ่งยังคงติดขณะที่ LiPo กำลังชาร์จ

ปุ่มผู้ใช้

N6 มีปุ่มสองปุ่ม:

  • SW — ปุ่มผู้ใช้อเนกประสงค์ ทำงานเมื่อดึงลงต่ำ

  • ONOFF (SW2) — ปุ่มปลุกการทำงาน เป็นปุ่มเดียวที่สามารถนำบอร์ดออกจากโหมดสลีปลึกได้

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

เพื่อนำบอร์ดเข้าสู่โหมดสลีปลึกและให้ ONOFF (SW2) ปลุกบอร์ดกลับมา เพียงเรียก machine.deepsleep() — ไม่ต้องกำหนดค่าการปลุก ปุ่มเชื่อมต่อตรงกับอินพุต WKUP2:

import machine

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

คุณยังสามารถต่อ ONOFF เป็นสวิตช์เปิด/ปิดแบบซอฟต์ได้ ทริกเกอร์บนขอบ ขาขึ้น — สายจะคงที่สูงหลังจากผู้ใช้ปล่อยปุ่ม ดังนั้นการกดครั้งถัดไปจึงเป็นเหตุการณ์ปลุกที่ชัดเจน:

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.

พินสถานะพลังงาน

อินพุตสถานะ active‑low สามตัวให้เฟิร์มแวร์ดูว่าชิปจัดการพลังงานบนบอร์ดกำลังทำอะไร:

  • ST — ต่ำเมื่อบอร์ดทำงานบน VIN สูงเมื่อทำงานบนพลังงาน USB

  • CHG — ต่ำขณะที่แบตเตอรี่ LiPo ที่เชื่อมต่อกำลังชาร์จ

  • PG — ต่ำเมื่อมีพลังงาน VIN หรือ 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()

เซนเซอร์กล้อง

PAG7936 ถูกขับผ่านโมดูล csi --- เซ็นเซอร์กล้อง

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

เซนเซอร์อยู่บน โมดูลแบบถอดได้ — เปลี่ยนเป็นโมดูลกล้อง OpenMV อื่นๆ (ชัตเตอร์โกลบอล, เทอร์มอล, ความละเอียดสูงกว่า ฯลฯ) โดยไม่ต้องเปลี่ยนส่วนที่เหลือของบอร์ด

PAG7936 รองรับโหมดทริกเกอร์ — การรวมพิกเซลจะสอดคล้องกับการเรียก csi.CSI.snapshot แต่ละครั้งอย่างแม่นยำแทนที่จะเป็นนาฬิกาเฟรมแบบอิสระ ซึ่งเป็นประโยชน์สำหรับการซิงค์การจับภาพกับเหตุการณ์ภายนอกหรือเซนเซอร์อื่น เปิดใช้งานผ่าน csi.CSI.ioctl ด้วย csi.IOCTL_SET_TRIGGERED_MODE อัตราเฟรมลดลงเหลือประมาณครึ่งหนึ่งของโหมดอิสระเนื่องจากการอ่านออกไม่ทำงานแบบท่อกับการรวมเฟรมถัดไปอีกต่อไป:

cam.ioctl(csi.IOCTL_SET_TRIGGERED_MODE, True)

NPU

NPU Neural‑ART 1 GHz ของ N6 (600 GOPS INT8) เปิดเผยผ่านโมดูล ml --- Machine Learning โมเดลที่จัดเก็บในระบบไฟล์แบบอ่านอย่างเดียว /rom โหลดโดยตรงจากแฟลชโดยไม่ต้องคัดลอกไป RAM ดังนั้นแม้แต่ตัวตรวจจับขนาดใหญ่ก็พอดีกับบัฟเฟอร์เฟรมสดได้อย่างสบาย รัน YOLOv8 detector บนทุกเฟรมและวาดการทำนายซ้อนทับบนภาพสด:

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

ไมโครโฟน

ไมค์บนบอร์ดถูกบันทึกผ่าน audio --- โมดูล Audio แต่ละบัฟเฟอร์มาเป็น bytearray PCM ขนาด 16 บิตที่มีเครื่องหมาย ซึ่งทำให้ง่ายต่อการป้อนเข้า ulab/numpy สำหรับ DSP อย่างรวดเร็ว ตัวตรวจจับความดังแบบง่าย — พิมพ์เมื่อปริมาณ RMS ข้ามค่าขีดแบ่ง:

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

มาตรวัดความเร่ง + ไจโรสโคปบนบอร์ดใต้โมดูลกล้องเปิดเผยผ่าน imu --- imu sensor

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

CYW43439 บนบอร์ดเปิดเผยผ่าน network --- การกำหนดค่าเครือข่าย เป็นอินเทอร์เฟซสถานี หลังจากเชื่อมต่อ ipconfig("addr4") จะคืนค่าคู่ (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

CYW43439 เดียวกันยังเปิดเผย Bluetooth 5.1 ด้วย ใช้ aioble --- Async BLE สำหรับ BLE ที่เป็นมิตรกับ asyncio — เช่น โฆษณาเป็น peripheral และรอให้ central เชื่อมต่อ:

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

เมื่อมีการเชื่อมต่อ RJ45 (พร้อมแม่เหล็ก) กับแผ่น MDI Gigabit PHY จะปรากฏเป็นอินเทอร์เฟซ LAN DHCP ทำงานโดยอัตโนมัติเมื่อลิงก์เชื่อมต่อ:

import network, time

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

การ์ด microSD

เมื่อใส่การ์ดจะถูกเมาท์โดยอัตโนมัติที่ /sdcard และสามารถใช้งานได้ผ่านระบบไฟล์ปกติ:

import os

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

อ้างอิงบัส

GPIO

ใช้ machine.Pin เพื่ออ่านหรือขับพินที่พิมพ์ซิลก์สกรีนใดๆ เอาต์พุตเป็น CMOS 3.3 V และสามารถซิงก์/ซอร์สได้สูงถึง 20 mA ต่อพิน

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

พินอินพุตใดๆ ยังสามารถส่ง interrupt เมื่อมีการเปลี่ยนขอบ:

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

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

UART

บัส

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

บัส

SCL

SDA

I2C2

P4

P5

from machine import I2C

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

ฮาร์ดแวร์เดียวกันยังสามารถใช้ในโหมด target (slave) ผ่าน machine.I2CTarget เพื่อเปิดเผยพื้นที่หน่วยความจำให้กับ I²C controller อื่น:

from machine import I2CTarget

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

SPI

บัส

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

บัส

TX

RX

CAN1

P2

P3

Note

CAN ยังไม่รองรับบนบอร์ดนี้ในเฟิร์มแวร์ 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

ช่อง ADC ทั้งสองผ่านตัวแบ่งแรงดันที่บัฟเฟอร์ด้วย op‑amp ก่อนถึง MCU ดังนั้น read_u16() จึงถูกแมปกับแรงดันอินพุตแบบ full‑scale ที่แตกต่างกันในแต่ละพิน

พิน

Full‑scale

หมายเหตุ

P6_ADC

~3.3 V

แผ่นอเนกประสงค์ เชื่อมต่อภายในกับ P6

BAT_ADC

~5.0 V

ช่องภายในสำหรับแบตเตอรี่ 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

พิน

ตัวจับเวลา / ช่อง

P4

TIM2 CH3

P5

TIM2 CH4

P6

TIM12 CH1

P7

TIM4 CH1

P8

TIM4 CH2

P9

TIM17 CH1

P10

TIM15 CH2

ขับด้วย machine.PWM

from machine import Pin, PWM

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

บัสแบบบิตแบง (ซอฟต์แวร์)

machine.SoftI2C และ machine.SoftSPI ทำงานบน GPIO ใดก็ได้หากคุณต้องการบัสเพิ่มเติม

เซนเซอร์ความร้อน (ภายนอกบอร์ด)

เฟิร์มแวร์รวมถึงไดรเวอร์ fir --- ไดรเวอร์เซนเซอร์ความร้อน (fir == far infrared) สำหรับเครื่องถ่ายภาพความร้อนที่ต่อสายภายนอก:

  • MLX90621 — อาร์เรย์ IR 16 × 4

  • MLX90640 — อาร์เรย์ IR 32 × 24

  • MLX90641 — อาร์เรย์ IR 16 × 12

  • AMG8833 — อาร์เรย์ IR 8 × 8

ต่อสายโมดูลกับบัส I²C ของบอร์ดและอ่านเฟรมด้วย 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())

ไดรเวอร์ fir คุยกับเซนเซอร์ผ่าน I²C 2 เท่านั้น — ต่อสายโมดูลกับ P4 (SCL) และ P5 (SDA)

การกำหนดเวลา

time

โมดูล time ครอบคลุมการหน่วงเวลาแบบ blocking, การจับเวลาแบบโมโนโทนิก และการวัดเวลาที่ผ่านไป:

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)

ตัวจับเวลาเสมือน

machine.Timer กำหนดการคอลแบ็กแบบคาบเวลาหรือแบบครั้งเดียวโดยไม่ใช้สล็อตตัวจับเวลาฮาร์ดแวร์ ส่ง -1 เป็น id เพื่อใช้ตัวจับเวลาเสมือน (ซอฟต์แวร์):

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

ค่าคาบเวลาอยู่ในหน่วยมิลลิวินาที เรียก deinit() เพื่อหยุดและคืนสล็อต

นาฬิกาเวลาจริง

machine.RTC รักษาเวลาตามนาฬิกาแขวนผ่านการรีเซ็ตและ (พร้อมแบตเตอรี่สำรอง 3.3 V ที่เชื่อมต่อกับแผ่นด้านหลัง ดู พินไฟฟ้า) ผ่านการตัดไฟทั้งหมด:

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 ยังทำงานผ่านโหมดสลีปลึกด้วย ดังนั้นคุณสามารถใช้เป็นแหล่งปลุกสำหรับ machine.deepsleep()

Watchdog

machine.WDT รีเซ็ตบอร์ดหากแอปพลิเคชันค้าง เมื่อเริ่มแล้วไม่สามารถหยุดหรือกำหนดค่าใหม่ได้ — ป้อนอาหารเป็นระยะๆ ภายในลูปหลักของคุณ:

from machine import WDT

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

ข้อมูลการบูตและรันไทม์

หน้าต่าง USB bootloader

ในทุกครั้งที่เปิดเครื่อง กล้องจะรัน bootloader สั้นๆ (สักสองสามวินาที) ที่ให้ OpenMV IDE อัปเดตเฟิร์มแวร์โดยไม่ต้องให้ผู้ใช้เข้าสู่โหมด DFU หลังจากหน้าต่างหมดอายุ bootloader จะส่งต่อไปยัง boot.py แล้วไปยัง main.py

สคริปต์ที่กำลังทำงานสามารถกลับเข้าสู่ bootloader ตามต้องการโดยเรียก machine.bootloader()

import machine

machine.bootloader()

ระบบไฟล์และลำดับการบูต

เฟิร์มแวร์ N6 เมาท์ระบบไฟล์สูงสุดสามระบบเมื่อบูต:

  • แฟลชภายใน — เมาท์เสมอที่ /flash ถือ main.py และ README.txt โดยค่าเริ่มต้น สร้างขึ้นในการบูตครั้งแรก

  • การ์ด microSD — หากใส่การ์ดจะเมาท์ที่ /sdcard

  • ROMFS — ระบบไฟล์แบบอ่านอย่างเดียว memory‑mapped ที่ /rom ใช้สำหรับส่งสินทรัพย์ข้อมูลขนาดใหญ่ (เช่น โมเดล AI) ที่ได้ประโยชน์จากการเข้าถึงแบบ zero‑copy เมาท์โดยอัตโนมัติโดย MicroPython เมื่อเริ่มต้น ก่อนที่ Python ของผู้ใช้จะรัน

หลังจากเมาท์แล้ว ไดเรกทอรีทำงานจะถูกตั้งเป็น /sdcard เมื่อมีการ์ด มิฉะนั้น /flash ตัวแปลภาษาจะรันสคริปต์จากไดเรกทอรีนั้น:

  • boot.py ถูกรันบน ทุก การรีเซ็ตแบบซอฟต์ (การบูตเย็น, Ctrl‑D จาก REPL หรือเมื่อสคริปต์ที่กำลังทำงานกลับมา)

  • main.py ถูกรัน เฉพาะการบูตเย็นเท่านั้น ทันทีหลังจาก boot.py การรีเซ็ตแบบซอฟต์ครั้งต่อไปจะรัน boot.py ซ้ำแต่ไปยัง REPL โดยตรง — เพื่อรัน main.py ซ้ำคุณต้องรีเซ็ตบอร์ดทั้งหมด

การวาง boot.py หรือ main.py ลงในการ์ด SD จะแทนที่สำเนาในแฟลชโดยไม่แตะต้องมัน — ทั้งสองไฟล์ถูกค้นหาในไดเรกทอรีบูต (/sdcard เมื่อมีการ์ดเมาท์ มิฉะนั้น /flash)

main.py เริ่มต้นที่ส่งมาบนบอร์ดที่เพิ่งแฟลชใหม่เพียงกะพริบช่อง สีน้ำเงิน ของ RGB LED ผู้ใช้เป็นสัญญาณฮาร์ตบีต (สองพัลส์สั้น, ช่องว่างสั้น) เพื่อให้คุณบอกได้ว่าเฟิร์มแวร์บูตสำเร็จโดยไม่มีโฮสต์เชื่อมต่อ

sys.path ถูกขยายให้รวมระบบไฟล์ทั้งสามและไดเรกทอรีย่อย lib/ ดังนั้นโมดูลที่นำเข้าได้จึงอยู่ใน /flash/lib, /sdcard/lib หรือ /rom/lib

หากต้องการบังคับให้ระบบละเว้นการ์ด SD ที่ใส่ไว้ (เช่น เพื่อรัน main.py ในแฟลชแม้จะมีการ์ดอยู่) ให้สร้างไฟล์เปล่าชื่อ SKIPSD ที่รูทของ /flash

เมื่อเชื่อมต่อผ่าน USB ระบบไฟล์บูต (/sdcard ถ้ามีการ์ด มิฉะนั้น /flash) ยังจะแสดงเป็นไดรฟ์ USB mass‑storage บนโฮสต์ด้วย ทำให้คุณแก้ไข boot.py, main.py และไฟล์อื่นๆ ได้โดยตรง Eject ไดรฟ์ก่อนรีเซ็ตกล้อง เพื่อให้โฮสต์ flush การเขียนที่แคชไว้

Note

เนื่องจาก OS ถือไดรฟ์เป็นอุปกรณ์บล็อกแบบ passive ไฟล์ที่สร้างหรือแก้ไขโดยโค้ดที่ทำงานบน OpenMV Cam จะไม่ปรากฏจนกว่าโฮสต์จะ remount ไดรฟ์ หาก OS และ OpenMV Cam เขียนระบบไฟล์เดียวกันพร้อมกัน OS จะชนะและเขียนทับการเปลี่ยนแปลงของกล้อง ใช้การ์ด SD สำหรับข้อมูลที่สคริปต์เขียนกลับ และ remount ก่อนอ่านไฟล์เหล่านั้นจากโฮสต์

Note

ช่อง สีแดง ของ RGB LED ผู้ใช้อาจติดสั้นๆ ขณะที่โฮสต์กำลังอ่านหรือเขียนไปยังไดรฟ์ USB mass‑storage — นี่เป็นตัวบ่งชี้กิจกรรมที่ขับโดยเฟิร์มแวร์ ไม่ใช่ข้อผิดพลาด

ขนาดหน่วยเก็บข้อมูล

N6 มาพร้อมกับ:

  • /flash — ระบบไฟล์ FAT 4 MB อ่าน/เขียน

  • /rom — ROMFS 24 MB แบบอ่านอย่างเดียว memory‑mapped ใช้สำหรับส่งสคริปต์และโมเดล ML ที่ได้ประโยชน์จากการเข้าถึง mmap แบบ zero‑copy

  • /sdcard — ขนาดเต็มของการ์ด microSD ที่ใส่ไว้ (เมื่อมี) อ่าน/เขียน

ตัวบ่งชี้ hard‑fault

หาก RGB LED ผู้ใช้กำลังวนซ้ำผ่านทุกสีอย่างรวดเร็ว — เร็วพอที่มักจะดูเหมือน LED สีขาวที่กะพริบ มากกว่าสีที่ต่างกัน — เฟิร์มแวร์ได้ประสบ hard fault ที่ไม่สามารถกู้คืนได้ Reflash เฟิร์มแวร์เพื่อกู้คืน หาก reflash ไม่ช่วย บอร์ดอาจเสียหายทางกายภาพ

ไลบรารีซอฟต์แวร์

ดู ดัชนีไลบรารี สำหรับรายการโมดูลทั้งหมด — รวมถึงโมดูลที่ไม่ซ้ำกับบิลด์ N6