Skip to content

Commit 9edd995

Browse files
committed
Move hardware initialization out of boot.py
There are potential downsides to requiring use of boot.py: * It's a bit obscure * Not all IDEs (eg. XRPCode) properly support boot.py * It's possible to brick a device with a bad boot.py Now all hardware initialization is in an example module, which all examples import Users can still move the contents to a boot.py file if they desire
1 parent d9501a7 commit 9edd995

File tree

11 files changed

+217
-129
lines changed

11 files changed

+217
-129
lines changed

examples/boot.py

Lines changed: 0 additions & 127 deletions
This file was deleted.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Initializes various hardware components for OpenCV in MicroPython. The
2+
# examples import this module, but you could instead create/edit a `boot.py`
3+
# script to automatically initialize the hardware when the board boots up. See:
4+
# https://micropython.org/resources/docs/en/latest/reference/reset_boot.html#id4
5+
6+
try:
7+
from .display import display
8+
except:
9+
print("Display initialization failed, skipping...")
10+
11+
try:
12+
from .camera import camera
13+
except:
14+
print("Camera initialization failed, skipping...")
15+
16+
try:
17+
from .touch_screen import touch_screen
18+
except:
19+
print("Touch screen initialization failed, skipping...")
20+
21+
try:
22+
# We don't actually need to import anything here, just want to run the
23+
# sd_card module so the SD card gets mounted to the filesystem. So just
24+
# import something then delete it to avoid clutter
25+
from .sd_card import sdcard
26+
del sdcard
27+
except:
28+
print("SD card initialization failed, skipping...")
29+
30+
# Optional - show a splash image on the display if one is available, or clear
31+
# the display of any previous content
32+
try:
33+
# Load and display a splash image, if one is available
34+
import cv2
35+
splash_image = cv2.imread("splash.png")
36+
cv2.imshow(display, splash_image)
37+
except Exception:
38+
# No splash image, instead clear the display if the driver supports it
39+
if hasattr(display, 'clear'):
40+
display.clear()

examples/cv2_hardware_init/bus_i2c.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Import the machine.I2C class
2+
from machine import I2C
3+
4+
# Initialize default I2C bus. You may need to adjust the arguments based on your
5+
# specific board and configuration
6+
i2c = I2C(
7+
# id = 0,
8+
# sda = machine.Pin(0),
9+
# scl = machine.Pin(1),
10+
# freq = 400_000
11+
)

examples/cv2_hardware_init/bus_spi.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Import the machine.SPI class
2+
from machine import SPI
3+
4+
# Initialize default SPI bus. You may need to adjust the arguments based on your
5+
# specific board and configuration
6+
spi = SPI(
7+
# id = 0,
8+
baudrate = 24_000_000, # Use the fastest baudrate you can for best performance!
9+
# sck = machine.Pin(2),
10+
# mosi = machine.Pin(3),
11+
# miso = machine.Pin(4),
12+
# freq = 100_000
13+
)

examples/cv2_hardware_init/camera.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Initializes a camera object. Multiple options are provided below, so you can
2+
# choose one that best fits your needs. You may need to adjust the arguments
3+
# based on your specific camera and board configuration
4+
5+
# Import the OpenCV camera drivers
6+
from cv2_drivers.cameras import *
7+
8+
# Import the I2C bus
9+
from .bus_i2c import i2c
10+
11+
################################################################################
12+
# HM01B0
13+
################################################################################
14+
15+
# PIO interface, only available on Raspberry Pi RP2 processors
16+
camera = hm01b0_pio.HM01B0_PIO(
17+
i2c,
18+
pin_d0 = 12,
19+
pin_vsync = 13,
20+
pin_hsync = 14,
21+
pin_pclk = 15,
22+
pin_xclk = None, # Optional xclock pin, specify if needed
23+
num_data_pins = 1 # Number of data pins used by the camera (1, 4, or 8)
24+
)
25+
26+
################################################################################
27+
# OV5640
28+
################################################################################
29+
30+
# PIO interface, only available on Raspberry Pi RP2 processors
31+
# camera = ov5640_pio.OV5640_PIO(
32+
# i2c,
33+
# pin_d0 = 8,
34+
# pin_vsync = 22,
35+
# pin_hsync = 21,
36+
# pin_pclk = 20,
37+
# pin_xclk = None # Optional xclock pin, specify if needed
38+
# )

examples/cv2_hardware_init/display.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Initializes a display object. Multiple options are provided below, so you can
2+
# choose one that best fits your needs. You may need to adjust the arguments
3+
# based on your specific display and board configuration
4+
5+
# Import the OpenCV display drivers
6+
from cv2_drivers.displays import *
7+
8+
# Import the SPI bus
9+
from .bus_spi import spi
10+
11+
################################################################################
12+
# ST7789
13+
################################################################################
14+
15+
# SPI interface. This should work on any platform, but it's not always the
16+
# fastest option (24Mbps on RP2350)
17+
display = st7789_spi.ST7789_SPI(
18+
width = 240,
19+
height = 320,
20+
spi = spi,
21+
pin_dc = 16,
22+
pin_cs = 17,
23+
rotation = 1
24+
)
25+
26+
# PIO interface. This is only available on Raspberry Pi RP2 processors,
27+
# but is much faster than the SPI interface (75Mbps on RP2350)
28+
# display = st7789_pio.ST7789_PIO(
29+
# width = 240,
30+
# height = 320,
31+
# sm_id = 1,
32+
# pin_clk = 18,
33+
# pin_tx = 19,
34+
# pin_dc = 16,
35+
# pin_cs = 17,
36+
# rotation = 1
37+
# )

examples/cv2_hardware_init/sd_card.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Initializes SD card and mounts it to the filesystem. This assumes the SD card
2+
# is on the same SPI bus as the display with a different chip select pin. You
3+
# may need to adjust this based on your specific board and configuration
4+
5+
# Import the Pin class for the chip select pin
6+
from machine import Pin
7+
8+
# Import the SPI bus
9+
from .bus_spi import spi
10+
11+
# When the SD card is initialized, it changes the SPI bus baudrate. We'll
12+
# want to revert it, so we need to know the original baudrate. There's no
13+
# way to get it directly, so we convert the bus to a string and parse it.
14+
# Example format:
15+
# "SPI(0, baudrate=24000000, sck=Pin(2), mosi=Pin(3), miso=Pin(4))"
16+
spi_str = str(spi)
17+
baudrate = int(spi_str[spi_str.index("baudrate=") + 9:].partition(",")[0])
18+
19+
# Set the chip select pin for the SD card
20+
sd_cs = Pin(7, Pin.OUT)
21+
22+
try:
23+
# Import the SD card module. This is often not installed by default in
24+
# MicroPython, so you may need to install it manually. For example, you can
25+
# use `mpremote mip install sdcard`
26+
import sdcard
27+
28+
# Initialize the SD card, then restore the original SPI bus baudrate. This
29+
# is wrapped in a try/finally block to ensure the baudrate is restored even if
30+
# the SD card initialization fails
31+
try:
32+
sd_card = sdcard.SDCard(spi, sd_cs)
33+
finally:
34+
spi.init(baudrate = baudrate)
35+
36+
# Mount the SD card to the filesystem under the "/sd" directory, which makes
37+
# it accessible just like the normal MicroPython filesystem
38+
import uos
39+
vfs = uos.VfsFat(sd_card)
40+
uos.mount(vfs, "/sd")
41+
except ImportError:
42+
print("sdcard module not found, skipping SD card initialization...")
43+
except OSError as e:
44+
eStr = str(e)
45+
if "no SD card" in eStr:
46+
print("no SD card found, skipping SD card initialization...")
47+
elif "Errno 1" in eStr:
48+
print("SD card already mounted, skipping SD card initialization...")
49+
else:
50+
print("Failed to mount SD card, skipping SD card initialization...")
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Import the machine module to access hardware features
2+
from .bus_i2c import i2c
3+
4+
# Import the OpenCV touch screen drivers
5+
from cv2_drivers.touch_screens import *
6+
7+
# Create a touch screen object. Multiple options are provided below, so you can choose
8+
# one that best fits your needs. You may need to adjust the arguments based on
9+
# your specific touch screen and board configuration
10+
11+
################################################################################
12+
# CST816
13+
################################################################################
14+
15+
# I2C interface
16+
touch_screen = cst816.CST816(i2c)

examples/ex01_hello_opencv.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
# Import OpenCV, just as you would in any other Python environment!
22
import cv2
33

4+
# Standard OpenCV leverages the host operating system to access hardware, but we
5+
# don't have that luxury in MicroPython. Instead, drivers are provided for
6+
# various hardware components, which need to be initialized before using them.
7+
# The exmples import a module called `cv2_hardware_init`, which initializes the
8+
# drivers. You may need to edit the contents of the `cv2_hardware_init` module
9+
# based on your specific board and hardware configuration
10+
from cv2_hardware_init import *
11+
412
# Import NumPy, almost like any other Python environment! The only difference is
513
# the addition of `from ulab` since MicroPython does not have a full NumPy
614
# implementation; ulab NumPy is a lightweight version of standard NumPy

examples/ex02_imread_imwrite.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
# Import OpenCV
1+
# Import OpenCV and hardware initialization module
22
import cv2
3+
from cv2_hardware_init import *
34

45
# Call `cv2.imread()` to read an image from the MicroPython filesystem, just
56
# like in any other Python environment! Make sure to copy the image to the

0 commit comments

Comments
 (0)