Firmware cleanup
This commit is contained in:
parent
11db5763eb
commit
4fbd7f0f1b
|
@ -1,7 +1,5 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
import serial_asyncio
|
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from dataclasses import dataclass
|
|
||||||
import struct
|
import struct
|
||||||
|
|
||||||
from led_cmds import *
|
from led_cmds import *
|
||||||
|
@ -23,10 +21,12 @@ class MessageHostToFw(Enum):
|
||||||
LED_WHEEL_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION = 3
|
LED_WHEEL_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION = 3
|
||||||
|
|
||||||
|
|
||||||
outgoingMsgMap = {
|
outgoing_msg_map = {
|
||||||
EffectStaticConfig: 0,
|
EffectStaticConfig: 0,
|
||||||
EffectAlexaSwipeConfig: 1,
|
EffectAlexaSwipeConfig: 1,
|
||||||
EffectCircularConfig: 2,
|
EffectCircularConfig: 2,
|
||||||
|
EffectRandomTwoColorInterpolationConfig: 3,
|
||||||
|
EffectSwipeAndChange: 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,17 +42,21 @@ incomingMsgMap = {0: RfidTokenRead}
|
||||||
|
|
||||||
|
|
||||||
class MusicMouseProtocol(asyncio.Protocol):
|
class MusicMouseProtocol(asyncio.Protocol):
|
||||||
|
def __init__(self):
|
||||||
|
super()
|
||||||
|
self._msg_callback = None
|
||||||
|
|
||||||
|
def register_message_callback(self, cb):
|
||||||
|
self._msg_callback = cb
|
||||||
|
|
||||||
def connection_made(self, transport):
|
def connection_made(self, transport):
|
||||||
self.transport = transport
|
self.transport = transport
|
||||||
self.in_buff = bytes()
|
self.in_buff = bytes()
|
||||||
|
|
||||||
def send_message(self, message):
|
def send_message(self, message):
|
||||||
msg_content = message.as_bytes()
|
msg_content = message.as_bytes()
|
||||||
print("Sending message content", len(msg_content))
|
header = struct.pack("<IBH", MAGIC_TOKEN_HOST_TO_FW, outgoing_msg_map[type(message)],
|
||||||
header = struct.pack("<IBH", MAGIC_TOKEN_HOST_TO_FW, outgoingMsgMap[type(message)],
|
|
||||||
len(msg_content))
|
len(msg_content))
|
||||||
|
|
||||||
print(repr(header + msg_content))
|
|
||||||
self.transport.write(header + msg_content)
|
self.transport.write(header + msg_content)
|
||||||
|
|
||||||
def data_received(self, data):
|
def data_received(self, data):
|
||||||
|
@ -89,25 +93,5 @@ class MusicMouseProtocol(asyncio.Protocol):
|
||||||
|
|
||||||
def _on_msg_receive(self, msg_type, msg_payload):
|
def _on_msg_receive(self, msg_type, msg_payload):
|
||||||
parsed_msg = incomingMsgMap[msg_type](msg_payload)
|
parsed_msg = incomingMsgMap[msg_type](msg_payload)
|
||||||
print("MSG:", parsed_msg)
|
if self._msg_callback is not None:
|
||||||
|
self._msg_callback(self, parsed_msg)
|
||||||
|
|
||||||
async def main(protocol: MusicMouseProtocol):
|
|
||||||
for i in range(10):
|
|
||||||
protocol.send_message(EffectStaticConfig(ColorRGBW(1, 0, 0, 0)))
|
|
||||||
await asyncio.sleep(2)
|
|
||||||
protocol.send_message(EffectStaticConfig(ColorRGBW(0, 1, 0, 0)))
|
|
||||||
await asyncio.sleep(2)
|
|
||||||
protocol.send_message(EffectStaticConfig(ColorRGBW(0, 1, 1, 0)))
|
|
||||||
await asyncio.sleep(2)
|
|
||||||
|
|
||||||
|
|
||||||
loop = asyncio.get_event_loop()
|
|
||||||
coro = serial_asyncio.create_serial_connection(loop,
|
|
||||||
MusicMouseProtocol,
|
|
||||||
'/dev/ttyUSB0',
|
|
||||||
baudrate=115200)
|
|
||||||
transport, protocol = loop.run_until_complete(coro)
|
|
||||||
#loop.create_task(main(protocol))
|
|
||||||
loop.run_forever()
|
|
||||||
loop.close()
|
|
||||||
|
|
|
@ -9,8 +9,13 @@ class ColorRGBW:
|
||||||
b: float
|
b: float
|
||||||
w: float
|
w: float
|
||||||
|
|
||||||
|
def repr(self):
|
||||||
|
return f"ColorRGBW({self.r}, {self.g}, {self.b}, {self.w}"
|
||||||
|
|
||||||
def as_bytes(self) -> bytes:
|
def as_bytes(self) -> bytes:
|
||||||
return struct.pack("<BBBB", self.r * 255, self.g * 255, self.b * 255, self.w * 255)
|
assert self.is_valid(), "Trying to send invalid " + repr(self)
|
||||||
|
return struct.pack("<BBBB", int(self.r * 255), int(self.g * 255), int(self.b * 255),
|
||||||
|
int(self.w * 255))
|
||||||
|
|
||||||
def is_valid(self):
|
def is_valid(self):
|
||||||
vals = (self.r, self.g, self.b, self.w)
|
vals = (self.r, self.g, self.b, self.w)
|
||||||
|
@ -46,14 +51,14 @@ class EffectStaticConfig:
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class EffectAlexaSwipeConfig:
|
class EffectAlexaSwipeConfig:
|
||||||
primary_color_width: float # in degrees
|
primary_color_width: float = 20 # in degrees
|
||||||
transition_width: float # in degrees
|
transition_width: float = 30 # in degrees
|
||||||
swipe_speed: float # in degrees per second
|
swipe_speed: float = 3 * 360 # in degrees per second
|
||||||
bell_curve_width_in_leds: float
|
bell_curve_width_in_leds: float = 3
|
||||||
start_position: float # in degrees
|
start_position: float = 180 # in degrees
|
||||||
forward: bool
|
forward: bool = True
|
||||||
primary_color: ColorRGBW
|
primary_color: ColorRGBW = ColorRGBW(0, 0, 1, 0)
|
||||||
secondary_color: ColorRGBW
|
secondary_color: ColorRGBW = ColorRGBW(0, 200 / 255, 1, 0)
|
||||||
|
|
||||||
def as_bytes(self) -> bytes:
|
def as_bytes(self) -> bytes:
|
||||||
return struct.pack(
|
return struct.pack(
|
||||||
|
@ -64,25 +69,34 @@ class EffectAlexaSwipeConfig:
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class EffectRandomTwoColorInterpolationConfig:
|
class EffectRandomTwoColorInterpolationConfig:
|
||||||
cycle_durations_ms: int
|
cycle_durations_ms: int = 6000
|
||||||
start_with_existing: bool
|
start_with_existing: bool = True
|
||||||
num_segments: int
|
num_segments: int = 3
|
||||||
hue1_random: bool
|
hue1_random: bool = False
|
||||||
hue2_random: bool
|
hue2_random: bool = False
|
||||||
color1: ColorHSV
|
color1: ColorHSV = ColorHSV(240, 1, 1)
|
||||||
color2: ColorHSV
|
color2: ColorHSV = ColorHSV(192, 1, 1)
|
||||||
|
|
||||||
def as_bytes(self) -> bytes:
|
def as_bytes(self) -> bytes:
|
||||||
return struct.pack("<i?i??", self.cycle_durations_ms, self.start_with_existing,
|
return struct.pack("<i?i??", self.cycle_durations_ms, self.start_with_existing,
|
||||||
self.num_segments, self.hue1_random,
|
self.num_segments, self.hue1_random,
|
||||||
self.hue2_random) + self.color1.as_bytes(), +self.color2.as_bytes()
|
self.hue2_random) + self.color1.as_bytes() + self.color2.as_bytes()
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class EffectCircularConfig:
|
class EffectCircularConfig:
|
||||||
speed: float # in degrees per second
|
speed: float = 360 # in degrees per second
|
||||||
width: float # in degrees
|
width: float = 180 # in degrees
|
||||||
color: ColorRGBW
|
color: ColorRGBW = ColorRGBW(0, 0, 1, 0)
|
||||||
|
|
||||||
def as_bytes(self) -> bytes:
|
def as_bytes(self) -> bytes:
|
||||||
return struct.pack("<ff", self.speed, self.width) + self.color.as_bytes()
|
return struct.pack("<ff", self.speed, self.width) + self.color.as_bytes()
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class EffectSwipeAndChange:
|
||||||
|
swipe: EffectAlexaSwipeConfig = EffectAlexaSwipeConfig()
|
||||||
|
change: EffectRandomTwoColorInterpolationConfig = EffectRandomTwoColorInterpolationConfig()
|
||||||
|
|
||||||
|
def as_bytes(self) -> bytes:
|
||||||
|
return self.swipe.as_bytes() + self.change.as_bytes()
|
|
@ -0,0 +1,47 @@
|
||||||
|
import asyncio
|
||||||
|
import serial_asyncio
|
||||||
|
from led_cmds import (ColorRGBW, ColorHSV, EffectStaticConfig,
|
||||||
|
EffectRandomTwoColorInterpolationConfig, EffectAlexaSwipeConfig,
|
||||||
|
EffectSwipeAndChange)
|
||||||
|
from host_driver import MusicMouseProtocol, RfidTokenRead
|
||||||
|
|
||||||
|
rfid_token_map = {
|
||||||
|
bytes.fromhex("0000000000"): "None",
|
||||||
|
bytes.fromhex("88041174e9"): "Elephant",
|
||||||
|
bytes.fromhex("8804ce7230"): "Fox",
|
||||||
|
bytes.fromhex("88040d71f0"): "Owl",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def on_firmware_msg(protocol, message):
|
||||||
|
print("Got message", message)
|
||||||
|
if isinstance(message, RfidTokenRead) and message.id in rfid_token_map:
|
||||||
|
if rfid_token_map[message.id] == "Elephant":
|
||||||
|
print("Elephant")
|
||||||
|
eff = EffectStaticConfig(ColorRGBW(0, 0, 1, 0))
|
||||||
|
protocol.send_message(eff)
|
||||||
|
elif rfid_token_map[message.id] == "Fox":
|
||||||
|
print("Fox")
|
||||||
|
eff = EffectRandomTwoColorInterpolationConfig()
|
||||||
|
protocol.send_message(eff)
|
||||||
|
elif rfid_token_map[message.id] == "Owl":
|
||||||
|
print("Owl")
|
||||||
|
eff = EffectSwipeAndChange()
|
||||||
|
eff.swipe.primary_color = ColorRGBW(1, 1, 0, 0)
|
||||||
|
protocol.send_message(eff)
|
||||||
|
elif rfid_token_map[message.id] == "None":
|
||||||
|
eff = EffectAlexaSwipeConfig()
|
||||||
|
eff.forward = False
|
||||||
|
print("Nothing")
|
||||||
|
protocol.send_message(eff)
|
||||||
|
|
||||||
|
|
||||||
|
loop = asyncio.get_event_loop()
|
||||||
|
coro = serial_asyncio.create_serial_connection(loop,
|
||||||
|
MusicMouseProtocol,
|
||||||
|
'/dev/ttyUSB0',
|
||||||
|
baudrate=115200)
|
||||||
|
transport, protocol = loop.run_until_complete(coro)
|
||||||
|
protocol.register_message_callback(on_firmware_msg)
|
||||||
|
loop.run_forever()
|
||||||
|
loop.close()
|
|
@ -6,6 +6,7 @@
|
||||||
#include "helpers/ColorConversions.h"
|
#include "helpers/ColorConversions.h"
|
||||||
#include "helpers/BellCurve.h"
|
#include "helpers/BellCurve.h"
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
struct EffectAlexaSwipeConfig
|
struct EffectAlexaSwipeConfig
|
||||||
{
|
{
|
||||||
float primaryColorWidth; // in degrees
|
float primaryColorWidth; // in degrees
|
||||||
|
@ -17,6 +18,7 @@ struct EffectAlexaSwipeConfig
|
||||||
ColorRGBW primaryColor;
|
ColorRGBW primaryColor;
|
||||||
ColorRGBW secondaryColor;
|
ColorRGBW secondaryColor;
|
||||||
};
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
template <typename TLedStrip>
|
template <typename TLedStrip>
|
||||||
class EffectAlexaSwipe
|
class EffectAlexaSwipe
|
||||||
|
@ -38,7 +40,8 @@ public:
|
||||||
speed_(cfg.swipeSpeed / 360 / 1000 * NUM_LEDS * DELAY_MS),
|
speed_(cfg.swipeSpeed / 360 / 1000 * NUM_LEDS * DELAY_MS),
|
||||||
startPosition_(cfg.startPosition / 360.0f * NUM_LEDS),
|
startPosition_(cfg.startPosition / 360.0f * NUM_LEDS),
|
||||||
primaryColor_(rgb2hsv(cfg.primaryColor)),
|
primaryColor_(rgb2hsv(cfg.primaryColor)),
|
||||||
secondaryColor_(rgb2hsv(cfg.secondaryColor))
|
secondaryColor_(rgb2hsv(cfg.secondaryColor)),
|
||||||
|
finished_(false)
|
||||||
{
|
{
|
||||||
if (cfg.forward)
|
if (cfg.forward)
|
||||||
{
|
{
|
||||||
|
@ -52,6 +55,8 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool finished() { return finished_; }
|
||||||
|
|
||||||
int operator()()
|
int operator()()
|
||||||
{
|
{
|
||||||
clear(ledStrip_);
|
clear(ledStrip_);
|
||||||
|
@ -72,8 +77,13 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
currentPosition_ += direction_ * speed_;
|
currentPosition_ += direction_ * speed_;
|
||||||
currentPosition_ = std::min(currentPosition_, float(NUM_LEDS) / 2.0f + bellCurveWidth_ / 2);
|
const auto maxPosition = float(NUM_LEDS) / 2.0f + bellCurveWidth_ / 2;
|
||||||
currentPosition_ = std::max(currentPosition_, 0.0f);
|
const auto minPosition = 0.0f;
|
||||||
|
currentPosition_ = std::min(currentPosition_, maxPosition);
|
||||||
|
currentPosition_ = std::max(currentPosition_, minPosition);
|
||||||
|
if (currentPosition_ <= minPosition || currentPosition_ >= maxPosition)
|
||||||
|
finished_ = true;
|
||||||
|
|
||||||
return DELAY_MS;
|
return DELAY_MS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,6 +129,8 @@ private:
|
||||||
const ColorHSV primaryColor_;
|
const ColorHSV primaryColor_;
|
||||||
const ColorHSV secondaryColor_;
|
const ColorHSV secondaryColor_;
|
||||||
float direction_;
|
float direction_;
|
||||||
|
|
||||||
|
bool finished_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Traits
|
// Traits
|
||||||
|
|
|
@ -4,12 +4,14 @@
|
||||||
#include "helpers/ColorRGBW.h"
|
#include "helpers/ColorRGBW.h"
|
||||||
#include "helpers/BellCurve.h"
|
#include "helpers/BellCurve.h"
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
struct EffectCircularConfig
|
struct EffectCircularConfig
|
||||||
{
|
{
|
||||||
float speed; // in degrees per second
|
float speed; // in degrees per second
|
||||||
float width; // width in degrees
|
float width; // width in degrees
|
||||||
ColorRGBW color;
|
ColorRGBW color;
|
||||||
};
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
template <typename TLedStrip>
|
template <typename TLedStrip>
|
||||||
class EffectCircular
|
class EffectCircular
|
||||||
|
|
|
@ -5,7 +5,8 @@ enum class EffectId
|
||||||
STATIC,
|
STATIC,
|
||||||
CIRCULAR,
|
CIRCULAR,
|
||||||
ALEXA_SWIPE,
|
ALEXA_SWIPE,
|
||||||
RANDOM_TWO_COLOR_INTERPOLATION
|
RANDOM_TWO_COLOR_INTERPOLATION,
|
||||||
|
SWIPE_AND_CHANGE, // combination of ALEXA_SWIPE and RANDOM_TWO_COLOR_INTERPOLATION
|
||||||
};
|
};
|
||||||
|
|
||||||
template <EffectId id>
|
template <EffectId id>
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "helpers/ColorHSV.h"
|
#include "helpers/ColorHSV.h"
|
||||||
#include "helpers/ColorConversions.h"
|
#include "helpers/ColorConversions.h"
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
struct EffectRandomTwoColorInterpolationConfig
|
struct EffectRandomTwoColorInterpolationConfig
|
||||||
{
|
{
|
||||||
int32_t cycleDurationMs;
|
int32_t cycleDurationMs;
|
||||||
|
@ -18,6 +19,7 @@ struct EffectRandomTwoColorInterpolationConfig
|
||||||
ColorHSV color1;
|
ColorHSV color1;
|
||||||
ColorHSV color2;
|
ColorHSV color2;
|
||||||
};
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
template <typename TLedStrip>
|
template <typename TLedStrip>
|
||||||
class EffectRandomTwoColorInterpolation
|
class EffectRandomTwoColorInterpolation
|
||||||
|
@ -43,6 +45,13 @@ public:
|
||||||
randomizeColors(nextColors_);
|
randomizeColors(nextColors_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void begin()
|
||||||
|
{
|
||||||
|
if (config_.startWithExisting)
|
||||||
|
for (int i = 0; i < NUM_LEDS; ++i)
|
||||||
|
currentColors_[i] = rgb2hsv(getLedRGBW(ledStrip_, i));
|
||||||
|
}
|
||||||
|
|
||||||
int operator()()
|
int operator()()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < NUM_LEDS; ++i)
|
for (int i = 0; i < NUM_LEDS; ++i)
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "effects/Common.h"
|
||||||
|
#include "effects/AlexaSwipe.h"
|
||||||
|
#include "effects/RandomTwoColorInterpolation.h"
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
struct EffectSwipeAndChangeConfig
|
||||||
|
{
|
||||||
|
EffectAlexaSwipeConfig swipeCfg;
|
||||||
|
EffectRandomTwoColorInterpolationConfig changeCfg;
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
template <typename TLedStrip>
|
||||||
|
class EffectSwipeAndChange
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EffectSwipeAndChange(const EffectSwipeAndChangeConfig &cfg, TLedStrip &ledStrip)
|
||||||
|
: effect1_(cfg.swipeCfg, ledStrip),
|
||||||
|
effect2_(cfg.changeCfg, ledStrip),
|
||||||
|
effectRunning_(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int operator()()
|
||||||
|
{
|
||||||
|
if (!effect1_.finished())
|
||||||
|
{
|
||||||
|
return effect1_();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (effectRunning_ == 0)
|
||||||
|
effect2_.begin();
|
||||||
|
effectRunning_ = 1;
|
||||||
|
return effect2_();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
EffectAlexaSwipe<TLedStrip> effect1_;
|
||||||
|
EffectRandomTwoColorInterpolation<TLedStrip> effect2_;
|
||||||
|
int effectRunning_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Traits
|
||||||
|
template <>
|
||||||
|
struct EffectIdToConfig<EffectId::SWIPE_AND_CHANGE>
|
||||||
|
{
|
||||||
|
using type = EffectSwipeAndChangeConfig;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct EffectConfigToId<EffectSwipeAndChangeConfig>
|
||||||
|
{
|
||||||
|
static constexpr auto id = EffectId::SWIPE_AND_CHANGE;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename TLedStrip>
|
||||||
|
struct EffectIdToClass<EffectId::SWIPE_AND_CHANGE, TLedStrip>
|
||||||
|
{
|
||||||
|
using type = EffectSwipeAndChange<TLedStrip>;
|
||||||
|
};
|
|
@ -39,7 +39,7 @@ inline ColorHSV rgb2hsv(const ColorRGBW &in)
|
||||||
out.h = 0.0f; //NAN; // its now undefined
|
out.h = 0.0f; //NAN; // its now undefined
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
if (r >= max) // > is bogus, just keeps compilor happy
|
if (r >= max) // > is bogus, just keeps compiler happy
|
||||||
out.h = (g - b) / delta; // between yellow & magenta
|
out.h = (g - b) / delta; // between yellow & magenta
|
||||||
else if (g >= max)
|
else if (g >= max)
|
||||||
out.h = 2.0f + (b - r) / delta; // between cyan & yellow
|
out.h = 2.0f + (b - r) / delta; // between cyan & yellow
|
||||||
|
|
|
@ -2,12 +2,11 @@
|
||||||
#include "effects/Static.h"
|
#include "effects/Static.h"
|
||||||
#include "effects/AlexaSwipe.h"
|
#include "effects/AlexaSwipe.h"
|
||||||
#include "effects/RandomTwoColorInterpolation.h"
|
#include "effects/RandomTwoColorInterpolation.h"
|
||||||
|
#include "effects/SwipeAndChange.h"
|
||||||
|
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
|
||||||
|
|
||||||
constexpr uint32_t MAGIC_TOKEN_HOST_TO_FW = 0x1d6379e3;
|
constexpr uint32_t MAGIC_TOKEN_HOST_TO_FW = 0x1d6379e3;
|
||||||
constexpr uint32_t MAGIC_TOKEN_FW_TO_HOST = 0x10c65631;
|
constexpr uint32_t MAGIC_TOKEN_FW_TO_HOST = 0x10c65631;
|
||||||
|
|
||||||
|
@ -41,7 +40,8 @@ enum class MessageHostToFw : uint8_t
|
||||||
LED_WHEEL_EFFECT_STATIC = 0,
|
LED_WHEEL_EFFECT_STATIC = 0,
|
||||||
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
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
@ -68,7 +68,11 @@ struct ClassToMessageType<EffectRandomTwoColorInterpolationConfig>
|
||||||
static constexpr auto msgType = MessageHostToFw::LED_WHEEL_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION;
|
static constexpr auto msgType = MessageHostToFw::LED_WHEEL_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION;
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack(pop)
|
template <>
|
||||||
|
struct ClassToMessageType<EffectSwipeAndChangeConfig>
|
||||||
|
{
|
||||||
|
static constexpr auto msgType = MessageHostToFw::LED_WHEEL_EFFECT_SWIPE_AND_CHANGE;
|
||||||
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -111,13 +115,11 @@ inline void handleIncomingMessagesFromHost(LedTask *ledTask)
|
||||||
Serial.readBytes(msgBuffer, msgSize);
|
Serial.readBytes(msgBuffer, msgSize);
|
||||||
if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_STATIC)
|
if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_STATIC)
|
||||||
{
|
{
|
||||||
Serial.println("Static color");
|
|
||||||
auto cfg = reinterpret_cast<EffectStaticConfig *>(msgBuffer);
|
auto cfg = reinterpret_cast<EffectStaticConfig *>(msgBuffer);
|
||||||
ledTask->startEffect(*cfg);
|
ledTask->startEffect(*cfg);
|
||||||
}
|
}
|
||||||
else if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_ALEXA_SWIPE)
|
else if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_ALEXA_SWIPE)
|
||||||
{
|
{
|
||||||
Serial.println("Alexa swipe");
|
|
||||||
auto cfg = reinterpret_cast<EffectAlexaSwipeConfig *>(msgBuffer);
|
auto cfg = reinterpret_cast<EffectAlexaSwipeConfig *>(msgBuffer);
|
||||||
ledTask->startEffect(*cfg);
|
ledTask->startEffect(*cfg);
|
||||||
}
|
}
|
||||||
|
@ -131,6 +133,11 @@ inline void handleIncomingMessagesFromHost(LedTask *ledTask)
|
||||||
auto cfg = reinterpret_cast<EffectRandomTwoColorInterpolationConfig *>(msgBuffer);
|
auto cfg = reinterpret_cast<EffectRandomTwoColorInterpolationConfig *>(msgBuffer);
|
||||||
ledTask->startEffect(*cfg);
|
ledTask->startEffect(*cfg);
|
||||||
}
|
}
|
||||||
|
else if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_SWIPE_AND_CHANGE)
|
||||||
|
{
|
||||||
|
auto cfg = reinterpret_cast<EffectSwipeAndChangeConfig *>(msgBuffer);
|
||||||
|
ledTask->startEffect(*cfg);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
Serial.println("Unknown message type");
|
Serial.println("Unknown message type");
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,10 +75,11 @@ void _led_task_func(void *params)
|
||||||
|
|
||||||
TLedStrip &ledStrip = *(task->ledStrip_);
|
TLedStrip &ledStrip = *(task->ledStrip_);
|
||||||
// clang-format off
|
// clang-format off
|
||||||
if (dispatchEffectId<EffectId::CIRCULAR >(id, effectFunction, ledStrip, msgBuffer, effectStorage)) { Serial.println("Parsed circular");}
|
if (dispatchEffectId<EffectId::CIRCULAR >(id, effectFunction, ledStrip, msgBuffer, effectStorage)) {}
|
||||||
else if (dispatchEffectId<EffectId::STATIC >(id, effectFunction, ledStrip, msgBuffer, effectStorage)) { Serial.println("Parsed static");}
|
else if (dispatchEffectId<EffectId::STATIC >(id, effectFunction, ledStrip, msgBuffer, effectStorage)) {}
|
||||||
else if (dispatchEffectId<EffectId::ALEXA_SWIPE >(id, effectFunction, ledStrip, msgBuffer, effectStorage)) { Serial.println("Alexa swipe");}
|
else if (dispatchEffectId<EffectId::ALEXA_SWIPE >(id, effectFunction, ledStrip, msgBuffer, effectStorage)) {}
|
||||||
else if (dispatchEffectId<EffectId::RANDOM_TWO_COLOR_INTERPOLATION>(id, effectFunction, ledStrip, msgBuffer, effectStorage)) { Serial.println("random color ip");}
|
else if (dispatchEffectId<EffectId::RANDOM_TWO_COLOR_INTERPOLATION>(id, effectFunction, ledStrip, msgBuffer, effectStorage)) {}
|
||||||
|
else if (dispatchEffectId<EffectId::SWIPE_AND_CHANGE >(id, effectFunction, ledStrip, msgBuffer, effectStorage)) {}
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
timeoutMsForEffect = 0;
|
timeoutMsForEffect = 0;
|
||||||
|
|
|
@ -15,111 +15,70 @@
|
||||||
|
|
||||||
#include "TaskLed.h"
|
#include "TaskLed.h"
|
||||||
|
|
||||||
MFRC522 rfid; // Instance of the class
|
// -------------------------------------------------- RFID Reader ----------------------------------------
|
||||||
|
MFRC522 rfid;
|
||||||
MFRC522::MIFARE_Key key;
|
MFRC522::MIFARE_Key key;
|
||||||
|
|
||||||
//LedStrip led(46, 23);
|
void tagHandler(uint8_t *sn)
|
||||||
LedStripRGBW<51> ledStrip;
|
|
||||||
Esp32DriverRGBW ledDriver;
|
|
||||||
|
|
||||||
LedTask<decltype(ledStrip)> ledTask;
|
|
||||||
|
|
||||||
bool fox;
|
|
||||||
void tag_handler(uint8_t *sn)
|
|
||||||
{
|
{
|
||||||
// serial number is always 5 bytes long
|
|
||||||
if (sn != nullptr)
|
if (sn != nullptr)
|
||||||
{
|
|
||||||
|
|
||||||
Serial.printf("Tag: %#x %#x %#x %#x %#x\n",
|
|
||||||
sn[0], sn[1], sn[2], sn[3], sn[4]);
|
|
||||||
sendMessageToHost(MsgRfidTokenRead{{sn[0], sn[1], sn[2], sn[3], sn[4]}});
|
sendMessageToHost(MsgRfidTokenRead{{sn[0], sn[1], sn[2], sn[3], sn[4]}});
|
||||||
if (sn[4] == 0x30)
|
|
||||||
{
|
|
||||||
Serial.println("Fuchs");
|
|
||||||
fox = true;
|
|
||||||
//ledTask.startEffect(EffectCircularConfig{2 * 360, 180, ColorRGBW{0, 0, 255, 0}});
|
|
||||||
ledTask.startEffect(EffectAlexaSwipeConfig{20, 30, 3 * 360, 3, 180, true, ColorRGBW{0, 255, 0, 0}, ColorRGBW{0, 0, 255, 0}});
|
|
||||||
delay(1000);
|
|
||||||
ledTask.startEffect(EffectRandomTwoColorInterpolationConfig{6000, true, 6, false, false, rgb2hsv(ColorRGBW{128, 0, 0, 0}),
|
|
||||||
rgb2hsv(ColorRGBW{0, 0, 128, 0})});
|
|
||||||
}
|
|
||||||
if (sn[4] == 0xf0)
|
|
||||||
{
|
|
||||||
Serial.println("Eule");
|
|
||||||
fox = false;
|
|
||||||
ledTask.startEffect(EffectCircularConfig{360, 180, ColorRGBW{0, 0, 255, 0}});
|
|
||||||
}
|
|
||||||
if (sn[4] == 0xe9)
|
|
||||||
{
|
|
||||||
Serial.println("Elephant");
|
|
||||||
fox = true;
|
|
||||||
ledTask.startEffect(EffectAlexaSwipeConfig{20, 30, 3 * 360, 3, 180, true, ColorRGBW{0, 0, 255, 0}, ColorRGBW{0, 200, 255, 0}});
|
|
||||||
delay(1000);
|
|
||||||
ledTask.startEffect(EffectRandomTwoColorInterpolationConfig{6000, true, 3, false, false, rgb2hsv(ColorRGBW{0, 0, 255, 0}),
|
|
||||||
rgb2hsv(ColorRGBW{0, 200, 255, 0})});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
sendMessageToHost(MsgRfidTokenRead{{0, 0, 0, 0, 0}});
|
||||||
Serial.println("Nichts");
|
|
||||||
if (fox)
|
|
||||||
{
|
|
||||||
fox = false;
|
|
||||||
ledTask.startEffect(EffectAlexaSwipeConfig{20, 30, 3 * 360, 3, 180, false, ColorRGBW{0, 255, 0, 0}, ColorRGBW{0, 0, 255, 0}});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ledTask.startEffect(EffectStaticConfig{ColorRGBW{0, 0, 0, 0}});
|
|
||||||
}
|
|
||||||
//led.transmit();
|
|
||||||
}
|
}
|
||||||
QueueHandle_t event_queue;
|
|
||||||
|
|
||||||
rotary_encoder_info_t info;
|
void setupRfidReader()
|
||||||
void setup()
|
|
||||||
{
|
{
|
||||||
Serial.begin(115200);
|
|
||||||
|
|
||||||
//led.begin();
|
|
||||||
ledDriver.begin(23, 0);
|
|
||||||
|
|
||||||
const rc522_start_args_t start_args = {
|
const rc522_start_args_t start_args = {
|
||||||
21, // MISO
|
21, // MISO
|
||||||
5, // MOSI
|
5, // MOSI
|
||||||
18, // SCK
|
18, // SCK
|
||||||
19, // SDA
|
19, // SDA
|
||||||
VSPI_HOST,
|
VSPI_HOST,
|
||||||
&tag_handler,
|
&tagHandler,
|
||||||
125, // scan_interval_ms
|
125, // scan_interval_ms
|
||||||
8 * 1024, // stacksize
|
8 * 1024, // stacksize
|
||||||
4 // task priority
|
4 // task priority
|
||||||
};
|
};
|
||||||
rc522_start(start_args);
|
rc522_start(start_args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------- Rotary Enc ----------------------------------------
|
||||||
|
QueueHandle_t eventQueueRotaryEncoder;
|
||||||
|
rotary_encoder_info_t info;
|
||||||
|
|
||||||
|
void setupRotaryEncoder()
|
||||||
|
{
|
||||||
ESP_ERROR_CHECK(gpio_install_isr_service(0));
|
ESP_ERROR_CHECK(gpio_install_isr_service(0));
|
||||||
ESP_ERROR_CHECK(rotary_encoder_init(&info, GPIO_NUM_26, GPIO_NUM_27));
|
ESP_ERROR_CHECK(rotary_encoder_init(&info, GPIO_NUM_26, GPIO_NUM_27));
|
||||||
ESP_ERROR_CHECK(rotary_encoder_enable_half_steps(&info, false));
|
ESP_ERROR_CHECK(rotary_encoder_enable_half_steps(&info, false));
|
||||||
event_queue = rotary_encoder_create_queue();
|
eventQueueRotaryEncoder = rotary_encoder_create_queue();
|
||||||
ESP_ERROR_CHECK(rotary_encoder_set_queue(&info, event_queue));
|
ESP_ERROR_CHECK(rotary_encoder_set_queue(&info, eventQueueRotaryEncoder));
|
||||||
|
|
||||||
//button leds
|
|
||||||
//pinMode(33, OUTPUT);
|
|
||||||
//digitalWrite(33, HIGH);
|
|
||||||
//pinMode(12, OUTPUT);
|
|
||||||
//digitalWrite(12, HIGH);
|
|
||||||
|
|
||||||
//// button in
|
|
||||||
//pinMode(25, INPUT_PULLUP);
|
|
||||||
//pinMode(14, INPUT_PULLUP);
|
|
||||||
//pinMode(13, INPUT_PULLUP);
|
|
||||||
ledTask.begin(ledStrip, ledDriver);
|
|
||||||
ledTask.startEffect(EffectStaticConfig{ColorRGBW{0, 0, 0, 0}});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool btn2state = true;
|
// -------------------------------------------------- Led circle ----------------------------------------
|
||||||
|
LedStripRGBW<51> ledStripCircle;
|
||||||
|
Esp32DriverRGBW ledDriverCircle;
|
||||||
|
LedTask<decltype(ledStripCircle)> ledTaskCircle;
|
||||||
|
|
||||||
|
void setupLedCircle()
|
||||||
|
{
|
||||||
|
ledDriverCircle.begin(23, 0);
|
||||||
|
ledTaskCircle.begin(ledStripCircle, ledDriverCircle);
|
||||||
|
ledTaskCircle.startEffect(EffectStaticConfig{ColorRGBW{0, 0, 0, 0}});
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(115200);
|
||||||
|
setupRfidReader();
|
||||||
|
setupRotaryEncoder();
|
||||||
|
setupLedCircle();
|
||||||
|
}
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
handleIncomingMessagesFromHost(&ledTask);
|
handleIncomingMessagesFromHost(&ledTaskCircle);
|
||||||
}
|
}
|
Loading…
Reference in New Issue