Skip to content

Commit 6c94c1e

Browse files
authored
Merge branch 'adafruit:main' into ducky-fix
2 parents 895b61f + f9ceb3f commit 6c94c1e

15 files changed

Lines changed: 380 additions & 24 deletions

File tree

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2021 Jeff Epler for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: Unlicense
4+
5+
"""
6+
This demo is designed for the Kaluga development kit version 1.3 with the
7+
ILI9341 display. Your secrets.py must be populated with your wifi credentials
8+
and your Adafruit IO credentials.
9+
"""
10+
11+
import ssl
12+
from secrets import secrets
13+
from ulab import numpy as np
14+
from terminalio import FONT
15+
import board
16+
import busio
17+
import displayio
18+
import qrio
19+
import socketpool
20+
import wifi
21+
import adafruit_ov2640
22+
from adafruit_display_text.bitmap_label import Label
23+
from adafruit_ili9341 import ILI9341
24+
from adafruit_io.adafruit_io import IO_MQTT
25+
import adafruit_minimqtt.adafruit_minimqtt as MQTT
26+
27+
# To change the name of the feed on adafruit_io, just modify this string:
28+
feed_name = "qrstring"
29+
30+
print("Initializing display")
31+
displayio.release_displays()
32+
spi = busio.SPI(MOSI=board.LCD_MOSI, clock=board.LCD_CLK)
33+
display_bus = displayio.FourWire(
34+
spi, command=board.LCD_D_C, chip_select=board.LCD_CS, reset=board.LCD_RST
35+
)
36+
display = ILI9341(display_bus, width=320, height=240, rotation=90)
37+
38+
print("Initializing camera")
39+
bus = busio.I2C(scl=board.CAMERA_SIOC, sda=board.CAMERA_SIOD)
40+
cam = adafruit_ov2640.OV2640(
41+
bus,
42+
data_pins=board.CAMERA_DATA,
43+
clock=board.CAMERA_PCLK,
44+
vsync=board.CAMERA_VSYNC,
45+
href=board.CAMERA_HREF,
46+
mclk=board.CAMERA_XCLK,
47+
mclk_frequency=20_000_000,
48+
size=adafruit_ov2640.OV2640_SIZE_QQVGA,
49+
)
50+
cam.flip_x = False
51+
cam.flip_y = False
52+
cam.colorspace = adafruit_ov2640.OV2640_COLOR_YUV
53+
54+
print("Connecting to WIFI")
55+
wifi.radio.connect(secrets["ssid"], secrets["password"])
56+
pool = socketpool.SocketPool(wifi.radio)
57+
58+
print("Connecting to Adafruit IO")
59+
mqtt_client = MQTT.MQTT(
60+
broker="io.adafruit.com",
61+
username=secrets["aio_username"],
62+
password=secrets["aio_key"],
63+
socket_pool=pool,
64+
ssl_context=ssl.create_default_context(),
65+
)
66+
mqtt_client.connect()
67+
io = IO_MQTT(mqtt_client)
68+
# Blank out any previously published message
69+
io.publish(feed_name, "\ufeff")
70+
71+
qrdecoder = qrio.QRDecoder(cam.width, cam.height)
72+
bitmap = displayio.Bitmap(cam.width, cam.height, 65536)
73+
74+
# Create a greyscale palette
75+
pal = displayio.Palette(256)
76+
for i in range(256):
77+
pal[i] = 0x10101 * i
78+
79+
label = Label(
80+
font=FONT,
81+
text="Scan QR Code...",
82+
color=0xFFFFFF,
83+
background_color=0x0,
84+
padding_top=2,
85+
padding_left=2,
86+
padding_right=2,
87+
padding_bottom=2,
88+
anchor_point=(0.5, 1.0),
89+
anchored_position=(160, 230),
90+
)
91+
# Show the camera image at 2x size
92+
g1 = displayio.Group(scale=2)
93+
view = np.frombuffer(bitmap, dtype=np.uint8)
94+
tg = displayio.TileGrid(
95+
bitmap,
96+
pixel_shader=pal,
97+
)
98+
tg.flip_y = True
99+
g1.append(tg)
100+
g = displayio.Group()
101+
g.append(g1)
102+
g.append(label)
103+
display.show(g)
104+
display.auto_refresh = False
105+
106+
old_payload = None
107+
while True:
108+
cam.capture(bitmap)
109+
110+
for row in qrdecoder.decode(bitmap, qrio.PixelPolicy.EVEN_BYTES):
111+
payload = row.payload
112+
try:
113+
payload = payload.decode("utf-8")
114+
except UnicodeError:
115+
payload = str(payload)
116+
if payload != old_payload:
117+
label.text = payload
118+
print(payload)
119+
for i in range(3):
120+
try:
121+
io.publish(feed_name, payload)
122+
old_payload = payload
123+
break
124+
except OSError as e:
125+
print(e)
126+
mqtt_client.reconnect()
127+
128+
# Clear out the odd bytes, so that the bitmap displays as greyscale
129+
view[1::2] = 0
130+
bitmap.dirty()
131+
display.refresh(minimum_frames_per_second=0)

CircuitPython_qrio/repl/code.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2021 Jeff Epler for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: Unlicense
4+
5+
"""
6+
This demo is designed for the Kaluga development kit version 1.3 with the
7+
ILI9341 display.
8+
"""
9+
10+
import ssl
11+
from ulab import numpy as np
12+
from terminalio import FONT
13+
import board
14+
import busio
15+
import displayio
16+
import qrio
17+
import adafruit_ov2640
18+
from adafruit_display_text.bitmap_label import Label
19+
from adafruit_ili9341 import ILI9341
20+
21+
print("Initializing display")
22+
displayio.release_displays()
23+
spi = busio.SPI(MOSI=board.LCD_MOSI, clock=board.LCD_CLK)
24+
display_bus = displayio.FourWire(
25+
spi, command=board.LCD_D_C, chip_select=board.LCD_CS, reset=board.LCD_RST
26+
)
27+
display = ILI9341(display_bus, width=320, height=240, rotation=90)
28+
29+
print("Initializing camera")
30+
bus = busio.I2C(scl=board.CAMERA_SIOC, sda=board.CAMERA_SIOD)
31+
cam = adafruit_ov2640.OV2640(
32+
bus,
33+
data_pins=board.CAMERA_DATA,
34+
clock=board.CAMERA_PCLK,
35+
vsync=board.CAMERA_VSYNC,
36+
href=board.CAMERA_HREF,
37+
mclk=board.CAMERA_XCLK,
38+
mclk_frequency=20_000_000,
39+
size=adafruit_ov2640.OV2640_SIZE_QQVGA,
40+
)
41+
cam.flip_x = False
42+
cam.flip_y = False
43+
cam.colorspace = adafruit_ov2640.OV2640_COLOR_YUV
44+
45+
qrdecoder = qrio.QRDecoder(cam.width, cam.height)
46+
bitmap = displayio.Bitmap(cam.width, cam.height, 65536)
47+
48+
# Create a greyscale palette
49+
pal = displayio.Palette(256)
50+
for i in range(256):
51+
pal[i] = 0x10101 * i
52+
53+
label = Label(
54+
font=FONT,
55+
text="Scan QR Code...",
56+
color=0xFFFFFF,
57+
background_color=0x0,
58+
padding_top=2,
59+
padding_left=2,
60+
padding_right=2,
61+
padding_bottom=2,
62+
anchor_point=(0.5, 1.0),
63+
anchored_position=(160, 230),
64+
)
65+
# Show the camera image at 2x size
66+
g1 = displayio.Group(scale=2)
67+
view = np.frombuffer(bitmap, dtype=np.uint8)
68+
tg = displayio.TileGrid(
69+
bitmap,
70+
pixel_shader=pal,
71+
)
72+
tg.flip_y = True
73+
g1.append(tg)
74+
g = displayio.Group()
75+
g.append(g1)
76+
g.append(label)
77+
display.show(g)
78+
display.auto_refresh = False
79+
80+
old_payload = None
81+
while True:
82+
cam.capture(bitmap)
83+
84+
for row in qrdecoder.decode(bitmap, qrio.PixelPolicy.EVEN_BYTES):
85+
payload = row.payload
86+
try:
87+
payload = payload.decode("utf-8")
88+
except UnicodeError:
89+
payload = str(payload)
90+
print(payload)
91+
92+
# Clear out the odd bytes, so that the bitmap displays as greyscale
93+
view[1::2] = 0
94+
bitmap.dirty()
95+
display.refresh(minimum_frames_per_second=0)

CircuitPython_qrio/usb_hid/code.py

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2021 Jeff Epler for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: Unlicense
4+
5+
"""
6+
This demo is designed for the Kaluga development kit version 1.3 with the
7+
ILI9341 display. Your secrets.py must be populated with your wifi credentials
8+
and your Adafruit IO credentials.
9+
"""
10+
11+
from ulab import numpy as np
12+
from terminalio import FONT
13+
import board
14+
import busio
15+
import displayio
16+
import qrio
17+
import adafruit_ov2640
18+
from adafruit_display_text.bitmap_label import Label
19+
from adafruit_ili9341 import ILI9341
20+
import adafruit_minimqtt.adafruit_minimqtt as MQTT
21+
import usb_hid
22+
from adafruit_hid.keyboard import Keyboard
23+
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
24+
from adafruit_hid.keycode import Keycode
25+
26+
print("Initializing display")
27+
displayio.release_displays()
28+
spi = busio.SPI(MOSI=board.LCD_MOSI, clock=board.LCD_CLK)
29+
display_bus = displayio.FourWire(
30+
spi, command=board.LCD_D_C, chip_select=board.LCD_CS, reset=board.LCD_RST
31+
)
32+
display = ILI9341(display_bus, width=320, height=240, rotation=90)
33+
34+
print("Initializing camera")
35+
bus = busio.I2C(scl=board.CAMERA_SIOC, sda=board.CAMERA_SIOD)
36+
cam = adafruit_ov2640.OV2640(
37+
bus,
38+
data_pins=board.CAMERA_DATA,
39+
clock=board.CAMERA_PCLK,
40+
vsync=board.CAMERA_VSYNC,
41+
href=board.CAMERA_HREF,
42+
mclk=board.CAMERA_XCLK,
43+
mclk_frequency=20_000_000,
44+
size=adafruit_ov2640.OV2640_SIZE_QQVGA,
45+
)
46+
cam.flip_x = False
47+
cam.flip_y = False
48+
cam.colorspace = adafruit_ov2640.OV2640_COLOR_YUV
49+
50+
print("Initializing USB")
51+
keyboard = Keyboard(usb_hid.devices)
52+
keyboard_layout = KeyboardLayoutUS(keyboard) # We're in the US :)
53+
54+
qrdecoder = qrio.QRDecoder(cam.width, cam.height)
55+
bitmap = displayio.Bitmap(cam.width, cam.height, 65536)
56+
57+
# Create a greyscale palette
58+
pal = displayio.Palette(256)
59+
for i in range(256):
60+
pal[i] = 0x10101 * i
61+
62+
label = Label(
63+
font=FONT,
64+
text="Scan QR Code...",
65+
color=0xFFFFFF,
66+
background_color=0x0,
67+
padding_top=2,
68+
padding_left=2,
69+
padding_right=2,
70+
padding_bottom=2,
71+
anchor_point=(0.5, 1.0),
72+
anchored_position=(160, 230),
73+
)
74+
# Show the camera image at 2x size
75+
g1 = displayio.Group(scale=2)
76+
view = np.frombuffer(bitmap, dtype=np.uint8)
77+
tg = displayio.TileGrid(
78+
bitmap,
79+
pixel_shader=pal,
80+
)
81+
tg.flip_y = True
82+
g1.append(tg)
83+
g = displayio.Group()
84+
g.append(g1)
85+
g.append(label)
86+
display.show(g)
87+
display.auto_refresh = False
88+
89+
i = 0
90+
spin = ".oOo"
91+
old_payload = None
92+
while True:
93+
cam.capture(bitmap)
94+
95+
for row in qrdecoder.decode(bitmap, qrio.PixelPolicy.EVEN_BYTES):
96+
payload = row.payload
97+
try:
98+
payload = payload.decode("utf-8")
99+
except UnicodeError:
100+
payload = str(payload)
101+
if payload != old_payload:
102+
label.text = payload
103+
keyboard_layout.write(payload)
104+
old_payload = payload
105+
106+
# Clear out the odd bytes, so that the bitmap displays as greyscale
107+
view[1::2] = 0
108+
bitmap.dirty()
109+
display.refresh(minimum_frames_per_second=0)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import usb_cdc
2+
3+
usb_cdc.enable(console=True, data=True)

MacroPad_RPC_Home_Assistant/code.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class MqttError(Exception):
4848
def rpc_call(function, *args, **kwargs):
4949
response = rpc.call(function, *args, **kwargs)
5050
if response["error"]:
51-
if response["error_type"]:
51+
if response["error_type"] == "mqtt":
5252
raise MqttError(response["message"])
5353
raise RpcError(response["message"])
5454
return response["return_val"]
@@ -58,11 +58,21 @@ def mqtt_init():
5858
rpc_call("mqtt_connect")
5959

6060
def update_key(key_number):
61-
switch_state = rpc_call("mqtt_get_last_value", SUBSCRIBE_TOPICS[key_number])
62-
if switch_state is not None:
63-
macropad.pixels[key_number] = NEOPIXEL_COLORS[switch_state]
64-
else:
65-
macropad.pixels[key_number] = None
61+
if key_number < len(SUBSCRIBE_TOPICS):
62+
switch_state = rpc_call("mqtt_get_last_value", SUBSCRIBE_TOPICS[key_number])
63+
if switch_state is not None:
64+
macropad.pixels[key_number] = NEOPIXEL_COLORS[switch_state]
65+
else:
66+
macropad.pixels[key_number] = 0
67+
68+
server_is_running = False
69+
print("Waiting for server...")
70+
while not server_is_running:
71+
try:
72+
server_is_running = rpc_call("is_running")
73+
print("Connected")
74+
except RpcError:
75+
pass
6676

6777
mqtt_init()
6878
last_macropad_encoder_value = macropad.encoder
@@ -92,6 +102,8 @@ def update_key(key_number):
92102
if "key_number" in output:
93103
time.sleep(UPDATE_DELAY)
94104
update_key(output["key_number"])
105+
elif ENCODER_ITEM is not None:
106+
update_key(ENCODER_ITEM)
95107
except MqttError:
96108
mqtt_init()
97109
except RpcError as err_msg:

MacroPad_RPC_Home_Assistant/rpc.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
import usb_cdc as serial
1616
json_decode_exception = ValueError
1717

18-
RESPONSE_TIMEOUT=1
19-
DATA_TIMEOUT=0.2
18+
RESPONSE_TIMEOUT=5
19+
DATA_TIMEOUT=0.5
2020

2121
class RpcError(Exception):
2222
"""For RPC Specific Errors"""

0 commit comments

Comments
 (0)