prev/next buttons working

This commit is contained in:
Martin Bauer 2021-12-16 22:34:40 +01:00
parent 1c406f8b4e
commit 6243480f6e
4 changed files with 135 additions and 31 deletions

View File

@ -29,7 +29,7 @@ class TouchButton(Enum):
RIGHT_EAR = 3 RIGHT_EAR = 3
outgoing_msg_map = { led_ring_effect_to_message_id = {
EffectStaticConfig: 0, EffectStaticConfig: 0,
EffectAlexaSwipeConfig: 1, EffectAlexaSwipeConfig: 1,
EffectCircularConfig: 2, EffectCircularConfig: 2,
@ -37,6 +37,12 @@ outgoing_msg_map = {
EffectSwipeAndChange: 4, EffectSwipeAndChange: 4,
} }
mouse_led_effect_to_message_id = {
EffectStaticConfig: 5,
EffectCircularConfig: 6,
EffectRandomTwoColorInterpolationConfig: 7
}
class RfidTokenRead: class RfidTokenRead:
def __init__(self, id: bytes): def __init__(self, id: bytes):
@ -72,11 +78,33 @@ class TouchButtonRelease:
return "Released " + repr(self.touch_button) return "Released " + repr(self.touch_button)
class ButtonEvent:
button_name = {1: 'left', 2: 'right', 3: 'rotary'}
event_name = {
0: 'pressed',
1: 'released',
2: 'clicked',
3: 'double_clicked',
4: 'long_pressed',
5: 'repeat_pressed',
6: 'long_released'
}
def __init__(self, msg_content: bytes):
button_nr, event_nr = struct.unpack("<BB", msg_content)
self.button = self.button_name[button_nr]
self.event = self.event_name[event_nr]
def __repr__(self) -> str:
return f"Button {self.button} {self.event}"
incomingMsgMap = { incomingMsgMap = {
0: RfidTokenRead, 0: RfidTokenRead,
1: RotaryEncoderEvent, 1: RotaryEncoderEvent,
2: TouchButtonPress, 2: TouchButtonPress,
3: TouchButtonRelease, 3: TouchButtonRelease,
4: ButtonEvent,
} }
@ -92,10 +120,16 @@ class MusicMouseProtocol(asyncio.Protocol):
self.transport = transport self.transport = transport
self.in_buff = bytes() self.in_buff = bytes()
def send_message(self, message): def led_ring_effect(self, effect_cfg):
msg_content = message.as_bytes() msg_content = effect_cfg.as_bytes()
header = struct.pack("<IBH", MAGIC_TOKEN_HOST_TO_FW, outgoing_msg_map[type(message)], header = struct.pack("<IBH", MAGIC_TOKEN_HOST_TO_FW,
len(msg_content)) led_ring_effect_to_message_id[type(effect_cfg)], len(msg_content))
self.transport.write(header + msg_content)
def mouse_led_effect(self, effect_cfg):
msg_content = effect_cfg.as_bytes()
header = struct.pack("<IBH", MAGIC_TOKEN_HOST_TO_FW,
mouse_led_effect_to_message_id[type(effect_cfg)], len(msg_content))
self.transport.write(header + msg_content) self.transport.write(header + msg_content)
def data_received(self, data): def data_received(self, data):

View File

@ -3,7 +3,7 @@ import serial_asyncio
from led_cmds import (ColorRGBW, ColorHSV, EffectStaticConfig, from led_cmds import (ColorRGBW, ColorHSV, EffectStaticConfig,
EffectRandomTwoColorInterpolationConfig, EffectAlexaSwipeConfig, EffectRandomTwoColorInterpolationConfig, EffectAlexaSwipeConfig,
EffectSwipeAndChange) EffectSwipeAndChange)
from host_driver import MusicMouseProtocol, RfidTokenRead, RotaryEncoderEvent from host_driver import MusicMouseProtocol, RfidTokenRead, RotaryEncoderEvent, ButtonEvent
from player import AudioPlayer from player import AudioPlayer
from glob import glob from glob import glob
import os import os
@ -22,7 +22,7 @@ rfid_token_map = {
} }
playlists = { playlists = {
fig: audio_player.create_playlist(glob(os.path.join(MUSIC_FOLDER, fig, "*.mp3"))) fig: audio_player.create_playlist(sorted(glob(os.path.join(MUSIC_FOLDER, fig, "*.mp3"))))
for fig in rfid_token_map.values() for fig in rfid_token_map.values()
} }
@ -36,16 +36,17 @@ mouse_leds = {
def set_mouse_leds(protocol, position: str, color: ColorRGBW): def set_mouse_leds(protocol, position: str, color: ColorRGBW):
start, end = mouse_leds[position] start, end = mouse_leds[position]
protocol.send_message(EffectStaticConfig(color, start, end)) protocol.led_ring_effect(EffectStaticConfig(color, start, end))
def on_music_end_callback(protocol): def on_music_end_callback(protocol):
eff = EffectAlexaSwipeConfig() eff = EffectAlexaSwipeConfig()
eff.forward = False eff.forward = False
protocol.send_message(eff) protocol.led_ring_effect(eff)
protocol.mouse_led_effect(EffectStaticConfig(ColorRGBW(0, 0, 0, 0)))
def on_firmware_msg(protocol, message): def on_firmware_msg(protocol: MusicMouseProtocol, message):
print("Got message", message) print("Got message", message)
if isinstance(message, RfidTokenRead) and message.id == bytes.fromhex("0000000000"): if isinstance(message, RfidTokenRead) and message.id == bytes.fromhex("0000000000"):
if audio_player.is_playing(): if audio_player.is_playing():
@ -53,7 +54,8 @@ def on_firmware_msg(protocol, message):
eff.forward = False eff.forward = False
else: else:
eff = EffectStaticConfig(ColorRGBW(0, 0, 0, 0)) eff = EffectStaticConfig(ColorRGBW(0, 0, 0, 0))
protocol.send_message(eff) protocol.led_ring_effect(eff)
protocol.mouse_led_effect(EffectStaticConfig(ColorRGBW(0, 0, 0, 0)))
audio_player.pause() audio_player.pause()
elif isinstance(message, RfidTokenRead) and message.id in rfid_token_map: elif isinstance(message, RfidTokenRead) and message.id in rfid_token_map:
eff = EffectSwipeAndChange() eff = EffectSwipeAndChange()
@ -66,7 +68,8 @@ def on_firmware_msg(protocol, message):
eff.swipe.swipe_speed = 180 eff.swipe.swipe_speed = 180
eff.swipe.bell_curve_width_in_leds = 6 eff.swipe.bell_curve_width_in_leds = 6
protocol.send_message(eff) protocol.led_ring_effect(eff)
protocol.mouse_led_effect(EffectStaticConfig(ColorRGBW(0, 0, 1, 0)))
print(figure) print(figure)
if figure in playlists: if figure in playlists:
audio_player.set_playlist(playlists[figure]) audio_player.set_playlist(playlists[figure])
@ -77,6 +80,11 @@ def on_firmware_msg(protocol, message):
audio_player.change_volume(2) audio_player.change_volume(2)
elif message.direction == 1: elif message.direction == 1:
audio_player.change_volume(-2) audio_player.change_volume(-2)
elif isinstance(message, ButtonEvent):
if message.button == "left" and message.event == "pressed":
audio_player.previous()
elif message.button == "right" and message.event == "pressed":
audio_player.next()
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()

View File

@ -21,6 +21,7 @@ enum class MessageFwToHost : uint8_t
ROTARY_ENCODER = 1, ROTARY_ENCODER = 1,
TOUCH_BUTTON_PRESS = 2, TOUCH_BUTTON_PRESS = 2,
TOUCH_BUTTON_RELEASE = 3, TOUCH_BUTTON_RELEASE = 3,
BUTTON_EVENT = 4,
}; };
enum class TouchButton : uint8_t enum class TouchButton : uint8_t
@ -53,6 +54,12 @@ struct MsgTouchButtonRelease
TouchButton button; TouchButton button;
}; };
struct MsgButtonEvent
{
uint8_t buttonNr;
uint8_t eventType;
};
#pragma pack(pop) #pragma pack(pop)
template <> template <>
@ -79,6 +86,12 @@ struct ClassToMessageType<MsgTouchButtonRelease>
static constexpr auto msgType = MessageFwToHost::TOUCH_BUTTON_RELEASE; static constexpr auto msgType = MessageFwToHost::TOUCH_BUTTON_RELEASE;
}; };
template <>
struct ClassToMessageType<MsgButtonEvent>
{
static constexpr auto msgType = MessageFwToHost::BUTTON_EVENT;
};
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
enum class MessageHostToFw : uint8_t enum class MessageHostToFw : uint8_t
@ -87,7 +100,11 @@ enum class MessageHostToFw : uint8_t
LED_WHEEL_EFFECT_ALEXA_SWIPE = 1, LED_WHEEL_EFFECT_ALEXA_SWIPE = 1,
LED_WHEEL_EFFECT_CIRCULAR = 2, LED_WHEEL_EFFECT_CIRCULAR = 2,
LED_WHEEL_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION = 3, LED_WHEEL_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION = 3,
LED_WHEEL_EFFECT_SWIPE_AND_CHANGE = 4 LED_WHEEL_EFFECT_SWIPE_AND_CHANGE = 4,
MOUSE_LED_EFFECT_STATIC = 5,
MOUSE_LED_EFFECT_CIRCULAR = 6,
MOUSE_LED_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION = 7,
}; };
template <> template <>
@ -134,8 +151,8 @@ void sendMessageToHost(const TMessage &msg)
Serial.write((uint8_t *)&msg, sizeof(msg)); Serial.write((uint8_t *)&msg, sizeof(msg));
} }
template <typename LedTask> template <typename LedTask1, typename LedTask2>
inline void handleIncomingMessagesFromHost(LedTask *ledTask) inline void handleIncomingMessagesFromHost(LedTask1 *ledTaskCircle, LedTask2 *ledTaskMouse)
{ {
if (Serial.available() < sizeof(MAGIC_TOKEN_FW_TO_HOST) + sizeof(MessageHostToFw) + sizeof(uint16_t)) if (Serial.available() < sizeof(MAGIC_TOKEN_FW_TO_HOST) + sizeof(MessageHostToFw) + sizeof(uint16_t))
return; return;
@ -162,27 +179,42 @@ inline void handleIncomingMessagesFromHost(LedTask *ledTask)
if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_STATIC) if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_STATIC)
{ {
auto cfg = reinterpret_cast<EffectStaticConfig *>(msgBuffer); auto cfg = reinterpret_cast<EffectStaticConfig *>(msgBuffer);
ledTask->startEffect(*cfg); ledTaskCircle->startEffect(*cfg);
} }
else if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_ALEXA_SWIPE) else if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_ALEXA_SWIPE)
{ {
auto cfg = reinterpret_cast<EffectAlexaSwipeConfig *>(msgBuffer); auto cfg = reinterpret_cast<EffectAlexaSwipeConfig *>(msgBuffer);
ledTask->startEffect(*cfg); ledTaskCircle->startEffect(*cfg);
} }
else if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_CIRCULAR) else if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_CIRCULAR)
{ {
auto cfg = reinterpret_cast<EffectCircularConfig *>(msgBuffer); auto cfg = reinterpret_cast<EffectCircularConfig *>(msgBuffer);
ledTask->startEffect(*cfg); ledTaskCircle->startEffect(*cfg);
} }
else if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION) else if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION)
{ {
auto cfg = reinterpret_cast<EffectRandomTwoColorInterpolationConfig *>(msgBuffer); auto cfg = reinterpret_cast<EffectRandomTwoColorInterpolationConfig *>(msgBuffer);
ledTask->startEffect(*cfg); ledTaskCircle->startEffect(*cfg);
} }
else if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_SWIPE_AND_CHANGE) else if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_SWIPE_AND_CHANGE)
{ {
auto cfg = reinterpret_cast<EffectSwipeAndChangeConfig *>(msgBuffer); auto cfg = reinterpret_cast<EffectSwipeAndChangeConfig *>(msgBuffer);
ledTask->startEffect(*cfg); ledTaskCircle->startEffect(*cfg);
}
else if (msgType == MessageHostToFw::MOUSE_LED_EFFECT_STATIC)
{
auto cfg = reinterpret_cast<EffectStaticConfig *>(msgBuffer);
ledTaskMouse->startEffect(*cfg);
}
else if (msgType == MessageHostToFw::MOUSE_LED_EFFECT_CIRCULAR)
{
auto cfg = reinterpret_cast<EffectCircularConfig *>(msgBuffer);
ledTaskMouse->startEffect(*cfg);
}
else if (msgType == MessageHostToFw::MOUSE_LED_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION)
{
auto cfg = reinterpret_cast<EffectRandomTwoColorInterpolationConfig *>(msgBuffer);
ledTaskMouse->startEffect(*cfg);
} }
else else
Serial.println("Unknown message type"); Serial.println("Unknown message type");

View File

@ -11,6 +11,8 @@
#include "effects/AlexaSwipe.h" #include "effects/AlexaSwipe.h"
#include "effects/RandomTwoColorInterpolation.h" #include "effects/RandomTwoColorInterpolation.h"
#include "AceButton.h"
#include "driver/touch_pad.h" #include "driver/touch_pad.h"
#include "Messages.h" #include "Messages.h"
@ -67,23 +69,48 @@ void handleRotaryEncoder()
// -------------------------------------------------- Buttons ---------------------------------------- // -------------------------------------------------- Buttons ----------------------------------------
constexpr int BUTTON1_PIN = 25; constexpr int BUTTON_RIGHT_PIN = 25;
constexpr int BUTTON2_PIN = 14; constexpr int BUTTON_LEFT_PIN = 14;
constexpr int ROTARY_PRESS_PIN = 13; constexpr int ROTARY_PRESS_PIN = 13;
constexpr int BUTTON1_LED_PIN = 33; constexpr int BUTTON_RIGHT_LED_PIN = 33;
constexpr int BUTTON2_LED_PIN = 12; constexpr int BUTTON_LEFT_LED_PIN = 12;
using ace_button::AceButton;
AceButton buttonLeft(BUTTON_LEFT_PIN);
AceButton buttonRight(BUTTON_RIGHT_PIN);
AceButton buttonRotary(ROTARY_PRESS_PIN);
void handleButtonEvent(AceButton *button, uint8_t eventType, uint8_t /*buttonState*/)
{
uint8_t buttonNr = 0;
if (button == &buttonLeft)
buttonNr = 1;
else if (button == &buttonRight)
buttonNr = 2;
else if (button == &buttonRotary)
buttonNr = 3;
sendMessageToHost(MsgButtonEvent{buttonNr, eventType});
}
void setupButtons() void setupButtons()
{ {
pinMode(BUTTON1_PIN, INPUT_PULLUP); pinMode(BUTTON_RIGHT_PIN, INPUT_PULLUP);
pinMode(BUTTON2_PIN, INPUT_PULLUP); pinMode(BUTTON_LEFT_PIN, INPUT_PULLUP);
pinMode(ROTARY_PRESS_PIN, INPUT_PULLUP); pinMode(ROTARY_PRESS_PIN, INPUT_PULLUP);
pinMode(BUTTON1_LED_PIN, OUTPUT); pinMode(BUTTON_RIGHT_LED_PIN, OUTPUT);
pinMode(BUTTON2_LED_PIN, OUTPUT); pinMode(BUTTON_LEFT_LED_PIN, OUTPUT);
digitalWrite(BUTTON1_LED_PIN, 1); buttonLeft.setEventHandler(handleButtonEvent);
digitalWrite(BUTTON2_LED_PIN, 1); buttonRight.setEventHandler(handleButtonEvent);
buttonRotary.setEventHandler(handleButtonEvent);
}
void handleButtons()
{
buttonLeft.check();
buttonRight.check();
buttonRotary.check();
} }
// -------------------------------------------------- Led circle ------------------------------------------ // -------------------------------------------------- Led circle ------------------------------------------
@ -113,6 +140,7 @@ void setupMouseLeds()
} }
// -------------------------------------------------- Touch Buttons ---------------------------------------- // -------------------------------------------------- Touch Buttons ----------------------------------------
constexpr auto TOUCH_PAD_RIGHT_EAR = TOUCH_PAD_NUM0; constexpr auto TOUCH_PAD_RIGHT_EAR = TOUCH_PAD_NUM0;
constexpr auto TOUCH_PAD_LEFT_EAR = TOUCH_PAD_NUM9; constexpr auto TOUCH_PAD_LEFT_EAR = TOUCH_PAD_NUM9;
constexpr auto TOUCH_PAD_RIGHT_FOOT = TOUCH_PAD_NUM2; constexpr auto TOUCH_PAD_RIGHT_FOOT = TOUCH_PAD_NUM2;
@ -168,11 +196,13 @@ void setup()
setupLedCircle(); setupLedCircle();
setupButtons(); setupButtons();
setupTouchButtons(); setupTouchButtons();
setupMouseLeds();
} }
void loop() void loop()
{ {
handleIncomingMessagesFromHost(&ledTaskCircle); handleIncomingMessagesFromHost(&ledTaskCircle, &ledTaskMouse);
handleTouchInputs(); handleTouchInputs();
handleRotaryEncoder(); handleRotaryEncoder();
handleButtons();
} }