Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
# SPDX-FileCopyrightText: Copyright (c) 2021 Jeff Epler for Adafruit Industries
#
# SPDX-License-Identifier: Unlicense
"""
Take a 10-frame stop motion GIF image.
This example requires:
* `Espressif Kaluga v1.3 <https://www.adafruit.com/product/4729>`_ with compatible LCD display
* `MicroSD card breakout board + <https://www.adafruit.com/product/254>`_ connected as follows:
* CLK to board.IO18
* DI to board.IO14
* DO to board.IO17
* CS to IO12
* GND to GND
* 5V to 5V
* A compatible SD card inserted in the SD card slot
* A compatible camera module (such as OV5640) connected to the camera header
To use:
Insert an SD card and power on.
Set up the first frame using the viewfinder. Click the REC button to take a frame.
Set up the next frame using the viewfinder. The previous and current frames are blended together on the display, which is called an "onionskin". Click the REC button to take the next frame.
After 10 frames are recorded, the GIF is complete and you can begin recording another.
About the Kaluga development kit:
The Kaluga development kit comes in two versions (v1.2 and v1.3); this demo is
tested on v1.3.
The audio board must be mounted between the Kaluga and the LCD, it provides the
I2C pull-ups(!)
The v1.3 development kit's LCD can have one of two chips, the ili9341 or
st7789. Furthermore, there are at least 2 ILI9341 variants, which differ
by rotation. This example is written for one if the ILI9341 variants,
the one which usually uses rotation=90 to get a landscape display.
"""
import os
import struct
import time
import dotenv
import io
import sys
import gifio
import adafruit_ticks
import binascii
import esp32_camera
import analogio
import board
import busio
import bitmaptools
import digitalio
import displayio
import socketpool
import wifi
import ssl
import adafruit_requests
aio_username = dotenv.get_key('/.env', 'AIO_USERNAME')
aio_key = dotenv.get_key('/.env', 'AIO_KEY')
image_feed = "image"
onoff_feed = "on_off"
cam = esp32_camera.Camera(
data_pins=board.CAMERA_DATA,
external_clock_pin=board.CAMERA_XCLK,
pixel_clock_pin=board.CAMERA_PCLK,
vsync_pin=board.CAMERA_VSYNC,
href_pin=board.CAMERA_HREF,
pixel_format=esp32_camera.PixelFormat.JPEG,
frame_size=esp32_camera.FrameSize.SVGA,
i2c=board.I2C(),
external_clock_frequency=20_000_000,
grab_mode=esp32_camera.GrabMode.WHEN_EMPTY)
cam.vflip = True
pool = socketpool.SocketPool(wifi.radio)
import adafruit_minimqtt.adafruit_minimqtt as MQTT
from adafruit_io.adafruit_io import IO_MQTT
print("Connecting to Adafruit IO")
mqtt_client = MQTT.MQTT(
broker="io.adafruit.com",
username=aio_username,
password=aio_key,
socket_pool=pool,
ssl_context=ssl.create_default_context(),
)
mqtt_client.connect()
io = IO_MQTT(mqtt_client)
def sleep_deadline(deadline):
while True:
now = adafruit_ticks.ticks_ms()
if now > deadline: break
time.sleep(adafruit_ticks.ticks_diff(deadline, now) / 1000)
ms_per_frame = 10*1000
t0 = adafruit_ticks.ticks_ms()
while True:
frame = cam.take(1)
if isinstance(frame, memoryview):
jpeg = frame
print(f"Captured {len(jpeg)} bytes of jpeg data")
# b2a_base64() appends a trailing newline, which IO does not like
encoded_data = binascii.b2a_base64(jpeg).strip()
print(f"Expanded to {len(encoded_data)} for IO upload")
io.publish("image", encoded_data)
end = t0 + ms_per_frame
sleep_deadline(end)
### i = io.BytesIO()
### with gifio.GifWriter(i, 240, 240, displayio.Colorspace.RGB565_SWAPPED, dither=True) as g:
### g.add_frame(frame)
### content = "data:image/gif;base64," + str(binascii.b2a_base64(i.getvalue()).strip(), "")
### # for i in range(0, len(content), 72):
### # print(repr(content[i:i+72]))
###
### # print(f"content length is {len(content)=}")
### # print(f"content length is {len(content.encode('utf-8'))=}")
### # print(repr(content[:70]))
### # print(repr(content[-70:]))
### # print(content.count("jepler"))
### publish_http(image_feed, content)
### t1 = adafruit_ticks.cticks_ms()
###
### fps = 1000 / (t1-t0)
### t0 = t1
### print(f"{fps:3.1f}fps")
### # break
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment