-
Notifications
You must be signed in to change notification settings - Fork 12
a little refactoring, speed-up, and CPython compatibility #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 4 commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,7 +42,6 @@ | |
* Adafruit CircuitPython firmware for the ESP8622 and M0-based boards: | ||
https://github.com/adafruit/circuitpython/releases | ||
""" | ||
import busio | ||
from micropython import const | ||
|
||
__version__ = "0.0.0-auto.0" | ||
|
@@ -79,6 +78,11 @@ | |
IMAGE_SIZE_320x240 = const(0x11) | ||
IMAGE_SIZE_160x120 = const(0x22) | ||
# pylint: enable=invalid-name | ||
_BAUDRATE_9600 = const(0xAEC8) | ||
_BAUDRATE_19200 = const(0x56E4) | ||
_BAUDRATE_38400 = const(0x2AF2) | ||
_BAUDRATE_57600 = const(0x1C1C) | ||
_BAUDRATE_115200 = const(0x0DA6) | ||
|
||
_MOTIONCONTROL = const(0x0) | ||
_UARTMOTION = const(0x01) | ||
|
@@ -93,20 +97,19 @@ | |
|
||
class VC0706: | ||
"""Driver for VC0706 serial TTL camera module. | ||
|
||
:param ~microcontroller.Pin rx: Receive pin | ||
:param ~microcontroller.Pin tx: Transmit pin | ||
:param int baudrate: Serial connection speed | ||
:param int timeout: Read timeout in seconds | ||
:param int buffer_size: Receive buffer size | ||
""" | ||
def __init__(self, rx, tx, *, baudrate=38400, timeout=250, buffer_size=100): | ||
self._uart = busio.UART(tx, rx, baudrate=baudrate, timeout=timeout) | ||
def __init__(self, uart, *, buffer_size=100): | ||
self._uart = uart | ||
self._buffer = bytearray(buffer_size) | ||
self._frame_ptr = 0 | ||
self._command_header = bytearray(3) | ||
if not self._run_command(_RESET, bytes([0x00]), 5): | ||
raise RuntimeError('Failed to get response from VC0706, check wiring!') | ||
for _ in range(2): # 2 retries to reset then check resetted baudrate | ||
for baud in (9600, 19200, 38400, 57600, 115200): | ||
self._uart.baudrate = baud | ||
if self._run_command(_RESET, bytes([0x00]), 5): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of |
||
break | ||
else: # for:else rocks! http://book.pythontips.com/en/latest/for_-_else.html | ||
raise RuntimeError('Failed to get response from VC0706, check wiring!') | ||
|
||
@property | ||
def version(self): | ||
|
@@ -116,6 +119,32 @@ def version(self): | |
readlen = self._read_response(self._buffer, len(self._buffer)) | ||
return str(self._buffer[:readlen], 'ascii') | ||
|
||
@property | ||
def baudrate(self): | ||
"""Return the currently configured baud rate.""" | ||
return self._uart.baudrate | ||
|
||
@baudrate.setter | ||
def baudrate(self, baud): | ||
"""Set the baudrate to 9600, 19200, 38400, 57600, or 115200. """ | ||
divider = None | ||
if baud == 9600: | ||
divider = _BAUDRATE_9600 | ||
elif baud == 19200: | ||
divider = _BAUDRATE_19200 | ||
elif baud == 38400: | ||
divider = _BAUDRATE_38400 | ||
elif baud == 57600: | ||
divider = _BAUDRATE_57600 | ||
elif baud == 115200: | ||
divider = _BAUDRATE_115200 | ||
else: | ||
raise ValueError("Unsupported baud rate") | ||
args = [0x03, 0x01, (divider>>8) & 0xFF, divider & 0xFF] | ||
self._run_command(_SET_PORT, bytes(args), 7) | ||
print([hex(i) for i in self._buffer[0:10]]) | ||
self._uart.baudrate = baud | ||
|
||
@property | ||
def image_size(self): | ||
"""Get the current image size, will return a value of IMAGE_SIZE_640x480, | ||
|
@@ -172,7 +201,7 @@ def read_picture_into(self, buf): | |
args = bytes([0x0C, 0x0, 0x0A, 0, 0, (self._frame_ptr >> 8) & 0xFF, | ||
self._frame_ptr & 0xFF, 0, 0, 0, n & 0xFF, | ||
(_CAMERA_DELAY >> 8) & 0xFF, _CAMERA_DELAY & 0xFF]) | ||
if not self._run_command(_READ_FBUF, args, 5): | ||
if not self._run_command(_READ_FBUF, args, 5, flush=False): | ||
return 0 | ||
if self._read_response(self._buffer, n+5) == 0: | ||
return 0 | ||
|
@@ -192,7 +221,7 @@ def _run_command(self, cmd, args, resplen, flush=True): | |
return True | ||
|
||
def _read_response(self, result, numbytes): | ||
return self._uart.readinto(result, numbytes) | ||
return self._uart.readinto(memoryview(result)[0:numbytes]) | ||
|
||
def _verify_response(self, cmd): | ||
return (self._buffer[0] == 0x76 and self._buffer[1] == _SERIAL and | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
# VC0706 image capture to local storage. | ||
# You must wire up the VC0706 to a USB or hardware serial port. | ||
# Primarily for use with Linux/Raspberry Pi but also can work with Mac/Windows | ||
|
||
import time | ||
import serial | ||
import adafruit_vc0706 | ||
|
||
# Configuration: | ||
IMAGE_FILE = 'image.jpg' # Full path to file name to save captured image. | ||
# Will overwrite! | ||
|
||
# Create a serial connection for the VC0706 connection, speed is auto-detected. | ||
# Update the serial port name to match the serial connection for the camera! | ||
uart = serial.Serial("/dev/ttyUSB0", timeout=0.25) | ||
|
||
# Setup VC0706 camera | ||
vc0706 = adafruit_vc0706.VC0706(uart) | ||
|
||
# Print the version string from the camera. | ||
print('VC0706 version:') | ||
print(vc0706.version) | ||
|
||
# Set the baud rate to 115200 for fastest transfer (its the max speed) | ||
vc0706.baudrate = 115200 | ||
|
||
# Set the image size. | ||
vc0706.image_size = adafruit_vc0706.IMAGE_SIZE_640x480 # Or set IMAGE_SIZE_320x240 or | ||
# IMAGE_SIZE_160x120 | ||
# Note you can also read the property and compare against those values to | ||
# see the current size: | ||
size = vc0706.image_size | ||
if size == adafruit_vc0706.IMAGE_SIZE_640x480: | ||
print('Using 640x480 size image.') | ||
elif size == adafruit_vc0706.IMAGE_SIZE_320x240: | ||
print('Using 320x240 size image.') | ||
elif size == adafruit_vc0706.IMAGE_SIZE_160x120: | ||
print('Using 160x120 size image.') | ||
|
||
# Take a picture. | ||
print('Taking a picture in 3 seconds...') | ||
time.sleep(3) | ||
print('SNAP!') | ||
if not vc0706.take_picture(): | ||
raise RuntimeError('Failed to take picture!') | ||
|
||
# Print size of picture in bytes. | ||
frame_length = vc0706.frame_length | ||
print('Picture size (bytes): {}'.format(frame_length)) | ||
|
||
# Open a file for writing (overwriting it if necessary). | ||
# This will write 50 bytes at a time using a small buffer. | ||
# You MUST keep the buffer size under 100! | ||
print('Writing image: {}'.format(IMAGE_FILE), end='', flush=True) | ||
stamp = time.monotonic() | ||
with open(IMAGE_FILE, 'wb') as outfile: | ||
wcount = 0 | ||
while frame_length > 0: | ||
t = time.monotonic() | ||
# Compute how much data is left to read as the lesser of remaining bytes | ||
# or the copy buffer size (32 bytes at a time). Buffer size MUST be | ||
# a multiple of 4 and under 100. Stick with 32! | ||
to_read = min(frame_length, 32) | ||
copy_buffer = bytearray(to_read) | ||
# Read picture data into the copy buffer. | ||
if vc0706.read_picture_into(copy_buffer) == 0: | ||
raise RuntimeError('Failed to read picture frame data!') | ||
# Write the data to SD card file and decrement remaining bytes. | ||
outfile.write(copy_buffer) | ||
frame_length -= 32 | ||
# Print a dot every 2k bytes to show progress. | ||
wcount += 1 | ||
if wcount >= 64: | ||
print('.', end='', flush=True) | ||
wcount = 0 | ||
print() | ||
print('Finished in %0.1f seconds!' % (time.monotonic() - stamp)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest updating this, not just deleting it. It makes for nicely formatted docs: https://circuitpython.readthedocs.io/projects/vc0706/en/latest/api.html#adafruit_vc0706.VC0706