Skip to content

Conversation

@sfe-SparkFro
Copy link
Collaborator

Resolves #5

The previous camera and display drivers were implemented using double inheritance. One parent was for the device driver (eg. HM01B0 or OV5640), and the other was for the interface driver (eg. SPI or PIO). This meant that to create each combination of m devices and n interfaces, a total of m+n+m*n classes were required, which would get unwieldy quickly.

This changes the implementation so each device driver encapsulates the interface driver (which all implement the same methods), so a total of only m+n classes are required. This also has the benefit of separating interface parameters (eg. pin numbers) from device parameters (eg. resolution) when calling the constructors. Then the user can (theoretically) freely mix and match whatever device and interface drivers they need/want for their setup, which is emphasized in the updated examplerv_init module.

Other changes:

  • New VideoCapture class to more closely match standard OpenCV's VideoCapture class. The constructor takes an object that implements the VideoCaptureDriver abstract base class (which itself, inherits the new VideoDriver abstract base class).
  • New VideoDisplay class to mirror the VideoCapture class. This is not a feature of standard OpenCV (cv.imshow() takes a string for the name of a window to display in, instead of an object that represents the window), but IMO it makes sense to keep the display driver structures as similar as possible to the camera drivers, and this is backwards compatible with the existing API difference in MicroPython-OpenCV. The constructor takes an object that implements the VideoDisplayDriver abstract base class (which itself, inherits the new VideoDriver abstract base class).
  • The touch screen drivers are missing the same love, but we only have 1 right now, so leaving it as-is for this PR. Can revisit when we add more touch screen drivers.
  • New utils subpackage with modules:
    • colors - Provides standard color mode constants intended for use across all Red Vision drivers, and color-related utility functions.
    • memory - Provides utility functions related to device memory, such as checking whether an object/address is located in internal or external memory (the slower speed of external memory has proven to require different implementations for best performance).
    • pins - Provides utility functions that drivers can leverage to check and modify machine.Pin behavior on the fly.
  • Example rv_init package now encourages importing the entire Red Vision package (eg. import red_vision as rv) rather than wildcard imports from submodules (eg. from red_vision.cameras import *) to improve readability and parity with OpenCV (eg. import cv2 as cv).
  • Added header comments to files that were missing it.
  • Added full file path to header comments for clarity.
  • DVI examples no longer access private class members.
  • Other minor tweaks and bug fixes.

No more dobule inheritance!
New VideoCapture and VideoDisplay classes to more clsoely match standard OpenCV.
New "abstract" base classes for camera and display drivers.
All camera and display drivers now encapsulate an interface object for better expandability to other platforms.
New utils subpackage with common color modes and memory helper functions.
Update rv_init package after refactor.
Update DVI exampels to no longer use private members.
Add header comments files that were previously missing it.
Add full file path to header comments.
…pixel.

Fixes a regression with the HM01B0 driver, where the DMA is unable to
transfer fast enough to keep up with the PIO when only 1 byte per transfer
is performed. It's also just more efficient in general.
On RedBoard RP2350, the D0 pin ends up connecting to the HSTX connector.
When an HDMI cable is plugged in, D0 connects to the CEC pin, which has
the effect of dramatically increasing the capacitance on the D0 pin,
resulting in a terrible eye pattern. Increasing the drive strength helps
clean it up a lot. Also probably beneficial to do this to the PCLK pin,
and on all boards when using 1-bit mode (highest PCLK frequency, same
as MCLK pin) to help maintain good signal quality.
Too high seems to maybe cause oscillations or something. Hard to
know for certain, because a scope probe changes the behavior.
Copy link
Member

@gigapod gigapod left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I marked a few nits, but overall this looks very solid.

Bonus points for the awesome comments and ASCII diagrams.

Copy link

@malcolm-sparkfun malcolm-sparkfun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, looks good!

Similar to the HM01B0, too high drive strength seems to result in
degraded signal integrity, which is not visible with an oscilloscope
due to the additional capacitance on the line. The default drive
strength was set to the max (4x), which was causing bytes to sometimes
be missed with the OV5640. Reducing to 2x seems to be much more stable
now, and still sufficiently strong to get a clean eye pattern on the
D0 pin while an HDMI cable is connected with the RP2350 RedBoard.
Further testing revealed 2x was still too much. 1x seems much more stable.
Also fix erroneous extra bit getting set (not documented in datasheet, so probably shouldn't be changing it).
@sfe-SparkFro sfe-SparkFro merged commit 6c3477e into develop Dec 13, 2025
@sfe-SparkFro sfe-SparkFro deleted the encapsulation branch December 13, 2025 00:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants