//with DOT STAR LIBRARY we use hardware SPI. (Arduino Uno = pin 11 for data, 13 for clock)
//#define DOT_STAR
//buttons debounce
#include <ButtonDebounce.h> //https://github.com/maykon/ButtonDebounce
#ifdef DOT_STAR
#include <Adafruit_DotStar.h> //https://github.com/adafruit/Adafruit_DotStar
typedef Adafruit_DotStar Strip;
#else
#include <Adafruit_NeoPixel.h> //https://github.com/adafruit/Adafruit_NeoPixel
typedef Adafruit_NeoPixel Strip;
#endif
#define PIN_BUTTON_1 2 // button 1 pin
#define PIN_BUTTON_2 3 // button 2 pin
#define PIN_BUTTON_3 4 // button 3 pin
#define PIN_BUTTON_4 5 // button 4 pin
#define PIN_BUTTON_5 6 // button 5 pin
#define PIN_BUTTON_6 7 // button 6 pin
#define PIN_BUTTON_7 8 // button 7 pin
#define PIN_BUTTON_8 9 // button 8 pin
#define PIN_BUTTON_9 10 // button 9 pin
#define PIN_STRIP 13 // led pin
#define FADEIN_DELAY 0 // the delay between steps of fade in
#define FADEOUT_DELAY 0 // the delay between steps of fade out
#define BUTTON_DENOUNCE_TIME 50 // time for button debounce
const uint16_t maxBrightness = 255; //maximal brightness of the strip
const uint16_t leds_number = 143; //total number of LEDs
const unsigned long fadeInDelay = 5000; //delay before fade in all LEDs
const uint16_t groups[9][20] = { //range for each group
{0, 9}, //group 1
{10, 14}, //group 2
{15, 49}, //group 3
{50, 58}, //group 4
{59, 68}, //group 5
{69, 78}, //group 6
{79, 88}, //group 7
{89, 98}, //group 8
{99, 120, 130, 143} //group 9
};
const uint16_t group_size[]{2,2,2,2,2,2,2,2,4};
const int increment = 5; //increment/decrement for effects
int brightness = 0; //current brightness
uint16_t cycleStep = 0; //current operation
uint16_t last_leds_group = 0; //last active group
unsigned long fadeMillis = 0; //time of fade out
int leds_brightness[leds_number]={0}; //brightness of all leds
//save button states
int stateSavedButton1 = HIGH;
int stateSavedButton2 = HIGH;
int stateSavedButton3 = HIGH;
int stateSavedButton4 = HIGH;
int stateSavedButton5 = HIGH;
int stateSavedButton6 = HIGH;
int stateSavedButton7 = HIGH;
int stateSavedButton8 = HIGH;
int stateSavedButton9 = HIGH;
//create a new strip object
#ifdef DOT_STAR
// Hardware SPI is a little faster, but must be wired to specific pins
// (Arduino Uno = pin 11 for data, 13 for clock, other boards are different).
Adafruit_DotStar strip(leds_number, DOTSTAR_BRG);
#else
Adafruit_NeoPixel strip(leds_number, PIN_STRIP, NEO_GRB + NEO_KHZ800);
#endif
// defines buttons and switches
ButtonDebounce button1(PIN_BUTTON_1, BUTTON_DENOUNCE_TIME);
ButtonDebounce button2(PIN_BUTTON_2, BUTTON_DENOUNCE_TIME);
ButtonDebounce button3(PIN_BUTTON_3, BUTTON_DENOUNCE_TIME);
ButtonDebounce button4(PIN_BUTTON_4, BUTTON_DENOUNCE_TIME);
ButtonDebounce button5(PIN_BUTTON_5, BUTTON_DENOUNCE_TIME);
ButtonDebounce button6(PIN_BUTTON_6, BUTTON_DENOUNCE_TIME);
ButtonDebounce button7(PIN_BUTTON_7, BUTTON_DENOUNCE_TIME);
ButtonDebounce button8(PIN_BUTTON_8, BUTTON_DENOUNCE_TIME);
ButtonDebounce button9(PIN_BUTTON_9, BUTTON_DENOUNCE_TIME);
void setup() {
Serial.begin(9600);
// strip settings
strip.begin();
strip.show();
//set maximal brightness
strip.setBrightness(maxBrightness);
}
void loop() {
// update buttons states
button1.update();
button2.update();
button3.update();
button4.update();
button5.update();
button6.update();
button7.update();
button8.update();
button9.update();
// read buttons state
int stateButton1 = button1.state();
int stateButton2 = button2.state();
int stateButton3 = button3.state();
int stateButton4 = button4.state();
int stateButton5 = button5.state();
int stateButton6 = button6.state();
int stateButton7 = button7.state();
int stateButton8 = button8.state();
int stateButton9 = button9.state();
// check if a button is pressed
if(!stateButton9){
if(!stateSavedButton9){
cycleStep = 9;
stateSavedButton9 = HIGH;
}
} else {
stateSavedButton9 = LOW;
}
if(!stateButton8){
if(!stateSavedButton8){
cycleStep = 8;
stateSavedButton8 = HIGH;
}
} else {
stateSavedButton8 = LOW;
}
if(!stateButton7){
if(!stateSavedButton7){
cycleStep = 7;
stateSavedButton7 = HIGH;
}
} else {
stateSavedButton7 = LOW;
}
if(!stateButton6){
if(!stateSavedButton6){
cycleStep = 6;
stateSavedButton6 = HIGH;
}
} else {
stateSavedButton6 = LOW;
}
if(!stateButton5){
if(!stateSavedButton5){
cycleStep = 5;
stateSavedButton5= HIGH;
}
} else {
stateSavedButton5 = LOW;
}
if(!stateButton4){
if(!stateSavedButton4){
cycleStep = 4;
stateSavedButton4 = HIGH;
}
} else {
stateSavedButton4 = LOW;
}
if(!stateButton3){
if(!stateSavedButton2){
cycleStep = 3;
stateSavedButton3 = HIGH;
}
} else {
stateSavedButton3 = LOW;
}
if(!stateButton2){
if(!stateSavedButton2){
cycleStep = 2;
stateSavedButton2 = HIGH;
}
} else {
stateSavedButton2 = LOW;
}
if(!stateButton1){
if(!stateSavedButton1){
cycleStep = 1;
stateSavedButton1 = HIGH;
}
} else {
stateSavedButton1 = LOW;
}
//change leds state depending on the pressed button
switch(cycleStep) {
case 0:
// change for all LEDs
if (stripFadeIn(strip, increment))
cycleStep = 100;
break;
case 1: //group 1
last_leds_group = 1;
if(stripFadeInGroup(strip, increment, groups[0], group_size[0]))
cycleStep = 98;
break;
case 2: //group 2
last_leds_group = 2;
if(stripFadeInGroup(strip, increment, groups[1], group_size[1]))
cycleStep = 98;
break;
case 3: // cycle stoped
last_leds_group = 3;
if(stripFadeInGroup(strip, increment, groups[2], group_size[2]))
cycleStep = 98;
break;
case 4: // cycle stoped
last_leds_group = 4;
if(stripFadeInGroup(strip, increment, groups[3], group_size[3]))
cycleStep = 98;
break;
case 5: // cycle stoped
last_leds_group = 5;
if(stripFadeInGroup(strip, increment, groups[4], group_size[4]))
cycleStep = 98;
break;
case 6: // cycle stoped
last_leds_group = 6;
if(stripFadeInGroup(strip, increment, groups[5], group_size[5]))
cycleStep = 98;
break;
case 7: // cycle stoped
last_leds_group = 7;
if(stripFadeInGroup(strip, increment, groups[6], group_size[6]))
cycleStep = 98;
break;
case 8: // cycle stoped
last_leds_group = 8;
if(stripFadeInGroup(strip, increment, groups[7], group_size[7]))
cycleStep = 98;
break;
case 9: // cycle stoped
last_leds_group = 9;
if(stripFadeInGroup(strip, increment, groups[8], group_size[8]))
cycleStep = 98;
break;
case 98: //update time for delay
fadeMillis = millis();
cycleStep = 99;
break;
case 99: //delay before fade in
if(millis() > (fadeMillis + fadeInDelay)){
if(stripFadeIn(strip, increment))
cycleStep = 100;
}
break;
case 100: //just wait for button press
break;
default:
cycleStep = 0;
}
}
bool check(const int _array[], const int _array_size, const int comp_value)
{
//size of array
for (int i = 0; i < _array_size; i++)
{
if (_array[i] != comp_value)
return false;
}
return true;
}
bool check_group(const int _array[], const int _array_size, const int _comp_value_max, const int _comp_value_min, const int _array_group[], int _array_group_size)
{
for (int i = 0; i < _array_size; i++)
{
//not in group
if(!inArray(i, _array_group, _array_group_size)){
if (_array[i] != _comp_value_min)
return false;
} else { //in group
if (_array[i] != _comp_value_max)
return false;
}
}
return true;
}
bool inArray(int a, int b[], int n) {
for (int i = 0; i < n; i++) if (a == b[i]) return true;
return false;
}
//fade in effect
bool stripFadeIn(Strip &strip, int _increment)
{
//pixels in the strip
uint16_t _numLEDs = strip.numPixels();
//get max brightness
int _brightness = strip.getBrightness();
//set LEDs' brightness
for (uint16_t j = 0; j < _numLEDs; j++){
//increase brightness
if (leds_brightness[j] < _brightness)
leds_brightness[j] += _increment;
//check for over range
if (leds_brightness[j] > _brightness)
leds_brightness[j] = _brightness;
strip.setPixelColor(j, strip.Color(leds_brightness[j], leds_brightness[j], leds_brightness[j]));
}
strip.show();
//delay to speed down the effect
//delay(FADEIN_DELAY);
//return true when reach max brightness
return check(leds_brightness, _numLEDs, _brightness);
}
//fade in except group
bool stripFadeInGroup(Strip &strip, int _increment, const int _array_group[], uint16_t _array_group_size)
{
//pixels in the strip
uint16_t _numLEDs = strip.numPixels();
//brightness
int _brightness = strip.getBrightness();
// change for all LEDs
for (uint16_t j = 0; j < _numLEDs; j++){
if(inArray(j, _array_group, _array_group_size)){ //fade in
//increase brightness
if (leds_brightness[j] < _brightness)
leds_brightness[j] += _increment;
//check for over range
if (leds_brightness[j] > _brightness)
leds_brightness[j] = _brightness;
strip.setPixelColor(j, strip.Color(leds_brightness[j], leds_brightness[j], leds_brightness[j]));
}else{ //not in group - fade out
//increase brightness
if (leds_brightness[j] > 0)
leds_brightness[j] -= _increment;
//check for over range
if (leds_brightness[j] < 0)
leds_brightness[j] = 0;
strip.setPixelColor(j, strip.Color(leds_brightness[j], leds_brightness[j], leds_brightness[j]));
}
}
//show the results
strip.show();
//delay to speed down the effect
//delay(FADEIN_DELAY);
//return true when reach max brightness
return check_group(leds_brightness, _numLEDs, _brightness, 0, _array_group, _array_group_size);
}