#include <RingBufCPP.h>
#include <RingBufHelpers.h>
#include <FastLED.h>
// command word: 0100 0000 0000 0011 0000 001x // x is rumble control
TaskHandle_t GCDataCollectorTask;
RingBufCPP<bool, 64> receiveBuffer;
//FASTLED Parameters
#define NUM_LEDS 16
#define LED_PIN 14 // pin the underglow led strip is attached to
#define P1_PIN 32 //pin to read the controller data for Player 1
//Rainbow Effect Parameters
uint8_t gHue = 0; // rotating "base color" used by many of the patterns
uint8_t gHueSpeed = 1; // default speed of the rainbow rotation animation
uint8_t ledBrightness = 200; // default low brightness of the underglow led strip
CRGB Leds[NUM_LEDS];
CHSV snakeHSVColor;
CHSV startupHSVColor;
// int64_t bitStart;
// int64_t bitEdge;
// void IRAM_ATTR ISRGCBitReceivedRISE() {
// bitEdge = esp_timer_get_time();
// }
// void IRAM_ATTR ISRGCBitReceivedFALL() {
// if ((bitEdge - bitStart) < 2) {
// receiveBuffer.add(1);
// } else {
// receiveBuffer.add(0);
// }
// bitStart = esp_timer_get_time();
// }
// void IRAM_ATTR ISRGCBitReceived() { //pick rise or fall
// digitalWrite(19, 1);
// if (digitalRead(P1_PIN))
// ISRGCBitReceivedRISE();
// else
// ISRGCBitReceivedFALL();
// }
void setup() {
//Serial.begin(115200);
//pinMode(P1_PIN, INPUT);
//pinMode(19, OUTPUT);
//attachInterrupt(P1_PIN, ISRGCBitReceived, CHANGE);
//attachInterrupt(P1_PIN, ISRGCBitReceivedFALL, FALLING);
FastLED.addLeds<NEOPIXEL, LED_PIN>(Leds, NUM_LEDS);
FastLED.setBrightness(ledBrightness);
//StartupLightTest();
// xTaskCreatePinnedToCore(
// GCCollectData, /* Function to implement the task */
// "CollectGCData", /* Name of the task */
// 10000, /* Stack size in words */
// NULL, /* Task input parameter */
// 0, /* Priority of the task */
// &GCDataCollectorTask, /* Task handle. */
// 0); /* Core where the task should run */
//Gamecube Purple
startupHSVColor.hue = 190;
startupHSVColor.val = ledBrightness;
startupHSVColor.sat = 255;
//Initial Snake Color
snakeHSVColor.hue = random(0, 255);
snakeHSVColor.val = ledBrightness;
snakeHSVColor.sat = 255;
fill_solid(Leds, NUM_LEDS, CRGB::Black);
FastLED.show();
//wait for GC to start displaying an image
delay(2200);
}
bool inStartup = true;
bool inStartupCubeGrow = true;
int startupAnimationIndex = 0;
bool fadeUp = true;
int fadeMaxBrightness = 255;
int fadeMinBrightness = 0;
int fadeUpLengthMS = 200;
int fadeDownLengthMS = 750;
int currentMode = 0;
int snakeIndex = 0;
void loop() {
if (inStartup) {
if (inStartupCubeGrow) {
EVERY_N_MILLISECONDS(215) {
Leds[NUM_LEDS - startupAnimationIndex] = startupHSVColor;
FastLED.show();
startupAnimationIndex++;
if (startupAnimationIndex > NUM_LEDS)
inStartupCubeGrow = false;
}
} else {
if (fadeUp) {
//calculate fadeup steps
int upSteps = fadeMaxBrightness - ledBrightness;
int fadeUpStepDelay = fadeUpLengthMS / upSteps;
EVERY_N_MILLISECONDS(fadeUpStepDelay) {
startupHSVColor.val += 1;
for (int i = 0; i < NUM_LEDS; i++) {
Leds[i] = startupHSVColor;
}
FastLED.show();
}
if (startupHSVColor.val >= 255)
fadeUp = false;
} else {
//fading down
//calculate fadedown steps
int downSteps = ledBrightness - fadeMinBrightness;
int fadeDownStepDelay = fadeDownLengthMS / downSteps;
EVERY_N_MILLISECONDS(fadeDownStepDelay) {
startupHSVColor.val -= 1;
for (int i = 0; i < NUM_LEDS; i++) {
Leds[i] = startupHSVColor;
}
FastLED.show();
}
if (startupHSVColor.val <= 0)
inStartup = false;
}
}
} else {
switch (currentMode) {
case 0:
default:
HSVRainbow();
EVERY_N_MILLISECONDS(8) {
IncrementHue(); // slowly cycle the "base color" through the rainbow
}
break;
case 1:
//Snake!
EVERY_N_MILLISECONDS(100) {
//advance snake 1 LED
if(++snakeIndex >= 0)
Leds[snakeIndex] = snakeHSVColor;
if (snakeIndex >= NUM_LEDS) {
snakeIndex = -8;
//re-randomize Color
snakeHSVColor.hue += 24;
}
}
EVERY_N_MILLISECONDS(12) {
for (int i = 0; i < NUM_LEDS; i++) {
fadeToBlackBy(&Leds[i], 1, 1);
}
break;
}
FastLED.show();
}
}
}
void HSVRainbow() {
CHSV hsv;
hsv.hue = gHue;
hsv.val = ledBrightness;
hsv.sat = 255;
for (int i = 0; i < NUM_LEDS; i++) {
Leds[i] = hsv;
hsv.hue += 16;
}
}
void IncrementHue() {
gHue += gHueSpeed;
}
void StartupLightTest() {
fill_solid(Leds, NUM_LEDS, CRGB::Red);
FastLED.show();
delay(500);
fill_solid(Leds, NUM_LEDS, CRGB::Green);
FastLED.show();
delay(500);
fill_solid(Leds, NUM_LEDS, CRGB::Blue);
FastLED.show();
delay(500);
fill_solid(Leds, NUM_LEDS, CRGB::Black);
FastLED.show();
}