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
outgoing_msg_map = {
led_ring_effect_to_message_id = {
EffectStaticConfig: 0,
EffectAlexaSwipeConfig: 1,
EffectCircularConfig: 2,
@ -37,6 +37,12 @@ outgoing_msg_map = {
EffectSwipeAndChange: 4,
}
mouse_led_effect_to_message_id = {
EffectStaticConfig: 5,
EffectCircularConfig: 6,
EffectRandomTwoColorInterpolationConfig: 7
}
class RfidTokenRead:
def __init__(self, id: bytes):
@ -72,11 +78,33 @@ class TouchButtonRelease:
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 = {
0: RfidTokenRead,
1: RotaryEncoderEvent,
2: TouchButtonPress,
3: TouchButtonRelease,
4: ButtonEvent,
}
@ -92,10 +120,16 @@ class MusicMouseProtocol(asyncio.Protocol):
self.transport = transport
self.in_buff = bytes()
def send_message(self, message):
msg_content = message.as_bytes()
header = struct.pack("<IBH", MAGIC_TOKEN_HOST_TO_FW, outgoing_msg_map[type(message)],
len(msg_content))
def led_ring_effect(self, effect_cfg):
msg_content = effect_cfg.as_bytes()
header = struct.pack("<IBH", MAGIC_TOKEN_HOST_TO_FW,
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)
def data_received(self, data):

View File

@ -3,7 +3,7 @@ import serial_asyncio
from led_cmds import (ColorRGBW, ColorHSV, EffectStaticConfig,
EffectRandomTwoColorInterpolationConfig, EffectAlexaSwipeConfig,
EffectSwipeAndChange)
from host_driver import MusicMouseProtocol, RfidTokenRead, RotaryEncoderEvent
from host_driver import MusicMouseProtocol, RfidTokenRead, RotaryEncoderEvent, ButtonEvent
from player import AudioPlayer
from glob import glob
import os
@ -22,7 +22,7 @@ rfid_token_map = {
}
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()
}
@ -36,16 +36,17 @@ mouse_leds = {
def set_mouse_leds(protocol, position: str, color: ColorRGBW):
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):
eff = EffectAlexaSwipeConfig()
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)
if isinstance(message, RfidTokenRead) and message.id == bytes.fromhex("0000000000"):
if audio_player.is_playing():
@ -53,7 +54,8 @@ def on_firmware_msg(protocol, message):
eff.forward = False
else:
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()
elif isinstance(message, RfidTokenRead) and message.id in rfid_token_map:
eff = EffectSwipeAndChange()
@ -66,7 +68,8 @@ def on_firmware_msg(protocol, message):
eff.swipe.swipe_speed = 180
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)
if figure in playlists:
audio_player.set_playlist(playlists[figure])
@ -77,6 +80,11 @@ def on_firmware_msg(protocol, message):
audio_player.change_volume(2)
elif message.direction == 1:
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()

View File

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

View File

@ -11,6 +11,8 @@
#include "effects/AlexaSwipe.h"
#include "effects/RandomTwoColorInterpolation.h"
#include "AceButton.h"
#include "driver/touch_pad.h"
#include "Messages.h"
@ -67,23 +69,48 @@ void handleRotaryEncoder()
// -------------------------------------------------- Buttons ----------------------------------------
constexpr int BUTTON1_PIN = 25;
constexpr int BUTTON2_PIN = 14;
constexpr int BUTTON_RIGHT_PIN = 25;
constexpr int BUTTON_LEFT_PIN = 14;
constexpr int ROTARY_PRESS_PIN = 13;
constexpr int BUTTON1_LED_PIN = 33;
constexpr int BUTTON2_LED_PIN = 12;
constexpr int BUTTON_RIGHT_LED_PIN = 33;
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()
{
pinMode(BUTTON1_PIN, INPUT_PULLUP);
pinMode(BUTTON2_PIN, INPUT_PULLUP);
pinMode(BUTTON_RIGHT_PIN, INPUT_PULLUP);
pinMode(BUTTON_LEFT_PIN, INPUT_PULLUP);
pinMode(ROTARY_PRESS_PIN, INPUT_PULLUP);
pinMode(BUTTON1_LED_PIN, OUTPUT);
pinMode(BUTTON2_LED_PIN, OUTPUT);
pinMode(BUTTON_RIGHT_LED_PIN, OUTPUT);
pinMode(BUTTON_LEFT_LED_PIN, OUTPUT);
digitalWrite(BUTTON1_LED_PIN, 1);
digitalWrite(BUTTON2_LED_PIN, 1);
buttonLeft.setEventHandler(handleButtonEvent);
buttonRight.setEventHandler(handleButtonEvent);
buttonRotary.setEventHandler(handleButtonEvent);
}
void handleButtons()
{
buttonLeft.check();
buttonRight.check();
buttonRotary.check();
}
// -------------------------------------------------- Led circle ------------------------------------------
@ -113,6 +140,7 @@ void setupMouseLeds()
}
// -------------------------------------------------- Touch Buttons ----------------------------------------
constexpr auto TOUCH_PAD_RIGHT_EAR = TOUCH_PAD_NUM0;
constexpr auto TOUCH_PAD_LEFT_EAR = TOUCH_PAD_NUM9;
constexpr auto TOUCH_PAD_RIGHT_FOOT = TOUCH_PAD_NUM2;
@ -168,11 +196,13 @@ void setup()
setupLedCircle();
setupButtons();
setupTouchButtons();
setupMouseLeds();
}
void loop()
{
handleIncomingMessagesFromHost(&ledTaskCircle);
handleIncomingMessagesFromHost(&ledTaskCircle, &ledTaskMouse);
handleTouchInputs();
handleRotaryEncoder();
handleButtons();
}