prev/next buttons working
This commit is contained in:
parent
1c406f8b4e
commit
6243480f6e
|
@ -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):
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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();
|
||||
}
|
Loading…
Reference in New Issue