Skip to content

Commit

Permalink
Merge pull request #4 from adafruit/internal-storage-example
Browse files Browse the repository at this point in the history
Internal storage example
  • Loading branch information
jepler committed Oct 9, 2021
2 parents 9e3b43b + 488e990 commit 5f411df
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 27 deletions.
6 changes: 3 additions & 3 deletions adafruit_ov5640.py
Original file line number Diff line number Diff line change
Expand Up @@ -1165,14 +1165,14 @@ def effect(self, value):

@property
def quality(self):
"""Controls the JPEG quality. Valid range is from 5..55 inclusive"""
"""Controls the JPEG quality. Valid range is from 2..55 inclusive"""
return self._read_register(_COMPRESSION_CTRL07) & 0x3F

@quality.setter
def quality(self, value: int):
if not 5 <= value < 55:
if not 2 <= value < 55:
raise ValueError(
f"Invalid quality value {value}, use a value from 5..55 inclusive"
f"Invalid quality value {value}, use a value from 2..55 inclusive"
)
self._write_register(_COMPRESSION_CTRL07, value & 0x3F)

Expand Down
4 changes: 0 additions & 4 deletions examples/ov5640_directio_kaluga1_3_ili9341.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,11 @@
the one which usually uses rotation=90 to get a landscape display.
"""

import os
import struct

import analogio
import board
import busio
import displayio
import sdcardio
import storage
import adafruit_ov5640

# Release any resources currently in use for the displays
Expand Down
57 changes: 47 additions & 10 deletions examples/ov5640_jpeg_kaluga1_3.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,45 @@
The audio board must be mounted between the Kaluga and the LCD, it provides the
I2C pull-ups(!)
You also need to place ov5640_jpeg_kaluga1_3_boot.py at CIRCUITPY/boot.py
and reset the board to make the internal flash readable by CircuitPython.
You can make CIRCUITPY readable from your PC by booting CircuitPython in
safe mode or holding the "MODE" button on the audio daughterboard while
powering on or resetting the board.
You also need to place ov5640_jpeg_kaluga1_3_boot.py at CIRCUITPY/boot.py.
Then, hold the Mode button (button K2 on the audio board) while resetting the
board to make the internal flash readable by CircuitPython.
"""

import time

import board
import busio
import displayio
import microcontroller

import adafruit_ili9341
import adafruit_ov5640

# Release any resources currently in use for the displays
displayio.release_displays()
spi = busio.SPI(MOSI=board.LCD_MOSI, clock=board.LCD_CLK)
display_bus = displayio.FourWire(
spi,
command=board.LCD_D_C,
chip_select=board.LCD_CS,
reset=board.LCD_RST,
baudrate=80_000_000,
)
display = adafruit_ili9341.ILI9341(display_bus, width=320, height=240, rotation=90)

try:
with open("/boot_out.txt", "ab") as f:
pass
except OSError as e:
print(e)
print(
"A 'read-only filesystem' error occurs if you did not correctly install"
"\nov5640_jpeg_kaluga1_3_boot.py as CIRCUITPY/boot.py and reset the"
'\nboard while holding the "mode" button'
"\n\nThis message is also shown after the board takes a picture and auto-restarts"
)
raise SystemExit from e

bus = busio.I2C(scl=board.CAMERA_SIOC, sda=board.CAMERA_SIOD)
cam = adafruit_ov5640.OV5640(
Expand All @@ -30,22 +58,31 @@
vsync=board.CAMERA_VSYNC,
href=board.CAMERA_HREF,
mclk=board.CAMERA_XCLK,
mclk_frequency=20_000_000,
size=adafruit_ov5640.OV5640_SIZE_QVGA,
size=adafruit_ov5640.OV5640_SIZE_QSXGA,
)

cam.colorspace = adafruit_ov5640.OV5640_COLOR_JPEG
cam.quality = 5
b = bytearray(cam.capture_buffer_size)
print(f"Capturing jpeg image of up to {len(b)} bytes")
jpeg = cam.capture(b)

print(f"Captured {len(jpeg)} bytes of jpeg data")
try:
with open("/jpeg.jpg", "wb") as f:
f.write(jpeg)
print(end="Writing to internal storage (this is SLOW)")
with open("/cam.jpg", "wb") as f:
for i in range(0, len(jpeg), 4096):
print(end=".")
f.write(jpeg[i : i + 4096])
print()
print("Wrote to CIRCUITPY/cam.jpg")
print("Resetting so computer sees new content of CIRCUITPY")
time.sleep(0.5)
microcontroller.reset() # pylint: disable=no-member

except OSError as e:
print(e)
print(
"A 'read-only filesystem' error occurs if you did not correctly install"
"\nov5640_jpeg_kaluga1_3_boot.py as CIRCUITPY/boot.py and reset the board"
)
print("Wrote to CIRCUITPY/jpeg.jpg")
5 changes: 3 additions & 2 deletions examples/ov5640_jpeg_kaluga1_3_boot.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"""Use this file as CIRCUITPY/boot.py in conjunction with ov5640_jpeg_kaluga1_3.py
It makes the CIRCUITPY filesystem writable to CircuitPython
(and read-only to the PC) unless the "MODE" button on the audio
(and read-only to the PC) if the "MODE" button on the audio
daughterboard is held while the board is powered on or reset.
"""

Expand All @@ -18,6 +18,7 @@

a = analogio.AnalogIn(board.IO6)
a_voltage = a.value * a.reference_voltage / 65535 # pylint: disable=no-member
if abs(a_voltage - V_MODE) > 0.05: # If mode is NOT pressed...
print("measured voltage", a_voltage)
if abs(a_voltage - V_MODE) < 0.05: # If mode IS pressed...
print("storage writable by CircuitPython")
storage.remount("/", readonly=False)
34 changes: 26 additions & 8 deletions examples/ov5640_sdcard_kaluga_1_3.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,30 @@
"""

import os

import time

import analogio
import board
import busio
import adafruit_ov5640
import displayio
import neopixel
import storage
import sdcardio
import storage

import adafruit_ili9341
import adafruit_ov5640

# Release any resources currently in use for the displays
displayio.release_displays()
spi = busio.SPI(MOSI=board.LCD_MOSI, clock=board.LCD_CLK)
display_bus = displayio.FourWire(
spi,
command=board.LCD_D_C,
chip_select=board.LCD_CS,
reset=board.LCD_RST,
baudrate=80_000_000,
)
display = adafruit_ili9341.ILI9341(display_bus, width=320, height=240, rotation=90)

V_MODE = 1.98
V_RECORD = 2.41
Expand Down Expand Up @@ -60,15 +75,15 @@ def exists(filename):
try:
os.stat(filename)
return True
except OSError as e:
except OSError as _:
return False


_image_counter = 0


def open_next_image():
global _image_counter
global _image_counter # pylint: disable=global-statement
while True:
filename = f"/sd/img{_image_counter:04d}.jpg"
_image_counter += 1
Expand All @@ -86,15 +101,16 @@ def open_next_image():
while True:
pixel[0] = 0x0000FF
pixel.write()
a_voltage = a.value * a.reference_voltage / 65535
a_voltage = a.value * a.reference_voltage / 65535 # pylint: disable=no-member
record_pressed = abs(a_voltage - V_RECORD) < 0.05
if record_pressed:
pixel[0] = 0xFF0000
pixel.write()
time.sleep(0.01)
jpeg = cam.capture(b)
print(
f"Captured {len(jpeg)} bytes of jpeg data (had allocated {cam.capture_buffer_size} bytes"
f"Captured {len(jpeg)} bytes of jpeg data"
f" (had allocated {cam.capture_buffer_size} bytes"
)
print(f"Resolution {cam.width}x{cam.height}")
try:
Expand All @@ -108,5 +124,7 @@ def open_next_image():
except OSError as e:
print(e)
while record_pressed:
a_voltage = a.value * a.reference_voltage / 65535
a_voltage = (
a.value * a.reference_voltage / 65535
) # pylint: disable=no-member
record_pressed = abs(a_voltage - V_RECORD) < 0.05

0 comments on commit 5f411df

Please sign in to comment.