Skip to content
Snippets Groups Projects
Commit 3409f154 authored by schneider's avatar schneider
Browse files

feat(ptt): Add demo app

parent acf4aa2e
No related branches found
No related tags found
1 merge request!439feat(ptt): Add demo app
Pipeline #5064 passed
import ble_hid
import buttons
import max86150
import leds
import vibra
import display
import simple_menu
import color
import config
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
from adafruit_hid.consumer_control_code import ConsumerControlCode
from adafruit_hid.consumer_control import ConsumerControl
import json
import os
import gc
import time
keys = [
"ESCAPE",
"SPACEBAR",
"CAPS_LOCK",
"F1",
"F2",
"F3",
"F4",
"F5",
"F6",
"F7",
"F8",
"F9",
"F10",
"F11",
"F12",
"PRINT_SCREEN",
"SCROLL_LOCK",
"PAUSE",
"APPLICATION",
"POWER",
"F13",
"F14",
"F15",
"F16",
"F17",
"F18",
"F19",
"LEFT_CONTROL",
"LEFT_SHIFT",
"LEFT_ALT",
"LEFT_GUI",
"RIGHT_CONTROL",
"RIGHT_SHIFT",
"RIGHT_ALT",
"RIGHT_GUI",
]
codes = [
"RECORD",
"FAST_FORWARD",
"REWIND",
"SCAN_NEXT_TRACK",
"SCAN_PREVIOUS_TRACK",
"STOP",
"EJECT",
"PLAY_PAUSE",
"MUTE",
"VOLUME_DECREMENT",
"VOLUME_INCREMENT",
]
KEYBOARD = "Keyboard"
CONSUMER = "Consumer Control"
classes = [KEYBOARD, CONSUMER]
CONFIG_NAME = "ptt.json"
def ble_check():
ble_enabled = False
try:
active = config.get_string("ble_enable")
if active.lower() == "true" or active == "1":
ble_enabled = True
except OSError:
pass
if not ble_enabled:
disp.clear()
disp.print("BLE", posy=0, fg=color.BLUE)
disp.print("disabled", posy=0, posx=45, fg=color.RED)
disp.print("Enable BLE", posy=40)
disp.print("in BLE Aapp", posy=60)
disp.update()
while buttons.read() == 0:
time.sleep(0.1)
os.exit()
def ble_hid_check():
ble_hid_enabled = False
try:
active = config.get_string("ble_hid_enable")
if active.lower() == "true" or active == "1":
ble_hid_enabled = True
except OSError:
pass
if not ble_hid_enabled:
disp.clear()
disp.print("HID", posy=0, fg=color.BLUE)
disp.print("disabled", posy=0, posx=45, fg=color.RED)
disp.print("Enable HID", posy=40)
disp.print("in HID App", posy=60)
disp.update()
while buttons.read() == 0:
time.sleep(0.1)
os.exit()
disp = display.open()
ble_check()
ble_hid_check()
connected = False
blocked = False
def save_config():
open(CONFIG_NAME, "w").write(json.dumps(config))
config = {
"key": "LEFT_CONTROL",
"code": "PLAY_PAUSE",
"class": KEYBOARD,
"optical_sensor": True,
"toggle": False,
}
try:
config.update(json.loads(open(CONFIG_NAME, "r").read()))
except Exception as e:
print(e)
print("Writing default config")
save_config()
print(config)
class ProximitySensor:
def __init__(self, callback):
self.callback = callback
self.pressed = False
def open(self):
def callback(datasets):
if len(datasets) > 0 and self.pressed:
pressed = True
for val in datasets:
# Threshold of proximity interrupt: 32 * (2 ** 10)
if val.infrared < 32 * (2 ** 10) / 2:
pressed = False
if not pressed:
self.pressed = pressed
self.callback(self.pressed)
def prox():
self.pressed = True
self.callback(self.pressed)
self.sensor = max86150.MAX86150(
callback=callback, prox_callback=prox, sample_rate=400
)
def close(self):
if self.self is not None:
self.sensor.close()
self.sensor = None
class PTTMenu(simple_menu.Menu):
def on_select(self, name, index):
if config["class"] == KEYBOARD:
config["key"] = name
print(gc.mem_free())
elif config["class"] == CONSUMER:
config["code"] = name
save_config()
self.exit()
class HIDClassMenu(simple_menu.Menu):
def on_select(self, name, index):
config["class"] = name
save_config()
self.exit()
class OpticalSensorMenu(simple_menu.Menu):
def on_select(self, name, index):
if name == "Enable":
config["optical_sensor"] = True
elif name == "Disable":
config["optical_sensor"] = False
save_config()
self.exit()
class ToggleMenu(simple_menu.Menu):
def on_select(self, name, index):
if name == "Enable":
config["toggle"] = True
elif name == "Disable":
config["toggle"] = False
save_config()
self.exit()
class MainMenu(simple_menu.Menu):
def on_select(self, name, index):
print(name)
if name == "PTT Key":
if config["class"] == KEYBOARD:
m = PTTMenu(keys)
try:
m.idx = keys.index(config["key"])
except Exception as e:
print(e)
elif config["class"] == CONSUMER:
m = PTTMenu(codes)
try:
m.idx = codes.index(config["code"])
except Exception as e:
print(e)
elif name == "HID Class":
m = HIDClassMenu(classes)
try:
m.idx = classes.index(config["class"])
except Exception as e:
print(e)
elif name == "Optical Sensor":
if config["optical_sensor"]:
m = OpticalSensorMenu(("Enabled", "Disable", "", ""))
else:
m = OpticalSensorMenu(("Enable", "Disabled", "", ""))
m.idx = 1
elif name == "Key Toggle":
if config["toggle"]:
m = ToggleMenu(("Enabled", "Disable", "", ""))
else:
m = ToggleMenu(("Enable", "Disabled", "", ""))
m.idx = 1
m.run()
self.exit()
def push():
global connected
if config["class"] == KEYBOARD:
key = config["key"]
if hasattr(Keycode, key):
# k.press(192)
try:
if config["toggle"]:
k.send(getattr(Keycode, key))
else:
k.press(getattr(Keycode, key))
except OSError as e:
if e.args[0] == 5:
connected = False
return
else:
raise e
elif config["class"] == CONSUMER:
code = config["code"]
if hasattr(ConsumerControlCode, code):
try:
if config["toggle"]:
c.send(getattr(ConsumerControlCode, code))
c.send(0)
else:
c.send(getattr(ConsumerControlCode, code))
except OSError as e:
if e.args[0] == 5:
connected = False
return
else:
raise e
leds.set_rocket(1, 31)
vibra.vibrate(20)
disp.print("Talk now", posy=30, font=4, fg=color.RED)
disp.update()
disp.backlight(20)
def release():
global connected
key = config["key"]
if config["class"] == KEYBOARD:
if hasattr(Keycode, key):
# k.release(192)
try:
if config["toggle"]:
k.send(getattr(Keycode, key))
else:
k.release(getattr(Keycode, key))
except OSError as e:
if e.args[0] == 5:
connected = False
else:
raise e
elif config["class"] == CONSUMER:
try:
if config["toggle"]:
code = config["code"]
c.send(getattr(ConsumerControlCode, code))
c.send(0)
else:
c.send(0)
except OSError as e:
if e.args[0] == 5:
connected = False
else:
raise e
leds.set_rocket(1, 0)
disp.backlight(0)
def prox_callback(state):
if blocked:
return
if not connected:
return
if "optical_sensor" in config and config["optical_sensor"]:
if state:
push()
else:
release()
sensor = ProximitySensor(prox_callback).open()
disp.clear()
disp.print("PushToTalk", posy=0)
disp.print("via BLE", posy=20, fg=color.BLUE)
disp.print(" Menu ->", posy=40)
disp.print("<- PTT", posy=60, fg=color.RED)
disp.update()
time.sleep(3)
b_old = buttons.read()
while True:
if not connected:
try:
k = Keyboard(ble_hid.devices)
c = ConsumerControl(ble_hid.devices)
connected = True
disp.clear().update()
disp.backlight(0)
except OSError as e:
if e.args[0] == 5:
disp.backlight(20)
disp.clear()
disp.print("Waiting for")
disp.print("BLE Connection", posy=20, fg=color.BLUE)
disp.update()
else:
raise e
else:
b_new = buttons.read()
if not b_old == b_new:
b_old = b_new
if b_new == buttons.BOTTOM_LEFT:
push()
elif b_new == buttons.TOP_RIGHT:
disp.backlight(20)
blocked = True
MainMenu(("PTT Key", "HID Class", "Optical Sensor", "Key Toggle")).run()
blocked = False
disp.clear().update()
disp.backlight(0)
else:
release()
time.sleep(0.05)
{"author": "card10 contributors", "name": "PTT", "description": "Push-To-Talk via BLE", "category": "Hardware", "revision": -1, "source":"preload"}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment