init commit

This commit is contained in:
mk
2025-12-01 06:47:16 -03:00
commit d6faf3e062
19 changed files with 2116 additions and 0 deletions

334
.clang-form Normal file
View File

@@ -0,0 +1,334 @@
---
Language: Cpp
AccessModifierOffset: -1
AlignAfterOpenBracket: Align
AlignArrayOfStructures: None
AlignConsecutiveAssignments:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: true
AlignConsecutiveBitFields:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveDeclarations:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: true
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveMacros:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveShortCaseStatements:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCaseArrows: false
AlignCaseColons: false
AlignConsecutiveTableGenBreakingDAGArgColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveTableGenCondOperatorColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveTableGenDefinitionColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignEscapedNewlines: Left
AlignOperands: Align
AlignTrailingComments:
Kind: Always
OverEmptyLines: 0
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowBreakBeforeNoexceptSpecifier: Never
AllowShortBlocksOnASingleLine: Never
AllowShortCaseExpressionOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: false
AllowShortCompoundRequirementOnASingleLine: true
AllowShortEnumsOnASingleLine: true
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: WithoutElse
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: true
AllowShortNamespacesOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AttributeMacros:
- __capability
- absl_nonnull
- absl_nullable
- absl_nullability_unknown
BinPackArguments: true
BinPackLongBracedList: true
BinPackParameters: BinPack
BitFieldColonSpacing: Both
BracedInitializerIndentWidth: -1
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterExternBlock: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakAdjacentStringLiterals: true
BreakAfterAttributes: Leave
BreakAfterJavaFieldAnnotations: false
BreakAfterReturnType: None
BreakArrays: true
BreakBeforeBinaryOperators: None
BreakBeforeConceptDeclarations: Always
BreakBeforeBraces: Attach
BreakBeforeInlineASMColon: OnlyMultiline
BreakBeforeTemplateCloser: false
BreakBeforeTernaryOperators: true
BreakBinaryOperations: Never
BreakConstructorInitializers: BeforeColon
BreakFunctionDefinitionParameters: false
BreakInheritanceList: BeforeColon
BreakStringLiterals: true
BreakTemplateDeclarations: Yes
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
EnumTrailingComma: Leave
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IfMacros:
- KJ_IF_MAYBE
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^<ext/.*\.h>'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '^<.*\.h>'
Priority: 1
SortPriority: 0
CaseSensitive: false
- Regex: '^<.*'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '.*'
Priority: 3
SortPriority: 0
CaseSensitive: false
IncludeIsMainRegex: '([-_](test|unittest))?$'
IncludeIsMainSourceRegex: ''
IndentAccessModifiers: false
IndentCaseBlocks: false
IndentCaseLabels: true
IndentExportBlock: true
IndentExternBlock: AfterExternBlock
IndentGotoLabels: true
IndentPPDirectives: None
IndentRequiresClause: true
IndentWidth: 2
IndentWrappedFunctionNames: false
InsertBraces: false
InsertNewlineAtEOF: false
InsertTrailingCommas: None
IntegerLiteralSeparator:
Binary: 0
BinaryMinDigits: 0
Decimal: 0
DecimalMinDigits: 0
Hex: 0
HexMinDigits: 0
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLines:
AtEndOfFile: false
AtStartOfBlock: false
AtStartOfFile: true
KeepFormFeed: false
LambdaBodyIndentation: Signature
LineEnding: DeriveLF
MacroBlockBegin: ''
MacroBlockEnd: ''
MainIncludeChar: Quote
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Never
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
OneLineFormatOffRegex: ''
PackConstructorInitializers: NextLine
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakBeforeMemberAccess: 150
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakOpenParenthesis: 0
PenaltyBreakScopeResolution: 500
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyIndentedWhitespace: 0
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
PPIndentWidth: -1
QualifierAlignment: Leave
RawStringFormats:
- Language: Cpp
Delimiters:
- cc
- CC
- cpp
- Cpp
- CPP
- 'c++'
- 'C++'
CanonicalDelimiter: ''
BasedOnStyle: google
- Language: TextProto
Delimiters:
- pb
- PB
- proto
- PROTO
EnclosingFunctions:
- EqualsProto
- EquivToProto
- PARSE_PARTIAL_TEXT_PROTO
- PARSE_TEST_PROTO
- PARSE_TEXT_PROTO
- ParseTextOrDie
- ParseTextProtoOrDie
- ParseTestProto
- ParsePartialTestProto
CanonicalDelimiter: pb
BasedOnStyle: google
ReferenceAlignment: Pointer
ReflowComments: Always
RemoveBracesLLVM: false
RemoveEmptyLinesInUnwrappedLines: false
RemoveParentheses: Leave
RemoveSemicolon: false
RequiresClausePosition: OwnLine
RequiresExpressionIndentation: OuterScope
SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 1
SkipMacroDefinitionBody: false
SortIncludes:
Enabled: true
IgnoreCase: false
SortJavaStaticImport: Before
SortUsingDeclarations: LexicographicNumeric
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterOperatorKeyword: false
SpaceAfterTemplateKeyword: true
SpaceAroundPointerQualifiers: Default
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeJsonColon: false
SpaceBeforeParens: ControlStatements
SpaceBeforeParensOptions:
AfterControlStatements: true
AfterForeachMacros: true
AfterFunctionDefinitionName: false
AfterFunctionDeclarationName: false
AfterIfMacros: true
AfterNot: false
AfterOverloadedOperator: false
AfterPlacementOperator: true
AfterRequiresInClause: false
AfterRequiresInExpression: false
BeforeNonEmptyParentheses: false
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpaceInEmptyBlock: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: Never
SpacesInContainerLiterals: true
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParens: Never
SpacesInParensOptions:
ExceptDoubleParentheses: false
InCStyleCasts: false
InConditionalStatements: false
InEmptyParentheses: false
Other: false
SpacesInSquareBrackets: false
Standard: Auto
StatementAttributeLikeMacros:
- Q_EMIT
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TableGenBreakInsideDAGArg: DontBreak
TabWidth: 8
UseTab: Never
VerilogBreakBetweenInstancePorts: true
WhitespaceSensitiveMacros:
- BOOST_PP_STRINGIZE
- CF_SWIFT_NAME
- NS_SWIFT_NAME
- PP_STRINGIZE
- STRINGIZE
WrapNamespaceBodyWithEmptyLines: Leave
...

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
.pio
.cache

0
.zed/settings.json Normal file
View File

50
.zed/tasks.json Normal file
View File

@@ -0,0 +1,50 @@
// Project tasks configuration. See https://zed.dev/docs/tasks for documentation.
//
// Example:
[
{
"label": "Upload && Monitor",
"command": "pio run -t upload --upload-port /dev/ttyUSB0 && pio device monitor --port /dev/ttyUSB0",
//"args": [],
// Env overrides for the command, will be appended to the terminal's environment from the settings.
"env": { "foo": "bar" },
"use_new_terminal": false,
"allow_concurrent_runs": false,
"reveal": "always",
"reveal_target": "dock",
"hide": "never",
"shell": "system",
"show_summary": true,
"show_command": true
},
{
"label": "Upload",
"command": "pio run -t upload --upload-port /dev/ttyUSB0",
//"args": [],
// Env overrides for the command, will be appended to the terminal's environment from the settings.
"env": { "foo": "bar" },
"use_new_terminal": false,
"allow_concurrent_runs": false,
"reveal": "always",
"reveal_target": "dock",
"hide": "on_success",
"shell": "system",
"show_summary": true,
"show_command": true
},
{
"label": "Monitor",
"command": "pio device monitor --port /dev/ttyUSB0",
//"args": [],
// Env overrides for the command, will be appended to the terminal's environment from the settings.
"env": { "foo": "bar" },
"use_new_terminal": false,
"allow_concurrent_runs": false,
"reveal": "always",
"reveal_target": "dock",
"hide": "never",
"shell": "system",
"show_summary": true,
"show_command": true
}
]

0
README.md Normal file
View File

16
TODO.md Normal file
View File

@@ -0,0 +1,16 @@
[X]ISHYGDDT pixels
[X]i like constant/unblinking or soft/slow fade
red+yellow
[X] Make patterns transition from time to time
[X] red+white i like bc peppermint
[X] i also like ALL GREEN despite it feeling like a shitpost
[X] a soft all white is also comfy
[X] Standard Christmas colors
[] Mosskoi color pattern

1058
compile_commands.json Normal file

File diff suppressed because one or more lines are too long

37
include/README Normal file
View File

@@ -0,0 +1,37 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the convention is to give header files names that end with `.h'.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

29
include/base_pattern.h Normal file
View File

@@ -0,0 +1,29 @@
#ifndef BASE_PATTERN_H
#define BASE_PATTERN_H
#include <Arduino.h>
#include <FastLED.h>
class BasePattern {
public:
BasePattern() : timeToProcess(2000), lastProcessed(millis()) {};
virtual ~BasePattern() = default;
// Called once at start
virtual void init() { Serial.printf("BasePattern::init\n"); };
// Called repeatedly. Return true to request exit, false to continue.
virtual void loop() { Serial.printf("BasePattern::loop\n"); };
// Called once at end
virtual void exit() { Serial.printf("BasePattern::exit\n"); };
void show() {
lastProcessed = millis();
FastLED.show();
}
bool shouldProcess() { return millis() - lastProcessed > timeToProcess; }
unsigned long timeToProcess, lastProcessed;
};
#endif // BASE_PATTERN_H

36
include/cLED.h Normal file
View File

@@ -0,0 +1,36 @@
#ifndef cHSV_H
#define cHSV_H
#include <FastLED.h>
#include <cstdint>
class cLED {
public:
int h;
int s;
int v;
uint8_t h8_t;
uint8_t s8_t;
uint8_t v8_t;
cLED() : h(0), s(0), v(0), h8_t(0), s8_t(0), v8_t(0) {};
// HSV as 360,100,100
cLED(int hue, int sat, int val) : h(hue), s(sat), v(val) {
h = (h > 360) ? 255 : h;
s = (s > 100) ? 255 : s;
v = (v > 100) ? 255 : v;
h8_t = 255 * (h / 360.0f);
s8_t = 255 * (s / 100.0f);
v8_t = 255 * (v / 100.0f);
};
CHSV asHSV() {
h8_t = 255 * (h / 360.0f);
s8_t = 255 * (s / 100.0f);
v8_t = 255 * (v / 100.0f);
return CHSV(h8_t, s8_t, v8_t);
}
};
#endif

8
include/hsv_colours.h Normal file
View File

@@ -0,0 +1,8 @@
#include <FastLED.h>
namespace HSVColor {
CHSV Green = CHSV(120, 2, 2);
CHSV Red = CHSV(0, 2, 20);
CHSV Cyan = CHSV(200, 70, 2);
} // namespace HSVColor

90
include/patterns.h Normal file
View File

@@ -0,0 +1,90 @@
#ifndef PATTERNS_H
#define PATTERNS_H
#include "base_pattern.h"
#include "cLED.h"
class hueCheck : public BasePattern {
public:
hueCheck() { timeToProcess = 200; };
~hueCheck() {};
void init() override { offLEDPos = 0; };
void exit() override {};
void loop();
int offLEDPos;
};
class ISHYGDDT : public BasePattern {
public:
ISHYGDDT() { timeToProcess = 4000; };
~ISHYGDDT() {};
void init();
void exit() override {};
void loop();
const float m_deepBluePerc = 0.5f;
const float m_lightBluePerc = 0.2f;
const float m_brownPerc = 0.1f;
const float m_peachPerc = 0.2f;
};
class RedYellowFade : public BasePattern {
public:
RedYellowFade() { timeToProcess = 100; };
~RedYellowFade() {};
void init();
void exit() override {};
void loop();
cLED yellow;
cLED red;
};
class Peppermint : public BasePattern {
public:
Peppermint() { timeToProcess = 7000; };
~Peppermint() {};
void init();
void exit() override {};
void loop();
cLED white;
cLED red;
};
class Bugs : public BasePattern {
public:
Bugs() { timeToProcess = 120; };
~Bugs() {};
void init();
void exit() override {};
void loop();
};
class HolyNight : public BasePattern {
public:
HolyNight() { timeToProcess = 10; };
~HolyNight() {};
void init();
void exit() override {};
void loop();
int breathValue = 0;
bool breathIn = true;
};
class Standard : public BasePattern {
public:
Standard() { timeToProcess = 10; };
~Standard() {};
void init();
void exit() override {};
void loop();
};
class DriveThru : public BasePattern {
public:
DriveThru() { timeToProcess = 250; };
~DriveThru() {};
void init();
void exit() override {};
void loop();
};
#endif

17
include/state_machine.h Normal file
View File

@@ -0,0 +1,17 @@
#ifndef STATE_MACHINE_H
#define STATE_MACHINE_H
#include "base_pattern.h"
class StateMachine {
public:
StateMachine();
void changeState(BasePattern *newState);
void processState();
private:
BasePattern *currentPattern;
};
#endif

46
lib/README Normal file
View File

@@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into the executable file.
The source code of each library should be placed in a separate directory
("lib/your_library_name/[Code]").
For example, see the structure of the following example libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional. for custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
Example contents of `src/main.c` using Foo and Bar:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
The PlatformIO Library Dependency Finder will find automatically dependent
libraries by scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

15
platformio.ini Normal file
View File

@@ -0,0 +1,15 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
lib_deps = fastled/FastLED@^3.10.3

61
src/main.cpp Normal file
View File

@@ -0,0 +1,61 @@
#include "base_pattern.h"
#include "crgb.h"
#include "esp32-hal.h"
#include "patterns.h"
#include "state_machine.h"
#include <Arduino.h>
#include <FastLED.h>
#include <cstdlib>
#define LED_COUNT 103
#define DATA_PIN 25
#define BAUD_RATE 9600
#define PATTERN_COUNT 6
#define TIME_TO_CHANGE_PATTERN_MS 1000 * 120
unsigned long lastTimeChanged = 0;
extern CRGB leds[LED_COUNT];
static BasePattern *getRandomPattern() {
int newPatternNum = std::rand() % PATTERN_COUNT;
switch (newPatternNum) {
case 0:
return new hueCheck;
case 1:
return new RedYellowFade;
case 2:
return new ISHYGDDT;
case 3:
return new HolyNight;
case 4:
return new Bugs;
case 5:
return new Peppermint;
case 6:
return new Standard;
default:
break;
}
return new hueCheck();
}
StateMachine sm;
// Define the array of leds
void setup() {
Serial.begin(9600);
FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, LED_COUNT);
delay(100);
FastLED.setBrightness(100);
delay(100);
sm.changeState(getRandomPattern());
delay(100);
}
void loop() {
sm.processState();
unsigned long time = millis();
if (time - lastTimeChanged > TIME_TO_CHANGE_PATTERN_MS) {
sm.changeState(getRandomPattern());
lastTimeChanged = time;
}
}

290
src/patterns.cpp Normal file
View File

@@ -0,0 +1,290 @@
#include "patterns.h"
#include "crgb.h"
#include <Arduino.h>
#include <FastLED.h>
#include <cLED.h>
#include <cstdint>
#include <cstdlib>
#define LED_COUNT 103
CRGB leds[LED_COUNT];
cLED cleds[LED_COUNT];
/**
* Converts standard ranges of HSV to 8 bits
*/
static CHSV convertHSVtoByte(int h, uint8_t s, uint8_t v) {
h = (h > 360) ? 255 : h;
s = (s > 100) ? 255 : s;
v = (v > 100) ? 255 : v;
return CHSV(255 * (h / 360.0f), 255 * (s / 100.0f), 255 * (v / 100.0f));
}
/**
* hueCheck
*/
void hueCheck::loop() {
if (!shouldProcess())
return;
for (int i = 0; i < LED_COUNT; i++) {
uint h = 255 * (i / 100.0);
leds[i] = CHSV(h, 255, 255);
}
leds[offLEDPos++ % LED_COUNT] = CHSV(255, 0, 0);
show();
}
/**
* ISHYGDDT
*/
void ISHYGDDT::init() {
if (m_brownPerc + m_deepBluePerc + m_lightBluePerc + m_peachPerc != 1) {
Serial.printf("ISHYGDDT::init() percentages do not make sense");
}
int numBrown = LED_COUNT * m_brownPerc;
int numDeepBlue = LED_COUNT * m_deepBluePerc;
int numLightBlue = LED_COUNT * m_lightBluePerc;
int numPeach = LED_COUNT * m_peachPerc;
CHSV brown = convertHSVtoByte(10, 100, 70);
CHSV deepBlue = convertHSVtoByte(230, 56, 77);
CHSV lightBlue = convertHSVtoByte(229, 30, 98);
CHSV peach = convertHSVtoByte(10, 39, 87);
CHSV off = convertHSVtoByte(0, 0, 0);
for (int i = 0; i < LED_COUNT; i++) {
if (numBrown >= 0) {
leds[i] = brown;
numBrown--;
} else if (numDeepBlue >= 0) {
leds[i] = deepBlue;
numDeepBlue--;
} else if (numLightBlue >= 0) {
leds[i] = lightBlue;
numLightBlue--;
} else if (numPeach >= 0) {
leds[i] = peach;
numPeach--;
}
}
}
void ISHYGDDT::loop() {
if (!shouldProcess())
return;
for (int i = 0; i < LED_COUNT; i++) {
int swapPos1 = std::rand() % LED_COUNT;
int swapPos2 = std::rand() % LED_COUNT;
CRGB auxSwap;
auxSwap = leds[swapPos1];
leds[swapPos1] = leds[swapPos2];
leds[swapPos2] = auxSwap;
}
show();
}
/**
* RedYellowFade
*/
void RedYellowFade::init() {
yellow = cLED(40, 100, 100);
red = cLED(0, 100, 100);
for (int i = 0; i < LED_COUNT; i++) {
int paintRed = std::rand() % 2;
if (paintRed)
cleds[i] = red;
else
cleds[i] = yellow;
leds[i] = cleds[i].asHSV();
}
}
void RedYellowFade::loop() {
if (!shouldProcess())
return;
for (int i = 0; i < LED_COUNT; i++) {
if (!cleds[i].v) {
int paintRed = rand() % 2;
if (paintRed)
cleds[i] = red;
else
cleds[i] = yellow;
cleds[i].v = 100;
}
cleds[i].v -= (rand() % 4);
cleds[i].v = cleds[i].v < 0 ? 0 : cleds[i].v;
leds[i] = cleds[i].asHSV();
}
show();
}
/**
* Peppermint
*/
void Peppermint::init() {
for (int i = 0; i < LED_COUNT; i++) {
int paintRed = std::rand() % 2;
if (paintRed) {
cleds[i] = cLED(0, 100, 100);
} else {
cleds[i] = cLED(0, 0, 100);
}
leds[i] = cleds[i].asHSV();
show();
}
}
void Peppermint::loop() {
if (!shouldProcess())
return;
CRGB posChangedLeds[LED_COUNT];
for (int i = 0; i < (std::rand() % LED_COUNT) + 20; i++) {
CRGB last = leds[LED_COUNT - 1];
for (int j = 0; j < LED_COUNT - 1; j++) {
posChangedLeds[j + 1] = leds[j];
}
posChangedLeds[0] = last;
for (int j = 0; j < LED_COUNT; j++)
leds[j] = posChangedLeds[j];
FastLED.show();
delay(100);
}
show();
}
/**
* Bugs
*/
void Bugs::init() {
for (int i = 0; i < LED_COUNT; i++) {
cleds[i] = cLED(110 + (20 - std::rand() % 40), // Hue
70 + (20 - std::rand() % 60), // Saturation
90 + (10 - std::rand() % 20)); // Value
leds[i] = cleds[i].asHSV();
}
show();
}
void Bugs::loop() {
if (!shouldProcess())
return;
for (int i = 0; i < LED_COUNT; i++) {
int nH, nS, nV;
nH = cleds[i].h;
nS = cleds[i].s + (10 - rand() % 20);
nV = cleds[i].v + (5 - rand() % 10);
cLED newBug = cLED(nH, nS, nV);
leds[i] = newBug.asHSV();
}
show();
}
/**
* HolyNight
*/
void HolyNight::init() {
for (int i = 0; i < LED_COUNT; i++) {
cleds[i] = cLED(0, // Hue
0, // Saturation
50 + (10 - std::rand() % 20)); // Value
leds[i] = cleds[i].asHSV();
}
show();
}
void HolyNight::loop() {
if (!shouldProcess())
return;
if (breathIn) {
breathValue++;
if (breathValue >= 70)
breathIn = !breathIn;
} else {
breathValue--;
if (breathValue <= -70)
breathIn = !breathIn;
}
for (int i = 0; i < LED_COUNT; i++) {
leds[i] = CHSV(0, 0, 120 + breathValue);
}
show();
}
/**
* Standard
*/
void Standard::init() {
cLED red = cLED(5, 100, 100);
cLED green = cLED(60, 100, 100);
cLED yellow = cLED(120, 100, 100);
cLED blue = cLED(230, 100, 100);
cLED *colors[] = {&red, &green, &yellow, &blue};
for (int i = 0; i < 4; i++) {
for (int j = 0; j < (int)(LED_COUNT * 0.25); j++) {
cleds[(int(LED_COUNT * 0.25) * i) + j] = *colors[i];
leds[(int(LED_COUNT * 0.25) * i) + j] =
cleds[(int(LED_COUNT * 0.25) * i) + j].asHSV();
}
}
for (int i = 0; i < LED_COUNT; i++) {
int swapPos1 = std::rand() % LED_COUNT;
int swapPos2 = std::rand() % LED_COUNT;
CRGB auxSwap;
auxSwap = leds[swapPos1];
leds[swapPos1] = leds[swapPos2];
leds[swapPos2] = auxSwap;
}
show();
}
void Standard::loop() {
if (!shouldProcess())
return;
show();
}
/**
* DriveThru
*/
void DriveThru::init() {
cLED pink = cLED(300, 75, 95);
cLED orange = cLED(7, 75, 95);
cLED green = cLED(127, 75, 95);
cLED blue = cLED(187, 75, 95);
cLED *colors[] = {&pink, &orange, &green, &blue};
for (int i = 0; i < 4; i++) {
for (int j = 0; j < (int)(LED_COUNT * 0.25); j++) {
cleds[(int(LED_COUNT * 0.25) * i) + j] = *colors[i];
leds[(int(LED_COUNT * 0.25) * i) + j] =
cleds[(int(LED_COUNT * 0.25) * i) + j].asHSV();
}
}
for (int i = 0; i < LED_COUNT; i++) {
int swapPos1 = std::rand() % LED_COUNT;
int swapPos2 = std::rand() % LED_COUNT;
cLED auxSwap;
auxSwap = cleds[swapPos1];
cleds[swapPos1] = cleds[swapPos2];
cleds[swapPos2] = auxSwap;
leds[i] = CHSV(0, 0, 0);
}
show();
}
void DriveThru::loop() {
if (!shouldProcess())
return;
for (int i = 0; i < LED_COUNT; i++) {
}
show();
}

16
src/state_machine.cpp Normal file
View File

@@ -0,0 +1,16 @@
#include "state_machine.h"
#include "base_pattern.h"
#include <Arduino.h>
StateMachine::StateMachine() {}
void StateMachine::changeState(BasePattern *newState) {
if (currentPattern) {
currentPattern->exit();
delete currentPattern;
}
currentPattern = newState;
currentPattern->init();
}
void StateMachine::processState() { currentPattern->loop(); }

11
test/README Normal file
View File

@@ -0,0 +1,11 @@
This directory is intended for PlatformIO Test Runner and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PlatformIO Unit Testing:
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html