#include <EEPROM.h>
#include <FastLED.h>
#include "Button2.h"
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define NUM_LEDS 18
#define LED_PIN 3
#define BUTTON_PIN 6
#define INTERNAL_LED 13
#define SCREEN_WIDTH 128 // OLED width, in pixels
#define SCREEN_HEIGHT 32 // OLED height, in pixels
#define OLED_RESET 4
#define MAX_MODES 5
CRGB leds[NUM_LEDS];
byte currentMode = 0;
bool isFast = false;
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
Button2 button;
unsigned long time_now = 0;
char str_display[30];
char str_display_speed[30];
unsigned long previousMillis = 0; // Stores last time LEDs were updated
int count = 0; // Stores count for incrementing up to the NUM_LEDs
int move = NUM_LEDS-1;
void displayCurrentMode();
void setup() {
pinMode(INTERNAL_LED, OUTPUT);
digitalWrite(INTERNAL_LED, LOW); // LED ausschalten
Serial.begin(9600);
button.begin(BUTTON_PIN);
button.setLongClickTime(500);
button.setClickHandler(clicked);
button.setLongClickDetectedHandler(longPress);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x32)
display.display(); //needed before anything is displayed
FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setMaxPowerInVoltsAndMilliamps(5, 2000);
for(int i=0;i<NUM_LEDS;i++){
leds[i] = CRGB(0,0,255);
}
FastLED.show();
currentMode = EEPROM.read(0);
if(currentMode > MAX_MODES){
currentMode = 2;
EEPROM.write(0,2);
}
// Clear the buffer
display.clearDisplay();
display.setTextWrap(false);
displayCurrentMode();
}
void loop() {
button.loop();
switch(currentMode){
case 0:
isFast ? shootingStarAnimation(0, 0, 255, 80, 20, 1000, -1): shootingStarAnimation(0, 0, 255, 30, 20, 1500, -1);
break;
case 1:
isFast ? strobo(0,0,255, 100) : strobo(0,0,255, 500);
break;
case 2:
isFast ? strobo(0,0,255, 100) : buildUp(0,0,255, 50);
break;
case 3:
isFast ? rainbow(isFast, 3) : rainbow(isFast, 10);
break;
case 4:
isFast ? strobo(50,50,50, 100) : buildUp(50,50,50, 50);
break;
}
}
void clicked(Button2& btn) {
isFast = !isFast;
displayCurrentMode();
}
void longPress(Button2& btn) {
currentMode++;
currentMode = currentMode % MAX_MODES;
EEPROM.write(0,currentMode);
Serial.print("Current Mode: ");
Serial.println(currentMode);
isFast = false;
displayCurrentMode();
}
void displayCurrentMode(){
display.clearDisplay();
display.setTextColor(WHITE); // Draw white text
display.setCursor(0, 0); // Start at top-left corner
display.cp437(false); // Use full 256 char 'Code Page 437' font
display.setTextSize(1);
switch(currentMode){
case 0:
sprintf(str_display,"Modus: Komet");
break;
case 1:
sprintf(str_display,"Modus: Blau Strobo");
break;
case 2:
sprintf(str_display,"Modus: Aufbauend");
for(int i = 0; i < NUM_LEDS; i++){
leds[i] = CRGB(0, 0, 0);
}
FastLED.show();
count = 0;
move = NUM_LEDS-1;
break;
case 3:
sprintf(str_display,"Modus: Regenbogen");
count = 0;
break;
case 4:
sprintf(str_display,"Modus: Weiss Strobo");
count = 0;
for(int i = 0; i < NUM_LEDS; i++){
leds[i] = CRGB(0, 0, 0);
}
FastLED.show();
break;
}
if(isFast){
sprintf(str_display_speed, "Refrain");
} else {
sprintf(str_display_speed, "Strophe");
}
display.print(str_display);
display.setCursor(42,16);
display.print(str_display_speed);
display.display();
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
CRGB Wheel(byte WheelPos) {
if(WheelPos < 85) {
return CRGB(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if(WheelPos < 170) {
WheelPos -= 85;
return CRGB(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return CRGB(0, WheelPos * 3, 255 - WheelPos * 3);
}
}
void rainbow(bool isFast, int interval){
unsigned long currentMillis = millis(); // Get the time
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
if(isFast)
{
int pos = random16(NUM_LEDS);
leds[pos] = Wheel((count) & 255);
}
else{
for(int i = 0; i< NUM_LEDS; i++){
leds[i] = Wheel((count) & 255);
}
}
if(count++ == 256) count=0;
FastLED.show();
}
}
void buildUp(int red, int green, int blue, int interval){
unsigned long currentMillis = millis(); // Get the time
for(int i = 0; i < count; i++){
leds[i] = CRGB(red, green, blue);
}
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
leds[move] = CRGB(red, green, blue);
move--;
if(move == count){
count ++;
move = NUM_LEDS-1;
}
if(count == NUM_LEDS-1 ){
for(int i = 0; i < NUM_LEDS; i++){
leds[i] = CRGB(0, 0, 0);
}
count = 0;
move = NUM_LEDS-1;
}
fadeToBlackBy(leds, NUM_LEDS, 200); // Fade the tail LEDs to black
}
FastLED.show();
}
bool isStroboOn = true;
void strobo(int red, int green, int blue, int interval){
unsigned long currentMillis = millis(); // Get the time
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis; // Save the last time the LEDs were updated
isStroboOn = !isStroboOn;
for(int i = 0; i < NUM_LEDS; i++){
leds[i] = isStroboOn ? CRGB(red, green, blue) : CRGB(0, 0, 0);
}
FastLED.show();
}
}
void shootingStarAnimation(int red, int green, int blue, int tail_length, int delay_duration, int interval, int direction){
/*
* red - 0 to 255 red color value
* green - 0 to 255 green color value
* blue - 0 to 255 blue color value
* tail_length - value which represents number of pixels used in the tail following the shooting star
* delay_duration - value to set animation speed. Higher value results in slower animation speed.
* interval - time between each shooting star (in miliseconds)
* direction - value which changes the way that the pixels travel (uses -1 for reverse, any other number for forward)
*/
unsigned long currentMillis = millis(); // Get the time
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis; // Save the last time the LEDs were updated
count = 0; // Reset the count to 0 after each interval
}
if (direction == -1) { // Reverse direction option for LEDs
if (count < NUM_LEDS) {
leds[NUM_LEDS - (count % (NUM_LEDS+1))].setRGB(red, green, blue); // Set LEDs with the color value
count++;
}
}
else {
if (count < NUM_LEDS) { // Forward direction option for LEDs
leds[count % (NUM_LEDS+1)].setRGB(red, green, blue); // Set LEDs with the color value
count++;
}
}
fadeToBlackBy(leds, NUM_LEDS, tail_length); // Fade the tail LEDs to black
FastLED.show();
delay(delay_duration); // Delay to set the speed of the animation
}