including light effects from different project
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
idf_component_register(
|
||||
SRC_DIRS "src"
|
||||
INCLUDE_DIRS "include"
|
||||
)
|
||||
@@ -0,0 +1,202 @@
|
||||
/**
|
||||
* @file color.hpp
|
||||
* @author Gustice
|
||||
* @brief
|
||||
*
|
||||
* @copyright Copyright (c) 2024
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <type_traits>
|
||||
|
||||
/// No Waveform definition
|
||||
extern uint8_t const *const noWave;
|
||||
|
||||
/**
|
||||
* @brief Color class
|
||||
*
|
||||
* @details Defines color data and common operations with color objects
|
||||
* \li Supports RGB with overlapping white channel (e.g. SK6812-LED)
|
||||
* \li Supports Operator overloading with '+' and '*' (Combined operation with MixWith)
|
||||
* \li Return formatted data stream that can be directly sent to an LED
|
||||
*/
|
||||
class Color {
|
||||
private:
|
||||
uint8_t red;
|
||||
uint8_t green;
|
||||
uint8_t blue;
|
||||
uint8_t white;
|
||||
|
||||
public:
|
||||
struct Rgbw {
|
||||
uint8_t red;
|
||||
uint8_t green;
|
||||
uint8_t blue;
|
||||
uint8_t white;
|
||||
};
|
||||
|
||||
struct Rgb {
|
||||
uint8_t red;
|
||||
uint8_t green;
|
||||
uint8_t blue;
|
||||
};
|
||||
|
||||
/// @brief Construct a new Color object
|
||||
/// @details Default color will be Black \ref _ctBlack
|
||||
Color(void) {
|
||||
set(0, 0, 0, 0);
|
||||
};
|
||||
|
||||
/// @brief Copy-Construct a new Color object
|
||||
Color(const Color & c) {
|
||||
red = c.red;
|
||||
green = c.green;
|
||||
blue = c.blue;
|
||||
white = c.white;
|
||||
};
|
||||
|
||||
/// @brief Construct a new Color object according to rgb color-channel-values
|
||||
/// @details This constructor also takes an overlapping white channel
|
||||
/// @param r Red channel
|
||||
/// @param g Green channel
|
||||
/// @param b Blue channel
|
||||
/// @param w White channel (zero by default if not assigned)
|
||||
Color(uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { set(r, g, b, w); };
|
||||
|
||||
/// @brief Set the Color object according to rgb color-channel values
|
||||
/// @param r Red channel
|
||||
/// @param g Green channel
|
||||
/// @param b Blue channel
|
||||
/// @param w White channel (zero by default if not assigned)
|
||||
void set(uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) {
|
||||
red = r;
|
||||
green = g;
|
||||
blue = b;
|
||||
white = w;
|
||||
}
|
||||
|
||||
/// @brief Returns Color as Color_t structure
|
||||
/// @return Color_t Color
|
||||
template <typename T>
|
||||
T getColor(void) const {
|
||||
if constexpr (std::is_same<T, Rgbw>::value) {
|
||||
return {red, green, blue, white};
|
||||
} else if constexpr (std::is_same<T, Rgb>::value) {
|
||||
return {red, green, blue};
|
||||
} else {
|
||||
throw "wrong type";
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t getRed() { return red; };
|
||||
uint8_t getGreen() { return green; };
|
||||
uint8_t getBlue() { return blue; };
|
||||
uint8_t getWhite() { return white; };
|
||||
|
||||
/// @brief Scaling and overlaying with given color.
|
||||
/// @param c2 Color 2
|
||||
/// @param k scaling factor
|
||||
/// @return Overlayed Color
|
||||
Color mixWith(const Color c2, uint8_t k = 0x7F) {
|
||||
auto t(c2);
|
||||
*this = (*this * (UINT8_MAX - k)) + (t * k);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// @brief Writes Color as formatted byte stream to location
|
||||
/// @param color
|
||||
template <typename T>
|
||||
void writeByteStreamTo(uint8_t raw[sizeof(T)]) const {
|
||||
if constexpr (std::is_same<T, Rgbw>::value) {
|
||||
raw[0] = blue;
|
||||
raw[1] = green;
|
||||
raw[2] = red;
|
||||
raw[3] = white;
|
||||
} else if constexpr (std::is_same<T, Rgb>::value) {
|
||||
raw[0] = blue;
|
||||
raw[1] = green;
|
||||
raw[2] = red;
|
||||
} else {
|
||||
throw "wrong type";
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Assign overload
|
||||
Color operator=(const Color &c2) {
|
||||
red = c2.red;
|
||||
green = c2.green;
|
||||
blue = c2.blue;
|
||||
white = c2.white;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// @brief Checks if both color values are equal
|
||||
bool operator==(Color const &c2) const {
|
||||
return ((blue == c2.blue) && (green == c2.green) &&
|
||||
(red == c2.red) && (white == c2.white));
|
||||
}
|
||||
|
||||
/// @brief Checks if both color values are not equal
|
||||
bool operator!=(Color const &c2) const {
|
||||
return ((blue != c2.blue) || (green != c2.green) ||
|
||||
(red != c2.red) || (white != c2.white));
|
||||
}
|
||||
|
||||
/// @brief Scale color by scaling each color-channel by given factor
|
||||
/// @param c1 Color
|
||||
/// @param k Scale-factor uint8_t.Max is full-scale
|
||||
/// @return Scaled Color
|
||||
Color operator*(uint8_t k) {
|
||||
red = (uint8_t)((uint16_t)red * k / 0xFF);
|
||||
green = (uint8_t)((uint16_t)green * k / 0xFF);
|
||||
blue = (uint8_t)((uint16_t)blue * k / 0xFF);
|
||||
white = (uint8_t)((uint16_t)white * k / 0xFF);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// @brief Overlaying to colors my adding each color channel value
|
||||
/// @note Colors channels should not overlap since there is no automatic ratio correction.
|
||||
/// Use *-Operator first in order to scale each color value a a way that no overflow can occur
|
||||
/// @param c2 Color 2
|
||||
/// @return Overlayed Color
|
||||
Color operator+(Color c2) {
|
||||
red = red + c2.red;
|
||||
green = green + c2.green;
|
||||
blue = blue + c2.blue;
|
||||
white = white + c2.white;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(sizeof(Color) == 4 && "Color Type is to big");
|
||||
|
||||
/// Null color object
|
||||
extern const Color *noColor;
|
||||
/// Used old color agreement (if no color pointer)
|
||||
extern const Color *oldColor;
|
||||
|
||||
/// Black color object constant
|
||||
extern const Color CBlack;
|
||||
/// Red color object constant
|
||||
extern const Color CRed;
|
||||
/// Green color object constant
|
||||
extern const Color CGreen;
|
||||
/// Blue color object constant
|
||||
extern const Color CBlue;
|
||||
/// Magenta color object constant
|
||||
extern const Color CMagenta;
|
||||
/// Cyan color object constant
|
||||
extern const Color CCyan;
|
||||
/// Yellow color object constant
|
||||
extern const Color CYellow;
|
||||
/// White color object constant
|
||||
extern const Color CWhite;
|
||||
/// Warm white color object constant (with higher red channel value)
|
||||
extern const Color CWarmWhite;
|
||||
/// Black color object constant (with higher green channel value)
|
||||
extern const Color CColdWhite;
|
||||
/// Black color object constant (with higher blue channel value)
|
||||
extern const Color CSpookyWhite;
|
||||
@@ -0,0 +1,202 @@
|
||||
/**
|
||||
* @file color.hpp
|
||||
* @author Gustice
|
||||
* @brief
|
||||
*
|
||||
* @copyright Copyright (c) 2024
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <type_traits>
|
||||
|
||||
/// No Waveform definition
|
||||
extern uint8_t const *const noWave;
|
||||
|
||||
/**
|
||||
* @brief Color class
|
||||
*
|
||||
* @details Defines color data and common operations with color objects
|
||||
* \li Supports RGB with overlapping white channel (e.g. SK6812-LED)
|
||||
* \li Supports Operator overloading with '+' and '*' (Combined operation with MixWith)
|
||||
* \li Return formatted data stream that can be directly sent to an LED
|
||||
*/
|
||||
class Color {
|
||||
private:
|
||||
uint8_t red;
|
||||
uint8_t green;
|
||||
uint8_t blue;
|
||||
uint8_t white;
|
||||
|
||||
public:
|
||||
struct Rgbw {
|
||||
uint8_t red;
|
||||
uint8_t green;
|
||||
uint8_t blue;
|
||||
uint8_t white;
|
||||
};
|
||||
|
||||
struct Rgb {
|
||||
uint8_t red;
|
||||
uint8_t green;
|
||||
uint8_t blue;
|
||||
};
|
||||
|
||||
/// @brief Construct a new Color object
|
||||
/// @details Default color will be Black \ref _ctBlack
|
||||
Color(void) {
|
||||
set(0, 0, 0, 0);
|
||||
};
|
||||
|
||||
/// @brief Copy-Construct a new Color object
|
||||
Color(const Color & c) {
|
||||
red = c.red;
|
||||
green = c.green;
|
||||
blue = c.blue;
|
||||
white = c.white;
|
||||
};
|
||||
|
||||
/// @brief Construct a new Color object according to rgb color-channel-values
|
||||
/// @details This constructor also takes an overlapping white channel
|
||||
/// @param r Red channel
|
||||
/// @param g Green channel
|
||||
/// @param b Blue channel
|
||||
/// @param w White channel (zero by default if not assigned)
|
||||
Color(uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { set(r, g, b, w); };
|
||||
|
||||
/// @brief Set the Color object according to rgb color-channel values
|
||||
/// @param r Red channel
|
||||
/// @param g Green channel
|
||||
/// @param b Blue channel
|
||||
/// @param w White channel (zero by default if not assigned)
|
||||
void set(uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) {
|
||||
red = r;
|
||||
green = g;
|
||||
blue = b;
|
||||
white = w;
|
||||
}
|
||||
|
||||
/// @brief Returns Color as Color_t structure
|
||||
/// @return Color_t Color
|
||||
template <typename T>
|
||||
T getColor(void) const {
|
||||
if constexpr (std::is_same<T, Rgbw>::value) {
|
||||
return {red, green, blue, white};
|
||||
} else if constexpr (std::is_same<T, Rgb>::value) {
|
||||
return {red, green, blue};
|
||||
} else {
|
||||
throw "wrong type";
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t getRed() { return red; };
|
||||
uint8_t getGreen() { return green; };
|
||||
uint8_t getBlue() { return blue; };
|
||||
uint8_t getWhite() { return white; };
|
||||
|
||||
/// @brief Scaling and overlaying with given color.
|
||||
/// @param c2 Color 2
|
||||
/// @param k scaling factor
|
||||
/// @return Overlayed Color
|
||||
Color mixWith(const Color c2, uint8_t k = 0x7F) {
|
||||
auto t(c2);
|
||||
*this = (*this * (UINT8_MAX - k)) + (t * k);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// @brief Writes Color as formatted byte stream to location
|
||||
/// @param color
|
||||
template <typename T>
|
||||
void writeByteStreamTo(uint8_t raw[sizeof(T)]) const {
|
||||
if constexpr (std::is_same<T, Rgbw>::value) {
|
||||
raw[0] = blue;
|
||||
raw[1] = green;
|
||||
raw[2] = red;
|
||||
raw[3] = white;
|
||||
} else if constexpr (std::is_same<T, Rgb>::value) {
|
||||
raw[0] = blue;
|
||||
raw[1] = green;
|
||||
raw[2] = red;
|
||||
} else {
|
||||
throw "wrong type";
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Assign overload
|
||||
Color operator=(const Color &c2) {
|
||||
red = c2.red;
|
||||
green = c2.green;
|
||||
blue = c2.blue;
|
||||
white = c2.white;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// @brief Checks if both color values are equal
|
||||
bool operator==(Color const &c2) const {
|
||||
return ((blue == c2.blue) && (green == c2.green) &&
|
||||
(red == c2.red) && (white == c2.white));
|
||||
}
|
||||
|
||||
/// @brief Checks if both color values are not equal
|
||||
bool operator!=(Color const &c2) const {
|
||||
return ((blue != c2.blue) || (green != c2.green) ||
|
||||
(red != c2.red) || (white != c2.white));
|
||||
}
|
||||
|
||||
/// @brief Scale color by scaling each color-channel by given factor
|
||||
/// @param c1 Color
|
||||
/// @param k Scale-factor uint8_t.Max is full-scale
|
||||
/// @return Scaled Color
|
||||
Color operator*(uint8_t k) {
|
||||
red = (uint8_t)((uint16_t)red * k / 0xFF);
|
||||
green = (uint8_t)((uint16_t)green * k / 0xFF);
|
||||
blue = (uint8_t)((uint16_t)blue * k / 0xFF);
|
||||
white = (uint8_t)((uint16_t)white * k / 0xFF);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// @brief Overlaying to colors my adding each color channel value
|
||||
/// @note Colors channels should not overlap since there is no automatic ratio correction.
|
||||
/// Use *-Operator first in order to scale each color value a a way that no overflow can occur
|
||||
/// @param c2 Color 2
|
||||
/// @return Overlayed Color
|
||||
Color operator+(Color c2) {
|
||||
red = red + c2.red;
|
||||
green = green + c2.green;
|
||||
blue = blue + c2.blue;
|
||||
white = white + c2.white;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(sizeof(Color) == 4 && "Color Type is to big");
|
||||
|
||||
/// Null color object
|
||||
extern const Color *noColor;
|
||||
/// Used old color agreement (if no color pointer)
|
||||
extern const Color *oldColor;
|
||||
|
||||
/// Black color object constant
|
||||
extern const Color CBlack;
|
||||
/// Red color object constant
|
||||
extern const Color CRed;
|
||||
/// Green color object constant
|
||||
extern const Color CGreen;
|
||||
/// Blue color object constant
|
||||
extern const Color CBlue;
|
||||
/// Magenta color object constant
|
||||
extern const Color CMagenta;
|
||||
/// Cyan color object constant
|
||||
extern const Color CCyan;
|
||||
/// Yellow color object constant
|
||||
extern const Color CYellow;
|
||||
/// White color object constant
|
||||
extern const Color CWhite;
|
||||
/// Warm white color object constant (with higher red channel value)
|
||||
extern const Color CWarmWhite;
|
||||
/// Black color object constant (with higher green channel value)
|
||||
extern const Color CColdWhite;
|
||||
/// Black color object constant (with higher blue channel value)
|
||||
extern const Color CSpookyWhite;
|
||||
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* @file ExactIndex.h
|
||||
* @author Gustice
|
||||
* @brief Index-Class with fix-point arithmetic
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
|
||||
/**
|
||||
* @brief Index-Class with fix-point arithmetic for exact stepping though data-points
|
||||
* @details Allows stepping through data-points by quotient step-sizes
|
||||
*/
|
||||
class ExactIndex {
|
||||
public:
|
||||
/// @brief Construct Index-object according to number of data points and steps to be taken
|
||||
/// @param length
|
||||
/// @param steps
|
||||
ExactIndex(unsigned length, uint16_t steps) : Length(std::max(1u, length)), Steps(steps) {
|
||||
_delta = Length << 8;
|
||||
_delta = _delta / steps;
|
||||
_index = unsigned(0u - _delta);
|
||||
}
|
||||
|
||||
/// @brief Get current index-position as floor value to never pass upper bound
|
||||
uint16_t GetIdx(void) { return ((_index) >> 8); };
|
||||
|
||||
/// @brief Move index by quotient step forward
|
||||
ExactIndex &operator++() {
|
||||
_index = _index + _delta;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// @brief Move index by quotient step backward
|
||||
ExactIndex &operator--() {
|
||||
_index = _index - _delta;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// @brief Get current index-position as floor value to never pass upper bound
|
||||
operator int() const { return ((_index) >> 8); }
|
||||
|
||||
/// @brief Get size of data set (number of data points)
|
||||
unsigned GetLength() { return Length; }
|
||||
/// @brief Get number of steps that are to be taken though data set
|
||||
uint16_t GetSteps() { return Steps; }
|
||||
|
||||
private:
|
||||
/// @brief Number of data points
|
||||
unsigned Length;
|
||||
/// @brief Steps to be taken through data-set
|
||||
uint16_t Steps;
|
||||
|
||||
/// @brief Current index in fixed-point representation
|
||||
unsigned _index = 0;
|
||||
|
||||
/// @brief Step-with in fixed-point representation
|
||||
unsigned _delta;
|
||||
};
|
||||
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* @file Macro.h
|
||||
* @author Gustice
|
||||
* @brief Predefined effect macros
|
||||
*
|
||||
* @copyright Copyright (c) 2024
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "Color.hpp"
|
||||
#include "Waveform.hpp"
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
namespace Effect {
|
||||
|
||||
/// Collection of process values to maintain processing state machine
|
||||
struct StepProcessVars {
|
||||
/// @brief Reference of current color
|
||||
const Color &pCurentColor;
|
||||
/// @brief Number of color entries
|
||||
uint8_t ColorLen;
|
||||
/// @brief Idle value for intensity
|
||||
uint8_t IdleIntensity;
|
||||
/// @brief Full value for intensity
|
||||
uint8_t FullIntensity;
|
||||
/// @brief Dynamic range for effects
|
||||
uint8_t DynamicRange;
|
||||
/// @brief Index in current waveform
|
||||
uint16_t waveIdx;
|
||||
/// @brief Reference to processed waveform
|
||||
const WaveForm_t *const pWave;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Effect implementation for State-Machine
|
||||
* @details State-Machine invokes referred effect-implementation during processing
|
||||
*/
|
||||
typedef Color (*EffectImplementation)(StepProcessVars &pcsParam);
|
||||
|
||||
/**
|
||||
* @brief Definition of Effect-Macro
|
||||
*/
|
||||
struct Macro_t {
|
||||
/// @brief Effect type
|
||||
const EffectImplementation pImplementation;
|
||||
/// @brief Effect duration waveforms will be compressed / stretched to fit the duration
|
||||
const uint8_t Duration;
|
||||
/// @brief Next SubEffect
|
||||
const int8_t Next;
|
||||
/// @brief waveform reference
|
||||
const WaveForm_t *pWave = emptyWave;
|
||||
/// @brief Full-Scale-intensity
|
||||
const uint8_t FsIntensity;
|
||||
/// @brief Num of Repeats
|
||||
const int8_t Repeats;
|
||||
|
||||
Macro_t(uint8_t duration, int8_t next, EffectImplementation state, uint8_t intensity,
|
||||
int8_t repeats = 0)
|
||||
: pImplementation(state), Duration(duration), Next(next), FsIntensity(intensity),
|
||||
Repeats(repeats) {}
|
||||
|
||||
Macro_t(uint8_t duration, int8_t next, WaveForm_t const *wave, EffectImplementation state,
|
||||
uint8_t intensity, int8_t repeats = 0)
|
||||
: pImplementation(state), Duration(duration), Next(next), pWave(wave),
|
||||
FsIntensity(intensity), Repeats(repeats) {}
|
||||
|
||||
private:
|
||||
/// @brief Null-pointer to represent no change in color
|
||||
static constexpr Color *pOldColor = nullptr;
|
||||
|
||||
/// @brief Null-pointer to represent no actual waveform-representation
|
||||
static constexpr WaveForm_t *pNoWave = nullptr;
|
||||
|
||||
/// @brief Default implemented Waveform with no profile
|
||||
static const constexpr WaveForm_t *emptyWave = &EmptyWave;
|
||||
};
|
||||
using Macro = std::vector<Macro_t>;
|
||||
|
||||
/// @brief Dark - Nothing to see here
|
||||
extern const Macro macDark;
|
||||
/// @brief Continuous idle
|
||||
extern const Macro macIdle;
|
||||
/// @brief Continuous flicker
|
||||
extern const Macro macStartFlicker;
|
||||
/// @brief Smooth turn on and then remaining idle
|
||||
extern const Macro macStartIdle;
|
||||
/// @brief Smooth turn on to full color
|
||||
extern const Macro macStartFull;
|
||||
/// @brief Slow pulse starting from idle intensity. Appears like breathing
|
||||
extern const Macro macStdPulse;
|
||||
/// @brief Short pulses starting from idle intensity. Appears nervously.
|
||||
extern const Macro macNervousPulse;
|
||||
|
||||
} // namespace Effect
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* @file EffectProcessor.h
|
||||
* @author Gustice
|
||||
* @brief Effect-Processor-Class for processing effect scenarios and switching actions
|
||||
*
|
||||
* @copyright Copyright (c) 2024
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "Color.hpp"
|
||||
#include "Macro.hpp"
|
||||
#include "StateMachine.hpp"
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
namespace Effect {
|
||||
|
||||
/**
|
||||
* @brief EffectProcessor Class
|
||||
* @details Maintains State-Machines, Processes effect-switching, and invokes generation
|
||||
* of raw data stream for LEDs.
|
||||
* \li If effect scenarios are changed a cross-fading is executed
|
||||
* \li Raw-data-stream for each Color object is generated
|
||||
*/
|
||||
class EffectProcessor {
|
||||
public:
|
||||
///@brief Constructor
|
||||
///@param fadeSteps Steps count for cross fade
|
||||
EffectProcessor(uint8_t const fadeSteps = 8);
|
||||
|
||||
/// @brief Set next effect sequence
|
||||
/// @param sequence reference to sequence that has to be processed next
|
||||
/// @param sColor Start color. Use noColor to start with default color
|
||||
/// @param intens Idle intensity for effect. Use NULL to start with default intensity
|
||||
void setEffect(const Macro &sequence, Color const *sColor = noColor, uint8_t delay = 0, uint8_t intens = gu8_idleIntensity);
|
||||
|
||||
/// @brief Execute step of effect processor
|
||||
/// @return Reference to color result
|
||||
Color tick(void);
|
||||
|
||||
private:
|
||||
StateMachine::Parameter _parameter;
|
||||
std::array<StateMachine, 2> _effectMachines;
|
||||
uint8_t _fadeSteps;
|
||||
uint8_t _fadingCnt;
|
||||
StateMachine *_EffPV;
|
||||
StateMachine *_EffPV_old;
|
||||
|
||||
Color crossFadeColors(Color &cNew, Color &cOld, uint8_t k);
|
||||
EffectProcessor();
|
||||
};
|
||||
|
||||
} // namespace Effect
|
||||
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
* @file EffectStateMachine.h
|
||||
* @author Gustice
|
||||
* @brief Effect-State-Machine-Class for processing Effect Macros
|
||||
* @version 0.6
|
||||
* @date 2019-10-01
|
||||
*
|
||||
* @copyright Copyright (c) 2019
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "Color.hpp"
|
||||
#include "Macro.hpp"
|
||||
#include <cstdint>
|
||||
#include "ExactIndex.hpp"
|
||||
|
||||
namespace Effect {
|
||||
|
||||
/**
|
||||
* @brief Effect State Machine Class
|
||||
* @details Processes Effect macro array Macro entry subsequently
|
||||
* Processing is executed in following manner:
|
||||
* \li Index-incrementing each Tick
|
||||
* \li ticks until duration \ref EffMacro is finished
|
||||
* \li each tick the index incremented by templateLength/duration
|
||||
* \li Repeats-processing
|
||||
* \li Each repeat the tick and the index are set back to start
|
||||
* \li Switches to next Macro enty
|
||||
* \li Next entry is given by 'next' index
|
||||
* \li Color changes can be executed optionally
|
||||
*/
|
||||
class StateMachine {
|
||||
public:
|
||||
/// @brief Collection of object configuration at startup
|
||||
struct Parameter {
|
||||
/// @brief Idle intensity as background color
|
||||
uint8_t idleIntens;
|
||||
/// @brief dynamic range as variation around background color
|
||||
uint8_t dynamicRange;
|
||||
/// @brief Fade steps for color changes
|
||||
uint8_t fadeSteps;
|
||||
/// @brief Count of target LEDs
|
||||
uint8_t targetCount;
|
||||
};
|
||||
|
||||
///@brief Construct a new Effect State Machine object
|
||||
///@param templateLength Length of waveforms that are used to display
|
||||
StateMachine(Parameter ¶meter);
|
||||
|
||||
///@brief Sets the effect state machine to process given effect macro
|
||||
///@param sequence reference to sequence
|
||||
///@param startColor Start color. Use noColor to invoke with default color
|
||||
///@param initialDelay Number of steps that are waited before effect is started
|
||||
void setEffect(const Macro &sequence, Color const *startColor = noColor, uint8_t initialDelay = 0);
|
||||
|
||||
/// @brief Sets the effect state machine to process given effect macro
|
||||
/// @param sequence reference to sequence
|
||||
/// @param startColor Start color. Use noColor to invoke with default color
|
||||
/// @param intens Idle intensity for effect. Use nullptr to start with default intensity
|
||||
/// @param delayedStart Number of steps that are waited before effect is started
|
||||
void setEffect(const Macro &sequence, Color const *startColor, const uint8_t *intens,
|
||||
const uint8_t delayedStart);
|
||||
|
||||
/// @brief Execute step of state machine
|
||||
/// @details Each tick the tick variable is decremented. After the limit is reached,
|
||||
/// the current macro line is either repeated or the next macro line is started (with
|
||||
/// an optional color change).\n
|
||||
/// @note Tick must be called regularly. For standard light applications all 40 ms seems to be
|
||||
/// a convenient values.
|
||||
/// @return Color const* Reference to color result
|
||||
virtual Color tick(void);
|
||||
|
||||
/// Black out lights
|
||||
static Color UpdateBlank(StepProcessVars &pcsParam);
|
||||
/// Continuous illumination in idle intensity
|
||||
static Color UpdateIdle(StepProcessVars &pcsParam);
|
||||
/// Keep latest state on hold
|
||||
static Color UpdateFreeze(StepProcessVars &pcsParam);
|
||||
/// Step through a defined waveform
|
||||
static Color UpdateWave(StepProcessVars &pcsParam);
|
||||
/// Step through a defined waveform backwards
|
||||
static Color UpdateRevWave(StepProcessVars &pcsParam);
|
||||
/// Show flicker effect with idle intensity as static part with dynamic flicker-range
|
||||
static Color UpdateFlicker(StepProcessVars &pcsParam);
|
||||
|
||||
protected:
|
||||
/// Collection of process values to maintain processing state machine
|
||||
struct ProcessValues {
|
||||
/// Decrementing tick, counting duration
|
||||
uint8_t tick;
|
||||
/// Decrementing repeats of current Effect-part
|
||||
uint8_t repeats;
|
||||
/// Index to macro element
|
||||
uint8_t macroIdx;
|
||||
/// Current index to waveform
|
||||
uint16_t waveIdx;
|
||||
/// Index step each tick according to duration and template length.
|
||||
uint16_t waveStep;
|
||||
};
|
||||
|
||||
/// @brief Concentrated parameter values of instance
|
||||
Parameter &_params;
|
||||
|
||||
Color const * _curentColor;
|
||||
ProcessValues _prcValues;
|
||||
void SetIndexes(void);
|
||||
|
||||
Macro const *_p_effSeq;
|
||||
Macro_t const *_p_effMac;
|
||||
ExactIndex _idx;
|
||||
|
||||
// Color& (*apF_Effects)(StateMachine * SM);
|
||||
typedef Color const *pEffPrc(StateMachine *);
|
||||
|
||||
};
|
||||
|
||||
} // namespace Effect
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @file WaveForm.h
|
||||
* @author Gustice
|
||||
* @brief C++ encapsulated waveform definition
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Waveforms.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
namespace Effect {
|
||||
|
||||
/**
|
||||
* @brief Waveform definition based on c-definitions
|
||||
*/
|
||||
struct WaveForm_t {
|
||||
/// @brief Reference to waveform
|
||||
const uint8_t *const pWave;
|
||||
/// @brief Length of waveform
|
||||
const unsigned Length;
|
||||
};
|
||||
|
||||
/// @brief Empty waveform with defined pointer to meaningless data to avoid problems
|
||||
extern const WaveForm_t EmptyWave;
|
||||
|
||||
} // namespace Effect
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* @file EffectWaveforms.h
|
||||
* @author Gustice
|
||||
* @brief Predefined Waveforms that can be put together to a complex Waveform
|
||||
* @version 0.6
|
||||
* @date 2019-10-01
|
||||
*
|
||||
* @copyright Copyright (c) 2019
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
|
||||
namespace Effect {
|
||||
|
||||
/// Length of all subsequent Template definitions
|
||||
extern const uint16_t cu16_TemplateLength;
|
||||
/// Idle intensity for Slopes and Pulses
|
||||
extern const uint8_t gu8_idleIntensity;
|
||||
/// Idle intensity for Slopes and Pulses
|
||||
extern const uint8_t gu8_fullIntensity;
|
||||
/// Headroom for Effects on top of idle brightness
|
||||
extern const uint8_t gu8_dynamicRange;
|
||||
/// Standard cross fade steps
|
||||
extern const uint8_t gu8_fadeSteps;
|
||||
|
||||
/// Starts from idle \ref gu8_idleIntensity and represents a gaussian impulse \ref gu8_fullIntensity
|
||||
extern const uint8_t gau8_offsetPulse[];
|
||||
/// Starts at zero and rises to idle intensity \ref gu8_idleIntensity
|
||||
extern const uint8_t gau8_initSlope[];
|
||||
/// Starts from idle \ref gu8_idleIntensity and rises up to full intensity \ref gu8_fullIntensity
|
||||
extern const uint8_t gau8_offsetSlope[];
|
||||
/// Starts at zero and rises to full intensity \ref gu8_fullIntensity
|
||||
extern const uint8_t gau8_fullSlope[];
|
||||
/// Starts at zero and represents a gaussian impulse to full intensity \ref gu8_fullIntensity
|
||||
extern const uint8_t gau8_fullPulse[];
|
||||
|
||||
} // namespace Effect
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @file color.cpp
|
||||
* @author Gustice
|
||||
* @brief Implementation of Color-Class
|
||||
*
|
||||
* @copyright Copyright (c) 2024
|
||||
*/
|
||||
|
||||
#include "Color.hpp"
|
||||
|
||||
uint8_t const * const noWave = nullptr;
|
||||
|
||||
const Color *noColor = nullptr;
|
||||
const Color *oldColor = nullptr;
|
||||
|
||||
const Color CBlack(0x00, 0x00, 0x00, 0x00);
|
||||
const Color CRed(0xFF, 0x00, 0x00, 0x00);
|
||||
const Color CGreen(0x00, 0xFF, 0x00, 0x00);
|
||||
const Color CBlue(0x00, 0x00, 0xFF, 0x00);
|
||||
const Color CMagenta(0x80, 0x00, 0x80, 0x00);
|
||||
const Color CCyan(0x00, 0x80, 0x80, 0x00);
|
||||
const Color CYellow(0x80, 0x80, 0x00, 0x00);
|
||||
const Color CWhite(0x55, 0x55, 0x55, 0x00);
|
||||
const Color CWarmWhite(0x7F, 0x4F, 0x4F, 0x00);
|
||||
const Color CColdWhite(0x4F, 0x4F, 0x7F, 0x00);
|
||||
const Color CSpookyWhite(0x4F, 0x7F, 0x4F, 0x00);
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* @file EffectMacro.cpp
|
||||
* @author Gustice
|
||||
* @brief Predefined Macros
|
||||
* @version 0.6
|
||||
* @date 2021-03-23
|
||||
*
|
||||
* @copyright Copyright (c) 2021
|
||||
*/
|
||||
|
||||
#include "Macro.hpp"
|
||||
#include "Color.hpp"
|
||||
#include "Waveforms.hpp"
|
||||
#include "StateMachine.hpp"
|
||||
|
||||
namespace Effect {
|
||||
const uint8_t Empty[4] = {0, 0, 0, 0};
|
||||
|
||||
const WaveForm_t EmptyWave{Empty, 4};
|
||||
const WaveForm_t OffsetPulseWave{gau8_offsetPulse, cu16_TemplateLength};
|
||||
const WaveForm_t InitSlopeWave{gau8_initSlope, cu16_TemplateLength};
|
||||
const WaveForm_t OffsetSlopeWave{gau8_offsetSlope, cu16_TemplateLength};
|
||||
const WaveForm_t FullSlopeWave{gau8_fullSlope, cu16_TemplateLength};
|
||||
const WaveForm_t FullPulseWave{gau8_fullPulse, cu16_TemplateLength};
|
||||
|
||||
const Macro macDark = {
|
||||
{32, 0, StateMachine::UpdateBlank, 0, 0}
|
||||
};
|
||||
|
||||
const Macro macIdle = {
|
||||
{32, 1, StateMachine::UpdateIdle, 0xFF},
|
||||
{32, 1, StateMachine::UpdateIdle, 0xFF},
|
||||
};
|
||||
|
||||
const Macro macStartIdle = {
|
||||
{64, 1, &InitSlopeWave, StateMachine::UpdateWave, 0xFF},
|
||||
{32, 1, StateMachine::UpdateIdle, 0xFF},
|
||||
};
|
||||
|
||||
const Macro macStartFlicker = {
|
||||
{64, 1, &InitSlopeWave, StateMachine::UpdateWave, 0xFF},
|
||||
{32, 1, StateMachine::UpdateFlicker, 0xFF},
|
||||
};
|
||||
|
||||
const Macro macStartFull = {
|
||||
{24, 1, &FullSlopeWave, StateMachine::UpdateWave, 0xFF},
|
||||
{32, 1, StateMachine::UpdateIdle, 0xFF},
|
||||
};
|
||||
|
||||
const Macro macStdPulse = {
|
||||
{32, 1, StateMachine::UpdateIdle, 0},
|
||||
{32, 2, &OffsetPulseWave, StateMachine::UpdateWave, 0xFF},
|
||||
{32, 0, StateMachine::UpdateIdle, 0},
|
||||
};
|
||||
|
||||
const Macro macNervousPulse = {
|
||||
{8, 1, StateMachine::UpdateIdle, 0},
|
||||
{16, 2, &OffsetPulseWave, StateMachine::UpdateWave, 0xFF},
|
||||
{8, 0, StateMachine::UpdateIdle, 0},
|
||||
};
|
||||
|
||||
const Macro macStdWipe = {
|
||||
{32, 1, StateMachine::UpdateIdle, 0},
|
||||
|
||||
{32, 2, &OffsetSlopeWave, StateMachine::UpdateWave, 0xFF},
|
||||
{32, 3, StateMachine::UpdateFreeze, 0},
|
||||
{32, 4, &OffsetSlopeWave, StateMachine::UpdateRevWave, 0xFF},
|
||||
{32, 1, StateMachine::UpdateFreeze, 0},
|
||||
};
|
||||
|
||||
} // namespace Effect
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* @file Processor.cpp
|
||||
* @author Gustice
|
||||
* @brief Implementation of Effect-Processor-Class EffectProcessor.h
|
||||
* @version 0.6
|
||||
* @date 2019-10-03
|
||||
*
|
||||
* @copyright Copyright (c) 2019
|
||||
*/
|
||||
|
||||
#include "Processor.hpp"
|
||||
#include "Macro.hpp"
|
||||
#include "Waveforms.hpp"
|
||||
#include <algorithm>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace Effect {
|
||||
|
||||
EffectProcessor::EffectProcessor(uint8_t const fadeSteps)
|
||||
: _parameter{0x20, 0x20, 0, 1},
|
||||
_effectMachines{StateMachine{_parameter}, StateMachine{_parameter}} {
|
||||
_EffPV = &_effectMachines[0];
|
||||
_EffPV_old = &_effectMachines[1];
|
||||
_EffPV->setEffect(macDark, noColor);
|
||||
_fadeSteps = fadeSteps;
|
||||
}
|
||||
|
||||
void EffectProcessor::setEffect(const Macro &sequence, Color const *sColor, uint8_t delay, uint8_t intens) {
|
||||
_fadingCnt = _fadeSteps;
|
||||
std::swap(_EffPV, _EffPV_old);
|
||||
_EffPV->setEffect(sequence, sColor, &intens, delay);
|
||||
}
|
||||
|
||||
Color EffectProcessor::tick(void) {
|
||||
uint8_t k;
|
||||
auto cN = (_EffPV->tick());
|
||||
|
||||
if (_fadingCnt > 0) { // always process soft cross dissolve between different macros
|
||||
_fadingCnt--;
|
||||
k = (uint16_t)_fadingCnt * 0xFF / _fadeSteps;
|
||||
|
||||
auto cO = (_EffPV_old->tick());
|
||||
cN = crossFadeColors(cN, cO, k);
|
||||
}
|
||||
|
||||
return cN;
|
||||
}
|
||||
|
||||
Color EffectProcessor::crossFadeColors(Color &cNew, Color &cOld, uint8_t k) {
|
||||
cOld = cOld * k;
|
||||
cNew = cNew * (0xFF - k);
|
||||
cNew = cNew + cOld;
|
||||
|
||||
return cNew;
|
||||
}
|
||||
|
||||
} // namespace Effect
|
||||
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* @file StateMachine.cpp
|
||||
* @author Gustice
|
||||
* @brief Implementation of Effect-State-Machine-Class EffectStateMachine.h
|
||||
* @version 0.6
|
||||
* @date 2019-10-01
|
||||
*
|
||||
* @copyright Copyright (c) 2019
|
||||
*
|
||||
*/
|
||||
#include "StateMachine.hpp"
|
||||
#include "Waveforms.hpp"
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace Effect {
|
||||
|
||||
/// Optional prequel for delayed start.
|
||||
/// \li Duration must be != 0
|
||||
/// \li Next entry will be first entry in given Effect sequence
|
||||
Macro delayPrequel = {
|
||||
{1, 0, StateMachine::UpdateBlank, 0, 0}
|
||||
};
|
||||
|
||||
StateMachine::StateMachine(Parameter ¶meter)
|
||||
: _params(parameter), _idx(/*pseudo values*/ 1, 1) {}
|
||||
|
||||
void StateMachine::setEffect(const Macro &sequence, Color const *startColor, uint8_t initialDelay) {
|
||||
setEffect(sequence, startColor, &_params.idleIntens, initialDelay);
|
||||
}
|
||||
|
||||
void StateMachine::setEffect(const Macro &sequence, Color const *startColor, const uint8_t *intens,
|
||||
const uint8_t delayedStart) {
|
||||
if (startColor != noColor) {
|
||||
_curentColor = startColor;
|
||||
}
|
||||
if (intens != nullptr) {
|
||||
_params.idleIntens = *intens;
|
||||
}
|
||||
|
||||
_p_effSeq = &sequence;
|
||||
if (delayedStart > 0) {
|
||||
_p_effMac = &delayPrequel[0];
|
||||
_prcValues.tick = delayedStart;
|
||||
} else {
|
||||
_p_effMac = &sequence[0];
|
||||
_prcValues.tick = _p_effMac->Duration;
|
||||
}
|
||||
|
||||
_prcValues.tick++;
|
||||
_prcValues.repeats = _p_effMac->Repeats;
|
||||
_idx = ExactIndex(_p_effMac->pWave->Length, _p_effMac->Duration);
|
||||
}
|
||||
|
||||
Color StateMachine::tick(void) {
|
||||
// tick-increment
|
||||
if (--_prcValues.tick == 0) {
|
||||
// repeats-decrement
|
||||
if (_prcValues.repeats-- == 0) {
|
||||
_p_effMac = &(*_p_effSeq)[_p_effMac->Next];
|
||||
_prcValues.repeats = _p_effMac->Repeats;
|
||||
}
|
||||
|
||||
_prcValues.tick = _p_effMac->Duration;
|
||||
_idx = ExactIndex(_p_effMac->pWave->Length, _p_effMac->Duration);
|
||||
}
|
||||
|
||||
++_idx;
|
||||
|
||||
StepProcessVars pv{
|
||||
.pCurentColor = *_curentColor,
|
||||
.ColorLen = _params.targetCount,
|
||||
.IdleIntensity = _params.idleIntens,
|
||||
.FullIntensity = _p_effMac->FsIntensity,
|
||||
.DynamicRange = _params.dynamicRange,
|
||||
.waveIdx = _idx.GetIdx(),
|
||||
.pWave = _p_effMac->pWave,
|
||||
};
|
||||
return _p_effMac->pImplementation(pv);
|
||||
}
|
||||
|
||||
Color StateMachine::UpdateBlank(StepProcessVars &pcsParam) {
|
||||
return CBlack;
|
||||
}
|
||||
|
||||
Color StateMachine::UpdateIdle(StepProcessVars &pcsParam) {
|
||||
auto c = pcsParam.pCurentColor;
|
||||
return c * pcsParam.IdleIntensity;
|
||||
}
|
||||
|
||||
Color StateMachine::UpdateFreeze(StepProcessVars &pcsParam) {
|
||||
return pcsParam.pCurentColor;
|
||||
}
|
||||
|
||||
Color StateMachine::UpdateWave(StepProcessVars &pcsParam) {
|
||||
Color temp = pcsParam.pCurentColor;
|
||||
temp = temp * ((float)(pcsParam.pWave->pWave[pcsParam.waveIdx]) / 0xFF * pcsParam.FullIntensity);
|
||||
return temp;
|
||||
}
|
||||
|
||||
Color StateMachine::UpdateRevWave(StepProcessVars &pcsParam) {
|
||||
unsigned lastIndex = pcsParam.pWave->Length - 1;
|
||||
Color temp = pcsParam.pCurentColor;
|
||||
temp = temp * ((float)(pcsParam.pWave->pWave[lastIndex - pcsParam.waveIdx]) / 0xFF *
|
||||
pcsParam.FullIntensity);
|
||||
return temp;
|
||||
}
|
||||
|
||||
Color StateMachine::UpdateFlicker(StepProcessVars &pcsParam) {
|
||||
uint8_t k = rand();
|
||||
k = pcsParam.IdleIntensity + ((int16_t)k * (pcsParam.DynamicRange) / 0xFF);
|
||||
auto c = pcsParam.pCurentColor;
|
||||
c = c * ((float)(k));
|
||||
return c;
|
||||
}
|
||||
|
||||
} // namespace Effect
|
||||
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* @file Waveforms.cpp
|
||||
* @author Gustice
|
||||
* @brief Implementation of defined Waveforms
|
||||
* @version 0.6
|
||||
* @date 2019-10-01
|
||||
*
|
||||
* @copyright Copyright (c) 2019
|
||||
* @note The defined waveforms are generated with a the WaveformGenerator
|
||||
*/
|
||||
#include "Waveforms.hpp"
|
||||
|
||||
namespace Effect {
|
||||
|
||||
const uint16_t cu16_TemplateLength = 128;
|
||||
const uint8_t gu8_idleIntensity = 0x55;
|
||||
const uint8_t gu8_fullIntensity = 0xFF;
|
||||
const uint8_t gu8_dynamicRange = gu8_fullIntensity - gu8_idleIntensity;
|
||||
const uint8_t gu8_fadeSteps = 10;
|
||||
|
||||
// clang-format off
|
||||
// Offset Pulse: Gaussian pulse from background illumination with full scale intensity
|
||||
const uint8_t gau8_offsetPulse[cu16_TemplateLength * 2] = {
|
||||
0x55, 0x55, 0x55, 0x56, 0x56, 0x56, 0x57, 0x57, 0x57, 0x58, 0x58, 0x59, 0x59, 0x5A, 0x5B, 0x5C,
|
||||
0x5D, 0x5E, 0x5F, 0x61, 0x62, 0x64, 0x66, 0x68, 0x6A, 0x6C, 0x6F, 0x71, 0x74, 0x77, 0x7B, 0x7E,
|
||||
0x81, 0x85, 0x89, 0x8E, 0x92, 0x97, 0x9B, 0xA0, 0xA5, 0xAA, 0xAF, 0xB5, 0xBA, 0xBF, 0xC4, 0xC9,
|
||||
0xCF, 0xD3, 0xD8, 0xDD, 0xE1, 0xE6, 0xEA, 0xED, 0xF1, 0xF4, 0xF7, 0xF9, 0xFB, 0xFD, 0xFD, 0xFE,
|
||||
0xFF, 0xFE, 0xFD, 0xFD, 0xFB, 0xF9, 0xF7, 0xF4, 0xF1, 0xED, 0xEA, 0xE6, 0xE1, 0xDD, 0xD8, 0xD3,
|
||||
0xCF, 0xC9, 0xC4, 0xBF, 0xBA, 0xB5, 0xAF, 0xAA, 0xA5, 0xA0, 0x9B, 0x97, 0x92, 0x8E, 0x89, 0x85,
|
||||
0x81, 0x7E, 0x7B, 0x77, 0x74, 0x71, 0x6F, 0x6C, 0x6A, 0x68, 0x66, 0x64, 0x62, 0x61, 0x5F, 0x5E,
|
||||
0x5D, 0x5C, 0x5B, 0x5A, 0x59, 0x59, 0x58, 0x58, 0x57, 0x57, 0x57, 0x56, 0x56, 0x56, 0x55, 0x55,
|
||||
|
||||
0x55, 0x55, 0x55, 0x56, 0x56, 0x56, 0x57, 0x57, 0x57, 0x58, 0x58, 0x59, 0x59, 0x5A, 0x5B, 0x5C,
|
||||
0x5D, 0x5E, 0x5F, 0x61, 0x62, 0x64, 0x66, 0x68, 0x6A, 0x6C, 0x6F, 0x71, 0x74, 0x77, 0x7B, 0x7E,
|
||||
0x81, 0x85, 0x89, 0x8E, 0x92, 0x97, 0x9B, 0xA0, 0xA5, 0xAA, 0xAF, 0xB5, 0xBA, 0xBF, 0xC4, 0xC9,
|
||||
0xCF, 0xD3, 0xD8, 0xDD, 0xE1, 0xE6, 0xEA, 0xED, 0xF1, 0xF4, 0xF7, 0xF9, 0xFB, 0xFD, 0xFD, 0xFE,
|
||||
0xFF, 0xFE, 0xFD, 0xFD, 0xFB, 0xF9, 0xF7, 0xF4, 0xF1, 0xED, 0xEA, 0xE6, 0xE1, 0xDD, 0xD8, 0xD3,
|
||||
0xCF, 0xC9, 0xC4, 0xBF, 0xBA, 0xB5, 0xAF, 0xAA, 0xA5, 0xA0, 0x9B, 0x97, 0x92, 0x8E, 0x89, 0x85,
|
||||
0x81, 0x7E, 0x7B, 0x77, 0x74, 0x71, 0x6F, 0x6C, 0x6A, 0x68, 0x66, 0x64, 0x62, 0x61, 0x5F, 0x5E,
|
||||
0x5D, 0x5C, 0x5B, 0x5A, 0x59, 0x59, 0x58, 0x58, 0x57, 0x57, 0x57, 0x56, 0x56, 0x56, 0x55, 0x55,
|
||||
};
|
||||
|
||||
// Full Pulse: Gaussian pulse from dark to full scale intensity
|
||||
const uint8_t gau8_fullPulse[cu16_TemplateLength * 2] = {
|
||||
0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x05, 0x06, 0x07, 0x08, 0x0A, 0x0B,
|
||||
0x0D, 0x0E, 0x10, 0x12, 0x14, 0x17, 0x1A, 0x1D, 0x20, 0x23, 0x27, 0x2B, 0x2F, 0x34, 0x39, 0x3E,
|
||||
0x43, 0x49, 0x4F, 0x56, 0x5C, 0x63, 0x6A, 0x71, 0x79, 0x80, 0x88, 0x90, 0x98, 0x9F, 0xA7, 0xAF,
|
||||
0xB7, 0xBE, 0xC5, 0xCC, 0xD3, 0xDA, 0xE0, 0xE5, 0xEA, 0xEF, 0xF3, 0xF6, 0xF9, 0xFC, 0xFD, 0xFE,
|
||||
0xFF, 0xFE, 0xFD, 0xFC, 0xF9, 0xF6, 0xF3, 0xEF, 0xEA, 0xE5, 0xE0, 0xDA, 0xD3, 0xCC, 0xC5, 0xBE,
|
||||
0xB7, 0xAF, 0xA7, 0x9F, 0x98, 0x90, 0x88, 0x80, 0x79, 0x71, 0x6A, 0x63, 0x5C, 0x56, 0x4F, 0x49,
|
||||
0x43, 0x3E, 0x39, 0x34, 0x2F, 0x2B, 0x27, 0x23, 0x20, 0x1D, 0x1A, 0x17, 0x14, 0x12, 0x10, 0x0E,
|
||||
0x0D, 0x0B, 0x0A, 0x08, 0x07, 0x06, 0x05, 0x05, 0x04, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01,
|
||||
|
||||
0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x05, 0x06, 0x07, 0x08, 0x0A, 0x0B,
|
||||
0x0D, 0x0E, 0x10, 0x12, 0x14, 0x17, 0x1A, 0x1D, 0x20, 0x23, 0x27, 0x2B, 0x2F, 0x34, 0x39, 0x3E,
|
||||
0x43, 0x49, 0x4F, 0x56, 0x5C, 0x63, 0x6A, 0x71, 0x79, 0x80, 0x88, 0x90, 0x98, 0x9F, 0xA7, 0xAF,
|
||||
0xB7, 0xBE, 0xC5, 0xCC, 0xD3, 0xDA, 0xE0, 0xE5, 0xEA, 0xEF, 0xF3, 0xF6, 0xF9, 0xFC, 0xFD, 0xFE,
|
||||
0xFF, 0xFE, 0xFD, 0xFC, 0xF9, 0xF6, 0xF3, 0xEF, 0xEA, 0xE5, 0xE0, 0xDA, 0xD3, 0xCC, 0xC5, 0xBE,
|
||||
0xB7, 0xAF, 0xA7, 0x9F, 0x98, 0x90, 0x88, 0x80, 0x79, 0x71, 0x6A, 0x63, 0x5C, 0x56, 0x4F, 0x49,
|
||||
0x43, 0x3E, 0x39, 0x34, 0x2F, 0x2B, 0x27, 0x23, 0x20, 0x1D, 0x1A, 0x17, 0x14, 0x12, 0x10, 0x0E,
|
||||
0x0D, 0x0B, 0x0A, 0x08, 0x07, 0x06, 0x05, 0x05, 0x04, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01,
|
||||
};
|
||||
|
||||
// Init Slope: Gaussian slope from dark to background brightness
|
||||
const uint8_t gau8_initSlope[cu16_TemplateLength * 2] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x04,
|
||||
0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
|
||||
0x12, 0x13, 0x14, 0x16, 0x17, 0x19, 0x1A, 0x1C, 0x1D, 0x1F, 0x21, 0x22, 0x24, 0x26, 0x27, 0x29,
|
||||
0x2B, 0x2D, 0x2E, 0x30, 0x32, 0x33, 0x35, 0x37, 0x38, 0x3A, 0x3B, 0x3D, 0x3E, 0x40, 0x41, 0x42,
|
||||
0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4C, 0x4D, 0x4E, 0x4E, 0x4F, 0x4F, 0x50,
|
||||
0x50, 0x51, 0x51, 0x52, 0x52, 0x52, 0x52, 0x53, 0x53, 0x53, 0x53, 0x53, 0x54, 0x54, 0x54, 0x54,
|
||||
0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55,
|
||||
};
|
||||
|
||||
// Offset Pulse: Gaussian slope from background illumination to full scale brightness
|
||||
const uint8_t gau8_offsetSlope[cu16_TemplateLength] = {
|
||||
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
|
||||
0x56, 0x56, 0x56, 0x56, 0x57, 0x57, 0x57, 0x58, 0x58, 0x59, 0x59, 0x5A, 0x5A, 0x5B, 0x5C, 0x5D,
|
||||
0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x65, 0x66, 0x68, 0x6A, 0x6C, 0x6E, 0x70, 0x72, 0x74, 0x76,
|
||||
0x79, 0x7B, 0x7E, 0x81, 0x84, 0x87, 0x8A, 0x8D, 0x90, 0x93, 0x97, 0x9A, 0x9D, 0xA1, 0xA4, 0xA8,
|
||||
0xAB, 0xAF, 0xB2, 0xB6, 0xB9, 0xBC, 0xC0, 0xC3, 0xC6, 0xC9, 0xCC, 0xCF, 0xD2, 0xD5, 0xD8, 0xDA,
|
||||
0xDD, 0xDF, 0xE1, 0xE3, 0xE5, 0xE7, 0xE9, 0xEB, 0xED, 0xEE, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5,
|
||||
0xF6, 0xF7, 0xF8, 0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFD,
|
||||
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF,
|
||||
};
|
||||
|
||||
// Full Slope: Gaussian slope from dark to full scale brightness
|
||||
const uint8_t gau8_fullSlope[cu16_TemplateLength] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0C,
|
||||
0x0D, 0x0F, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1D, 0x1F, 0x22, 0x25, 0x28, 0x2B, 0x2F, 0x32,
|
||||
0x36, 0x3A, 0x3E, 0x42, 0x46, 0x4B, 0x50, 0x54, 0x59, 0x5E, 0x63, 0x68, 0x6D, 0x72, 0x77, 0x7C,
|
||||
0x82, 0x87, 0x8C, 0x91, 0x96, 0x9B, 0xA0, 0xA5, 0xAA, 0xAE, 0xB3, 0xB8, 0xBC, 0xC0, 0xC4, 0xC8,
|
||||
0xCC, 0xCF, 0xD3, 0xD6, 0xD9, 0xDC, 0xDF, 0xE1, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE, 0xEF, 0xF1,
|
||||
0xF2, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFC, 0xFD, 0xFD,
|
||||
0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF,
|
||||
};
|
||||
|
||||
}// clang-format on
|
||||
@@ -0,0 +1,5 @@
|
||||
idf_component_register(
|
||||
SRC_DIRS "."
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES cmock utils
|
||||
)
|
||||
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* @file testUtils.cpp
|
||||
* @author Gustice
|
||||
* @brief Hardware bound unit-tests
|
||||
*
|
||||
* @copyright Copyright (c) 2024
|
||||
*/
|
||||
|
||||
#include "testable.h"
|
||||
#include "unity.h"
|
||||
#include <limits.h>
|
||||
|
||||
TEST_CASE("No relevant test case", "[utils]") {
|
||||
TEST_ASSERT_EQUAL(0, 0);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
unitTestsFrame()
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* @file TestableUTest.cpp
|
||||
* @author Gustice
|
||||
* @brief
|
||||
*
|
||||
* @copyright Copyright (c) 2024
|
||||
*/
|
||||
|
||||
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
|
||||
#include "utils.hpp"
|
||||
#include "doctest/doctest.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace SingleActiveTests {
|
||||
|
||||
class Foo : public SingleActive<Foo> {
|
||||
public:
|
||||
int test{};
|
||||
|
||||
Foo() : SingleActive() {}
|
||||
};
|
||||
template <>
|
||||
bool Foo::SingleActive<Foo>::active{};
|
||||
|
||||
class Bar : public SingleActive<Bar> {
|
||||
public:
|
||||
int test{};
|
||||
|
||||
Bar() : SingleActive() {}
|
||||
};
|
||||
template <>
|
||||
bool Bar::SingleActive<Bar>::active{};
|
||||
|
||||
TEST_CASE("Sweet path") {
|
||||
{ // first instances
|
||||
Foo dut;
|
||||
} // destruction
|
||||
|
||||
{ // second instances
|
||||
Foo dut;
|
||||
} // destruction
|
||||
|
||||
{ // third instance
|
||||
Foo dut1;
|
||||
Bar dut2; // First instance of second class
|
||||
} // destruction
|
||||
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
TEST_CASE("Too many instances") {
|
||||
{
|
||||
Foo dut1;
|
||||
Foo *pDut2;
|
||||
CHECK_THROWS_WITH(pDut2 = new Foo, "Instance already active");
|
||||
}
|
||||
CHECK(true);
|
||||
}
|
||||
}
|
||||
+197
-43
@@ -1,42 +1,12 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
/**
|
||||
* @file watchMain.cpp
|
||||
* @author Gustice
|
||||
* @brief ChaosWatch Application
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
* @copyright Copyright (c) 2024
|
||||
*/
|
||||
/* eth2ap (Ethernet to Wi-Fi AP packet forwarding) Example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_eth_driver.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "esp_private/wifi.h"
|
||||
#include "ethernet_init.h"
|
||||
#include "esp_netif.h"
|
||||
#include "esp_eth.h"
|
||||
|
||||
// Component header
|
||||
#include "Task.hpp"
|
||||
#include "PwmExpanderPca9685.hpp"
|
||||
#include "StepperDrv8833.hpp"
|
||||
#include "stepperMotor.hpp"
|
||||
#include "cliWrapper.hpp"
|
||||
#include "udpSockets.hpp"
|
||||
#include "tcpSockets.hpp"
|
||||
#include "Queue.hpp"
|
||||
#include "Artnet.h"
|
||||
#include "watchMain.hpp"
|
||||
|
||||
static const char *TAG = "Watch";
|
||||
static esp_eth_handle_t s_eth_handle = NULL;
|
||||
@@ -46,12 +16,6 @@ extern "C" { // This switch allows the ROS C-implementation to find this main
|
||||
void app_main(void);
|
||||
}
|
||||
|
||||
struct Color {
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
};
|
||||
|
||||
struct DeviceState {
|
||||
int jumps;
|
||||
int pictogram;
|
||||
@@ -150,7 +114,7 @@ static void telnetSocketTask(int addrFamily) {
|
||||
|
||||
|
||||
constexpr uint32_t DmxUniverse = 0;
|
||||
constexpr int DmxChannelCount = 9; //
|
||||
constexpr int DmxChannelCount = 9;
|
||||
|
||||
uint8_t scaledRgbChannel(uint8_t value, float scale) {
|
||||
return static_cast<uint8_t>(value * scale);
|
||||
@@ -344,6 +308,30 @@ static void initialize_ethernet(void)
|
||||
ESP_ERROR_CHECK(esp_eth_start(s_eth_handle));
|
||||
}
|
||||
|
||||
namespace Effect {
|
||||
extern const WaveForm_t OffsetPulseWave{gau8_offsetPulse, cu16_TemplateLength};
|
||||
extern const WaveForm_t InitSlopeWave{gau8_initSlope, cu16_TemplateLength};
|
||||
extern const WaveForm_t OffsetSlopeWave{gau8_offsetSlope, cu16_TemplateLength};
|
||||
extern const WaveForm_t FullSlopeWave{gau8_fullSlope, cu16_TemplateLength};
|
||||
extern const WaveForm_t FullPulseWave{gau8_fullPulse, cu16_TemplateLength};
|
||||
|
||||
const Macro macDemoStart = {
|
||||
{64, 1, &InitSlopeWave, StateMachine::UpdateWave, 0xFF},
|
||||
{32, 1, StateMachine::UpdateIdle, 0xFF},
|
||||
};
|
||||
|
||||
const Macro macDemoPulse = {
|
||||
{64, 1, &InitSlopeWave, StateMachine::UpdateWave, 0xFF},
|
||||
{32, 2, StateMachine::UpdateIdle, 0xFF},
|
||||
{64, 1, &OffsetPulseWave, StateMachine::UpdateWave, 0xFF},
|
||||
};
|
||||
|
||||
const Macro macDemoFlicker = {
|
||||
{64, 1, &InitSlopeWave, StateMachine::UpdateWave, 0xFF},
|
||||
{32, 1, StateMachine::UpdateFlicker, 0xFF},
|
||||
};
|
||||
}
|
||||
|
||||
void LightingTask() {
|
||||
ESP_LOGI(TAG, "Start Lighting");
|
||||
|
||||
@@ -376,6 +364,70 @@ void LightingTask() {
|
||||
}
|
||||
fos::Task::delayMs(100);
|
||||
}
|
||||
|
||||
|
||||
// ESP_LOGI(TAG, "Start Lighting");
|
||||
|
||||
// static I2cMaster master(I2C_NUM_0, GPIO_NUM_10, GPIO_NUM_11);
|
||||
// static PmwExpanderPca9685 pca9685(master);
|
||||
// PmwExpanderPca9685::GrayValues values;
|
||||
|
||||
// AddressableLeRtz ledBar(GPIO_NUM_15, AddressableLeRtz::Type::Rgb, 6);
|
||||
// std::vector<Color> pictoSpots(6);
|
||||
// for (auto &&led : pictoSpots) {
|
||||
// led.set(0, 0, 0);
|
||||
// }
|
||||
|
||||
// auto const &colorSource = activeState.color;
|
||||
// std::array<Effect::EffectProcessor, 6> processors{
|
||||
// Effect::EffectProcessor(8),
|
||||
// Effect::EffectProcessor(8),
|
||||
// Effect::EffectProcessor(8),
|
||||
// Effect::EffectProcessor(8),
|
||||
// Effect::EffectProcessor(8),
|
||||
// Effect::EffectProcessor(8)};
|
||||
|
||||
// processors[0].setEffect(Effect::macDemoStart, &colorSource, 16);
|
||||
// processors[1].setEffect(Effect::macDemoStart, &colorSource, 32);
|
||||
// processors[2].setEffect(Effect::macDemoPulse, &colorSource, 48);
|
||||
// processors[3].setEffect(Effect::macDemoPulse, &colorSource, 64);
|
||||
// processors[4].setEffect(Effect::macStartFlicker, &colorSource, 80);
|
||||
// processors[5].setEffect(Effect::macStartIdle, &colorSource, 96);
|
||||
|
||||
// int idx = 0;
|
||||
// values.fill(0);
|
||||
// while (true) {
|
||||
// values[0] = activeState.color.getRed() * 257;
|
||||
// values[1] = activeState.color.getGreen() * 257;
|
||||
// values[2] = activeState.color.getBlue() * 257;
|
||||
// pca9685.sendImage(values);
|
||||
|
||||
// for (size_t i = 0; i < 600; i++) {
|
||||
// Task::delayMs(20);
|
||||
// for (size_t i = 0; i < pictoSpots.size(); i++) {
|
||||
// pictoSpots[i] = processors[i].tick();
|
||||
// }
|
||||
// ledBar.send(pictoSpots);
|
||||
// }
|
||||
|
||||
// processors[1].setEffect(Effect::macDark, &colorSource, 32);
|
||||
// processors[2].setEffect(Effect::macDark, &colorSource, 48);
|
||||
// processors[3].setEffect(Effect::macDark, &colorSource, 64);
|
||||
// processors[4].setEffect(Effect::macDark, &colorSource, 80);
|
||||
|
||||
// for (size_t i = 0; i < 50; i++) {
|
||||
// Task::delayMs(20);
|
||||
// for (size_t i = 0; i < pictoSpots.size(); i++) {
|
||||
// pictoSpots[i] = processors[i].tick();
|
||||
// }
|
||||
// ledBar.send(pictoSpots);
|
||||
// }
|
||||
|
||||
// processors[1].setEffect(Effect::macDemoStart, &colorSource, 32);
|
||||
// processors[2].setEffect(Effect::macDemoPulse, &colorSource, 48);
|
||||
// processors[3].setEffect(Effect::macDemoPulse, &colorSource, 64);
|
||||
// processors[4].setEffect(Effect::macStartFlicker, &colorSource, 80);
|
||||
// }
|
||||
}
|
||||
|
||||
void MovementTask() {
|
||||
@@ -415,6 +467,108 @@ void MovementTask() {
|
||||
while (true) {
|
||||
fos::Task::delayMs(100);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ESP_LOGI(TAG, "Start Stepper");
|
||||
// StepperDriverTb6612::Pins stepperPins{
|
||||
// LEDC_TIMER_0,
|
||||
// LEDC_CHANNEL_0,
|
||||
// GPIO_NUM_23,
|
||||
// {GPIO_NUM_22, GPIO_NUM_21},
|
||||
// LEDC_CHANNEL_1,
|
||||
// GPIO_NUM_20,
|
||||
// {GPIO_NUM_19, GPIO_NUM_18},
|
||||
// };
|
||||
// constexpr int MicroSteps = 32;
|
||||
// StepperDriverTb6612 stepperDriver(stepperPins, MicroSteps);
|
||||
// stepperDriver.setPos(0);
|
||||
|
||||
// StepperMotor::Config stepperCfg{1.8F, MicroSteps};
|
||||
// InputPort initSens(GPIO_NUM_3);
|
||||
// initSens.setLogic(GpioPort::Logic::Inverted);
|
||||
// StepperMotor stepper(stepperCfg, stepperDriver, initSens);
|
||||
|
||||
// ESP_LOGI(TAG, "Find Home");
|
||||
|
||||
// stepper.findRef();
|
||||
// ESP_LOGI(TAG, "Fist Position is %f.2", stepper.getScaledPos() * 6);
|
||||
// Task::delayMs(1000);
|
||||
|
||||
// AddressableLeRtz ledRing(GPIO_NUM_9, AddressableLeRtz::Type::Rgb, 12);
|
||||
// std::vector<Color> ledStrip(12);
|
||||
// for (auto &&led : ledStrip) {
|
||||
// led.set(0, 0, 0);
|
||||
// }
|
||||
|
||||
// uint32_t ledPos = 0;
|
||||
// ledStrip[0].set(
|
||||
// activeState.color.getRed(),
|
||||
// activeState.color.getGreen(),
|
||||
// activeState.color.getBlue(),
|
||||
// 0);
|
||||
// ledRing.send(ledStrip);
|
||||
|
||||
// while (true) {
|
||||
// ESP_LOGD(TAG, "Waiting for command");
|
||||
// auto cmd = commandQueue.dequeue();
|
||||
// if (cmd->type == MoveType::Step) {
|
||||
// if (stepper.isIdle()) {
|
||||
// auto delta = cmd->deltaPic;
|
||||
// auto profile = cmd->profile;
|
||||
|
||||
// for (auto &&led : ledStrip) {
|
||||
// led.set(0, 0, 0);
|
||||
// }
|
||||
// ledPos = (ledPos + delta) % 6;
|
||||
// activeState.pictogram = ledPos;
|
||||
|
||||
// ledStrip[ledPos * 2].set(
|
||||
// cmd->color.getRed(),
|
||||
// cmd->color.getGreen(),
|
||||
// cmd->color.getBlue(),
|
||||
// 0);
|
||||
// ledRing.send(ledStrip);
|
||||
// MqttClient::publishPosition(ledPos);
|
||||
|
||||
// delta = std::min<uint8_t>(delta, 7);
|
||||
// Syslog::logv(Syslog::Severity::Notice, "Running Stepper by %i steps with prof=%i a=%.2f w=%.2f", delta, profile, activeState.accel, activeState.speed);
|
||||
// stepper.moveBy(delta * std::numbers::pi / 3,
|
||||
// profile, activeState.accel, activeState.speed);
|
||||
// }
|
||||
// } else if (cmd->type == MoveType::AllPictograms) {
|
||||
// activeState.pictogram = -1;
|
||||
// stepper.findRef();
|
||||
// Task::delayMs(1000);
|
||||
// for (size_t i = 0; i < 6; i++) {
|
||||
// for (auto &&led : ledStrip) {
|
||||
// led.set(0, 0, 0);
|
||||
// }
|
||||
// ledStrip[i * 2].set(0, 0, 16);
|
||||
// ledRing.send(ledStrip);
|
||||
// stepper.moveBy(std::numbers::pi / 3);
|
||||
// while (!stepper.isIdle()) {
|
||||
// Task::delayMs(100);
|
||||
// }
|
||||
// ESP_LOGI(TAG, "Position is %f.2", stepper.getScaledPos() * 6);
|
||||
// }
|
||||
// } else if (cmd->type == MoveType::Arbitrary) {
|
||||
// activeState.pictogram = -1;
|
||||
// ESP_LOGI(TAG, "Full Turn");
|
||||
// stepper.demoFullTurn();
|
||||
// Task::delayMs(4000);
|
||||
|
||||
// while (true) {
|
||||
// if (stepper.isIdle()) {
|
||||
// ESP_LOGI(TAG, "Position is %f.2", stepper.getScaledPos() * 6);
|
||||
// Task::delayMs(500);
|
||||
// stepper.createDemoProfile();
|
||||
// }
|
||||
// Task::delayMs(20);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
void IoTest()
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* @file watchMain.hpp
|
||||
* @author Gustice
|
||||
*
|
||||
* @copyright Copyright (c) 2024
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_eth_driver.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "esp_private/wifi.h"
|
||||
#include "ethernet_init.h"
|
||||
#include "esp_netif.h"
|
||||
#include "esp_eth.h"
|
||||
|
||||
// Component header
|
||||
#include "Task.hpp"
|
||||
#include "PwmExpanderPca9685.hpp"
|
||||
#include "StepperDrv8833.hpp"
|
||||
#include "stepperMotor.hpp"
|
||||
#include "cliWrapper.hpp"
|
||||
#include "udpSockets.hpp"
|
||||
#include "tcpSockets.hpp"
|
||||
#include "Mutex.hpp"
|
||||
#include "Queue.hpp"
|
||||
#include "Semaphore.hpp"
|
||||
#include "Task.hpp"
|
||||
#include "Artnet.h"
|
||||
#include "Processor.hpp"
|
||||
|
||||
|
||||
// #include "esp_chip_info.h"
|
||||
// #include "esp_flash.h"
|
||||
// #include "esp_log.h"
|
||||
// #include "esp_netif.h"
|
||||
// #include "esp_ota_ops.h"
|
||||
// #include "esp_partition.h"
|
||||
// #include "esp_random.h"
|
||||
// #include "esp_system.h"
|
||||
// #include "esp_vfs_fat.h"
|
||||
// #include "esp_vfs_semihost.h"
|
||||
// #include "esp_wifi.h"
|
||||
// #include "fileSystem.hpp"
|
||||
// #include "freertos/FreeRTOS.h"
|
||||
// #include "freertos/task.h"
|
||||
// #include "gpTimer.hpp"
|
||||
// #include "gpioPort.hpp"
|
||||
// #include "i2cPort.hpp"
|
||||
// #include "lwip/apps/netbiosns.h"
|
||||
// #include "mdns.h"
|
||||
// #include "mqttClient.hpp"
|
||||
// #include "nlohmann/json.hpp"
|
||||
// #include "nvsFunctions.hpp"
|
||||
// #include "pwmExpanderPca9685.hpp"
|
||||
// #include "pwmPort.hpp"
|
||||
// #include "rmtPort.hpp"
|
||||
// #include "sdkconfig.h"
|
||||
// #include "soc/soc_caps.h"
|
||||
// #include "stepperMotor.hpp"
|
||||
// #include "stepperTB6612.hpp"
|
||||
// #include "stepperDrv8833.hpp"
|
||||
// #include "string.h"
|
||||
// #include "systemFunctions.hpp"
|
||||
// #include "tcpSockets.hpp"
|
||||
// #include "uartPort.hpp"
|
||||
// #include "udpSockets.hpp"
|
||||
// #include "webServer.hpp"
|
||||
// #include "wifiFunctions.hpp"
|
||||
// #include <inttypes.h>
|
||||
// #include <string.h>
|
||||
// #include <sys/param.h>
|
||||
// #include <unistd.h>
|
||||
// #include <cmath>
|
||||
|
||||
Reference in New Issue
Block a user