Skip to content

Commit 990dcd0

Browse files
authored
Merge pull request #5 from ladyada/master
a little refactoring, speed-up, and CPython compatibility
2 parents f0d58c6 + 20ca342 commit 990dcd0

File tree

4 files changed

+134
-24
lines changed

4 files changed

+134
-24
lines changed

adafruit_vc0706.py

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
* Adafruit CircuitPython firmware for the ESP8622 and M0-based boards:
4343
https://github.com/adafruit/circuitpython/releases
4444
"""
45-
import busio
4645
from micropython import const
4746

4847
__version__ = "0.0.0-auto.0"
@@ -79,6 +78,11 @@
7978
IMAGE_SIZE_320x240 = const(0x11)
8079
IMAGE_SIZE_160x120 = const(0x22)
8180
# pylint: enable=invalid-name
81+
_BAUDRATE_9600 = const(0xAEC8)
82+
_BAUDRATE_19200 = const(0x56E4)
83+
_BAUDRATE_38400 = const(0x2AF2)
84+
_BAUDRATE_57600 = const(0x1C1C)
85+
_BAUDRATE_115200 = const(0x0DA6)
8286

8387
_MOTIONCONTROL = const(0x0)
8488
_UARTMOTION = const(0x01)
@@ -93,36 +97,62 @@
9397

9498
class VC0706:
9599
"""Driver for VC0706 serial TTL camera module.
96-
97-
:param ~microcontroller.Pin rx: Receive pin
98-
:param ~microcontroller.Pin tx: Transmit pin
99-
:param int baudrate: Serial connection speed
100-
:param int timeout: Read timeout in seconds
100+
:param ~busio.UART uart: uart serial or compatible interface
101101
:param int buffer_size: Receive buffer size
102102
"""
103-
def __init__(self, rx, tx, *, baudrate=38400, timeout=250, buffer_size=100):
104-
self._uart = busio.UART(tx, rx, baudrate=baudrate, timeout=timeout)
103+
def __init__(self, uart, *, buffer_size=100):
104+
self._uart = uart
105105
self._buffer = bytearray(buffer_size)
106106
self._frame_ptr = 0
107107
self._command_header = bytearray(3)
108-
if not self._run_command(_RESET, bytes([0x00]), 5):
109-
raise RuntimeError('Failed to get response from VC0706, check wiring!')
108+
for _ in range(2): # 2 retries to reset then check resetted baudrate
109+
for baud in (9600, 19200, 38400, 57600, 115200):
110+
self._uart.baudrate = baud
111+
if self._run_command(_RESET, b'\x00', 5):
112+
break
113+
else: # for:else rocks! http://book.pythontips.com/en/latest/for_-_else.html
114+
raise RuntimeError('Failed to get response from VC0706, check wiring!')
110115

111116
@property
112117
def version(self):
113118
"""Return camera version byte string."""
114119
# Clear buffer to ensure the end of a string can be found.
115-
self._send_command(_GEN_VERSION, bytes([0x01]))
120+
self._send_command(_GEN_VERSION, b'\x01')
116121
readlen = self._read_response(self._buffer, len(self._buffer))
117122
return str(self._buffer[:readlen], 'ascii')
118123

124+
@property
125+
def baudrate(self):
126+
"""Return the currently configured baud rate."""
127+
return self._uart.baudrate
128+
129+
@baudrate.setter
130+
def baudrate(self, baud):
131+
"""Set the baudrate to 9600, 19200, 38400, 57600, or 115200. """
132+
divider = None
133+
if baud == 9600:
134+
divider = _BAUDRATE_9600
135+
elif baud == 19200:
136+
divider = _BAUDRATE_19200
137+
elif baud == 38400:
138+
divider = _BAUDRATE_38400
139+
elif baud == 57600:
140+
divider = _BAUDRATE_57600
141+
elif baud == 115200:
142+
divider = _BAUDRATE_115200
143+
else:
144+
raise ValueError("Unsupported baud rate")
145+
args = [0x03, 0x01, (divider>>8) & 0xFF, divider & 0xFF]
146+
self._run_command(_SET_PORT, bytes(args), 7)
147+
self._uart.baudrate = baud
148+
119149
@property
120150
def image_size(self):
121151
"""Get the current image size, will return a value of IMAGE_SIZE_640x480,
122152
IMAGE_SIZE_320x240, or IMAGE_SIZE_160x120.
123153
"""
124154
if not self._run_command(_READ_DATA,
125-
bytes([0x4, 0x4, 0x1, 0x00, 0x19]),
155+
b'\0x04\x04\x01\x00\x19',
126156
6):
127157
raise RuntimeError('Failed to read image size!')
128158
return self._buffer[5]
@@ -141,7 +171,7 @@ def image_size(self, size):
141171
def frame_length(self):
142172
"""Return the length in bytes of the currently capture frame/picture.
143173
"""
144-
if not self._run_command(_GET_FBUF_LEN, bytes([0x01, 0x00]), 9):
174+
if not self._run_command(_GET_FBUF_LEN, b'\x01\x00', 9):
145175
return 0
146176
frame_length = self._buffer[5]
147177
frame_length <<= 8
@@ -172,7 +202,7 @@ def read_picture_into(self, buf):
172202
args = bytes([0x0C, 0x0, 0x0A, 0, 0, (self._frame_ptr >> 8) & 0xFF,
173203
self._frame_ptr & 0xFF, 0, 0, 0, n & 0xFF,
174204
(_CAMERA_DELAY >> 8) & 0xFF, _CAMERA_DELAY & 0xFF])
175-
if not self._run_command(_READ_FBUF, args, 5):
205+
if not self._run_command(_READ_FBUF, args, 5, flush=False):
176206
return 0
177207
if self._read_response(self._buffer, n+5) == 0:
178208
return 0
@@ -192,7 +222,7 @@ def _run_command(self, cmd, args, resplen, flush=True):
192222
return True
193223

194224
def _read_response(self, result, numbytes):
195-
return self._uart.readinto(result, numbytes)
225+
return self._uart.readinto(memoryview(result)[0:numbytes])
196226

197227
def _verify_response(self, cmd):
198228
return (self._buffer[0] == 0x76 and self._buffer[1] == _SERIAL and

examples/snapshot.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@
1818

1919

2020
# Configuration:
21-
SD_CS_PIN = board.SD_CS # CS for SD card (SD_CS is for Feather Adalogger)
22-
RX_PIN = board.RX # RX pin of board, connected to VC0706 TX
23-
TX_PIN = board.TX # TX pin of board, connected to VC0706 RX
21+
SD_CS_PIN = board.D10 # CS for SD card (SD_CS is for Feather Adalogger)
2422
IMAGE_FILE = '/sd/image.jpg' # Full path to file name to save captured image.
2523
# Will overwrite!
2624

@@ -33,13 +31,18 @@
3331
vfs = storage.VfsFat(sdcard)
3432
storage.mount(vfs, '/sd')
3533

36-
# Setup VC0706.
37-
vc0706 = adafruit_vc0706.VC0706(RX_PIN, TX_PIN)
34+
# Create a serial connection for the VC0706 connection, speed is auto-detected.
35+
uart = busio.UART(board.TX, board.RX, timeout=250)
36+
# Setup VC0706 camera
37+
vc0706 = adafruit_vc0706.VC0706(uart)
3838

3939
# Print the version string from the camera.
4040
print('VC0706 version:')
4141
print(vc0706.version)
4242

43+
# Set the baud rate to 115200 for fastest transfer (its the max speed)
44+
vc0706.baudrate = 115200
45+
4346
# Set the image size.
4447
vc0706.image_size = adafruit_vc0706.IMAGE_SIZE_640x480 # Or set IMAGE_SIZE_320x240 or
4548
# IMAGE_SIZE_160x120

examples/snapshot_computer.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# VC0706 image capture to local storage.
2+
# You must wire up the VC0706 to a USB or hardware serial port.
3+
# Primarily for use with Linux/Raspberry Pi but also can work with Mac/Windows
4+
5+
import time
6+
import serial
7+
import adafruit_vc0706
8+
9+
# Configuration:
10+
IMAGE_FILE = 'image.jpg' # Full path to file name to save captured image.
11+
# Will overwrite!
12+
13+
# Create a serial connection for the VC0706 connection, speed is auto-detected.
14+
# Update the serial port name to match the serial connection for the camera!
15+
uart = serial.Serial("/dev/ttyUSB0", timeout=0.25)
16+
17+
# Setup VC0706 camera
18+
vc0706 = adafruit_vc0706.VC0706(uart)
19+
20+
# Print the version string from the camera.
21+
print('VC0706 version:')
22+
print(vc0706.version)
23+
24+
# Set the baud rate to 115200 for fastest transfer (its the max speed)
25+
vc0706.baudrate = 115200
26+
27+
# Set the image size.
28+
vc0706.image_size = adafruit_vc0706.IMAGE_SIZE_640x480 # Or set IMAGE_SIZE_320x240 or
29+
# IMAGE_SIZE_160x120
30+
# Note you can also read the property and compare against those values to
31+
# see the current size:
32+
size = vc0706.image_size
33+
if size == adafruit_vc0706.IMAGE_SIZE_640x480:
34+
print('Using 640x480 size image.')
35+
elif size == adafruit_vc0706.IMAGE_SIZE_320x240:
36+
print('Using 320x240 size image.')
37+
elif size == adafruit_vc0706.IMAGE_SIZE_160x120:
38+
print('Using 160x120 size image.')
39+
40+
# Take a picture.
41+
print('Taking a picture in 3 seconds...')
42+
time.sleep(3)
43+
print('SNAP!')
44+
if not vc0706.take_picture():
45+
raise RuntimeError('Failed to take picture!')
46+
47+
# Print size of picture in bytes.
48+
frame_length = vc0706.frame_length
49+
print('Picture size (bytes): {}'.format(frame_length))
50+
51+
# Open a file for writing (overwriting it if necessary).
52+
# This will write 50 bytes at a time using a small buffer.
53+
# You MUST keep the buffer size under 100!
54+
print('Writing image: {}'.format(IMAGE_FILE), end='', flush=True)
55+
stamp = time.monotonic()
56+
with open(IMAGE_FILE, 'wb') as outfile:
57+
wcount = 0
58+
while frame_length > 0:
59+
t = time.monotonic()
60+
# Compute how much data is left to read as the lesser of remaining bytes
61+
# or the copy buffer size (32 bytes at a time). Buffer size MUST be
62+
# a multiple of 4 and under 100. Stick with 32!
63+
to_read = min(frame_length, 32)
64+
copy_buffer = bytearray(to_read)
65+
# Read picture data into the copy buffer.
66+
if vc0706.read_picture_into(copy_buffer) == 0:
67+
raise RuntimeError('Failed to read picture frame data!')
68+
# Write the data to SD card file and decrement remaining bytes.
69+
outfile.write(copy_buffer)
70+
frame_length -= 32
71+
# Print a dot every 2k bytes to show progress.
72+
wcount += 1
73+
if wcount >= 64:
74+
print('.', end='', flush=True)
75+
wcount = 0
76+
print()
77+
print('Finished in %0.1f seconds!' % (time.monotonic() - stamp))

examples/snapshot_internal.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@
1010
import adafruit_vc0706
1111

1212
# Configuration:
13-
RX_PIN = board.RX # RX pin of board, connected to VC0706 TX
14-
TX_PIN = board.TX # TX pin of board, connected to VC0706 RX
1513
IMAGE_FILE = '/image.jpg' # Full path to file name to save captured image.
1614
# Will overwrite!
1715

1816
# Setup SPI bus (hardware SPI).
1917
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
2018

21-
# Setup VC0706.
22-
vc0706 = adafruit_vc0706.VC0706(RX_PIN, TX_PIN)
19+
# Create a serial connection for the VC0706 connection, speed is auto-detected.
20+
uart = busio.UART(board.TX, board.RX, timeout=250)
21+
# Setup VC0706 camera
22+
vc0706 = adafruit_vc0706.VC0706(uart)
2323

2424
# Print the version string from the camera.
2525
print('VC0706 version:')

0 commit comments

Comments
 (0)