This commit is contained in:
Cyril Li 2024-10-21 21:55:29 -05:00
parent 3a5a189a61
commit 648dfefa44
4 changed files with 106 additions and 10 deletions

View file

@ -19,4 +19,6 @@
# Case Components
- `acrylic` - 3mm acrylic sheet
- `top` and `bottom` - 3D printed, any colour
- 4x M3 screws & nuts, at least 50mm long (case should be easily disassembled)
- 4x M3 screws & nuts, at least 50mm long (case should be easily disassembled)
## *Firmware is written in CircuitPython.*

View file

@ -0,0 +1,51 @@
# This program requires the 'wtype' command to be installed on the computer.
from serial import Serial
import json, subprocess, time
keymap = [
"a",
"b",
"c",
"d",
"e",
"f",
"g",
"h",
"i",
"j",
"k"
]
port = input ("Enter the port name (e.g. /dev/ttyACM0 for Linux): ")
ser = Serial (port, write_timeout = 0.1)
while ser.readline () != b"HackPad\n":
ser.write (b"HkPd\n")
time.sleep (0.2)
keys = (0, ) * 11
while True:
response = json.reads (ser.readline ().decode ("utf-8"))
keys1, enc, rx = response ["keys"], response ["enc"], response ["rx"]
# TODO: debouncing
for j, (k, k1) in enumerate (zip (keys, keys1)):
if k < k1: # Keydown
subprocess.run (["wtype", "-P", keymap [j]])
elif k > k1: # Keyup
subprocess.run (["wtype", "-p", keymap [j]])
keys = keys1
# TODO: sensitivity
enc = sum (enc)
for i in range (abs (enc)):
if enc < 0:
subprocess.run (["wtype", "-k", "XF86AudioLowerVolume"])
else:
subprocess.run (["wtype", "-k", "XF86AudioRaiseVolume"])
# Do something with rx
print (rx)
# Send the response (tx)

View file

@ -0,0 +1 @@
pyserial

View file

@ -1,7 +1,8 @@
import analogio, board, digitalio, usb_cdc
import analogio, board, digitalio, json, time, usb_cdc
from array import array
# I/O initialization
global owsi_in, kbclk, kb0, kb1, gp2, gp1, gp0, owsi_pd, owsi_wpu, owsi_spu
owsi_in = analogio.AnalogIn (board.A0)
kbclk = digitalio.DigitalInOut (board.D1)
kbclk.switch_to_output ()
@ -16,11 +17,11 @@ gp1.switch_to_output ()
gp0 = digitalio.DigitalInOut (board.D6)
gp0.switch_to_output ()
owsi_pd = digitalio.DigitalInOut (board.D7)
owsi_pd.switch_to_output ()
owsi_pd.switch_to_output (True)
owsi_wpu = digitalio.DigitalInOut (board.D8)
owsi_wpu.switch_to_output ()
owsi_wpu.switch_to_output (True)
owsi_spu = digitalio.DigitalInOut (board.D9)
owsi_spu.switch_to_output ()
owsi_spu.switch_to_output (True)
serial = usb_cdc.data
@ -37,6 +38,7 @@ enc_ttable = array ("b", (
))
def read_kb ():
nonlocal enc_a, enc_b, enc_ttable
keys = array ("b", (0, ) * 11)
enc = array ("b")
for i in (0, 5):
@ -47,6 +49,7 @@ def read_kb ():
keys [i + 1] = kb0.value
enc_b1 = kb1.value
enc.append (enc_ttable [enc_a << 3 | enc_b << 2 | enc_a1 << 1 | enc_b1])
enc_a, enc_b = enc_a1, enc_b1
kbclk.value = True
kbclk.value = False
keys [i + 2] = kb0.value
@ -65,16 +68,55 @@ def read_kb ():
kbclk.value = False
return keys, enc
def owsi ():
def owsi (tx, delay = 0.0001, thresh = 15000) # 100 us between bits, ~1.5V logic leve, can be adjusted
"""
This is a simple subset of the OWSI protocol which just passes data continuously between two devices.
It is ultimately used to control up to 16 smart home devices with a focus on switches and dimmers.
"""
pass
# TODO: Schmitt trigger
# Configured as receive-first for this example
rx = array ("b")
while owsi_in.value > thresh:
pass # Wait for low signal
for i in range (8):
owsi_spu.value, owsi_wpu.value, owsi_pd.value = False, False, False # Pull up
sleep (delay)
owsi_spu.value = True # Weak pull up
sleep (delay)
rx.append (owsi_in.value > thresh)
owsi_wpu.value, owsi_pd.value = True, True # Pull down
sleep (delay)
owsi_spu.value, owsi_wpu.value, owsi_pd.value = False, False, False # Pull up
sleep (delay)
owsi_spu.value = True # Weak pull up
sleep (delay)
while owsi_in.value > thresh:
pass # Wait for low signal
owsi_wpu.value, owsi_pd.value = True, False # Floating
# Transmit
for i in tx:
while owsi_in.value < thresh:
pass
owsi_pd.value = i # Set data
while owsi_in.value > thresh:
pass
while owsi_in.value < thresh:
pass
return rx
def main ()
ack = ["-"] * 5
while ack != ["H", "k", "P", "d", "\n"]:
ack.append (serial.read ().decode ("utf-8"))
ack.pop (0)
time.sleep (0.01)
serial.write (b"HackPad\n")
while True:
keys, enc = read_kb ()
serial.write (keys)
serial.write (enc)
serial.write (owsi ())
rx = owsi ((1, ) * 8) # TODO: Full protocol
serial.write (json.dumps ({"keys": tuple (keys), "enc": tuple (enc), "rx": tuple (rx)}).encode ("utf-8"))