#include <FastLED.h> // https://github.com/FastLED/FastLED

#define PIN 0   // ATtiny85 Neopixel pin
#define led 1   // Number of Neopixels
#define MAX 255 // Maximum brightness
#define MIN 0   // Minimum brightness

CRGB leds[led];

// INTERRUPT ON ATTINY85
#include <avr/io.h> // required for #defines
#include <avr/interrupt.h> // required for ATtiny85 interrupts
volatile bool button; // type volatile for interrupt handler indicates "pressed"
int buttonPin = PINB2; // PB2
int count = 0; // which function to run
int cases = 6; // number of functions available

void setup() {
  FastLED.addLeds<WS2812, PIN, GRB>(leds, led);
  FastLED.clear();
  FastLED.setBrightness(MAX);
  FastLED.show();

  pinMode(PB2, INPUT_PULLUP); // inside or outside PCINT setup?

  // Configure interrupt and interrupt service routine for ATtiny85
  cli(); // CLEAR interrupts enabled while configuring interrupts

  // PCMSK -7-- -6-- PCI5 PCI4 PCI3 PCI2 PCI1 PCI0 // Bit 2 is PC Int Mask PB2
  PCMSK |= (1 << buttonPin); // shift 1 left 2 bits to set PCINT2/PB2/buttonPin

  // GIMSK -7-- INT0 PCIE -4-- -3-- -2-- -1-- -0-- // Bit 6 is Pin Change Interrupt Enable
  GIMSK |= (1 << PCIE); // shift 1 left six to set PCIE

  sei(); // SET interrupts enabled after confiuration is complete
}

void loop() {
  if (button) { // button flag is returned from ISR
    delay(200); // debounce
    button = 0; // reset ISR flag
    count++; // increment selected pattern
    if (count > cases) { // if counter reached last case...
      count = 0; // ... reset counter to first case
    }
  }

  switch (count) {
    case 0: zero();     break; // startup, pixel 0 random max R, G, B
    case 1: blink();    break; // Helo, Blink!
    case 2: candle();   break; // candle flicker with orange color values
    case 3: diffuse();  break; // white pixel for diffusion media (paper, plastic, et c.)
    case 4: fadeHSV();  break; // Hue, Saturation, Value transitions
    case 5: rgbycm();   break; // six basic colors cycling
    case 6: rnd();      break; // any of (256 * 256 * 256) = 16,777,216 colors
    // case 7: sequence(); break; // in-work sequencer GUI
  }
}

//**************************************************
// button isr
//**************************************************

ISR(PCINT0_vect) { // PCINT0_vect is devined. Only one PCINT
  cli(); // disable interrupts while in the ISR
  button = 1; // set the flag that the button was pressed
  sei(); // enable interrupts when leaving the ISR
}

//**************************************************
// patterns
//**************************************************

void zero() { // at startup, pixel 0 random max R, G, B
  leds[0] =  CRGB(random(2) * random(MAX),
                  random(2) * random(MAX),
                  random(2) * random(MAX));
  FastLED.show();
  delay(100);
}

void candle() { // candle flicker with orange color values
  int r = random (127, 255);
  int g = random (50, 127);
  int b = random (0, 15);
  leds[0] = CRGB(r, g, b);
  FastLED.show();
  delay(random(63, 255));
}

void diffuse() { // white pixel for diffusion media (paper, plastic, et c.)
  int i = random (63, 255);
  leds[0] = CRGB(i, i, i);
  FastLED.show();
  delay(random(63, 255));
}

void blink() { // Hello, Blink!
  leds[0] = CRGB::White; FastLED.show(); delay(500);
  leds[0] = CRGB::Black; FastLED.show(); delay(500);
}

void rgbycm() { // basic colors cycling
  int pause = 500;
  leds[0] = CRGB(MAX, 000, 000); FastLED.show(); delay(pause); // red
  leds[0] = CRGB(000, MAX, 000); FastLED.show(); delay(pause); // grn
  leds[0] = CRGB(000, 000, MAX); FastLED.show(); delay(pause); // blu
  leds[0] = CRGB(MAX, MAX, 000); FastLED.show(); delay(pause); // yel
  leds[0] = CRGB(000, MAX, MAX); FastLED.show(); delay(pause); // cyn
  leds[0] = CRGB(MAX, 000, MAX); FastLED.show(); delay(pause); // mag
}

void fadeHSV() { // Hue, Saturation, Value transitions
  uint8_t speed = 10; uint8_t change = 10; uint8_t hue = beat8(speed, 255);
  fill_rainbow(leds, led, hue, change);
  FastLED.show();
}

void rnd() { // random r, random g, random b
  leds[0] = CRGB(random(255), random(255), random(255));
  FastLED.show();
  delay(500);
}

void sequence() {
}

//**************************************************
// information
//**************************************************

/*
  or use INPUT_PULLUP    +-----------+
       +---R4.7k----+----|+ BATTERY -|-+
       |   +-- --+  |    +-----------+ |
       |   |1* V8|--|----------------+ |
   SW /    |2   7|--+     +-------+  | |
       |   |3   6|        |WS2812 |  | |
       |---|4G  5|--R470--|DIN VCC|--+ |
       |   +-----+     +--|GND out|    |
       |               |  +-------+    |
       +---------------+---------------+

                                   +-- --+
         PCINT5/-RESET/ADC0/dW/PB5 |1*  8| VCC
  PCINT3/XTAL1/CLKI/-OC1B/ADC3/PB3 |2   7| PB2/SCK/USCK/SCL/ADC1/T0/INT0/PCINT2
   PCINT4/XTAL2/CLKO/OC1B/ADC2/PB4 |3   6| PB1/MISO/DO/AIN1/OC0B/OC1A/PCINT1
                               GND |4   5| PB0/MOSI/DI/SDA/AIN0/OC0A/-OC1A/AREF/PCINT0
                                   +-----+

  // BlinkM
  // https://thingm.com/products/blinkm

  // BlinkM-MinM
  // https://thingm.com/products/blinkm-minm/

  // sequencer
  // https://thingm.com/products/blinkm/

  // https://www.instructables.com/Ghetto-Pixels-Building-an-open-source-BlinkM/
  // https://forum.arduino.cc/t/desperately-seeking-minm-leds-from-thingm/1173261

  // https://wokwi.com/projects/377183196488010753

  // https://thingm.com/products
  // https://raw.githubusercontent.com/todbot/LinkM/master/docs/LinkM_datasheet.pdf
  // https://github.com/todbot/LinkM/releases/download/v20150915/BlinkMSequencer2-win.zip

  Communications Connector
  – Ground, aka “Gnd”
  + 3-5VDC regulated power input, aka “Vcc”
  d I2C data input/output, aka “SDA”
  c I2C clock input/output, aka “SCL”

  LED Drive Connector
  V+ Positive voltage to drive LED external LED array
  (5-12 VDC @ 2A)
  R Red channel drive output
  G Green channel drive output
  B Blue channel drive output

  Input Connector
  analog input #0
    Red adjust w/ “Knob Adjust RGB” command
    Hue adjust w/ “Knob Adjust HSB” command

  analog input #1
    Green adjust w/ “Knob Adjust RGB” command
    Saturation adjust w/ “Knob Adjust HSB” command

  analog input #2
    Blue adjust w/ “Knob Adjust RGB” command
    Brightness adjust w/ “Knob Adjust HSB” command
    input 3 analog input #3

  toggle - on/off

  /**************************************************
  /*  button - sequence
  /**************************************************
  #include <avr/io.h>
  int main(void) {
  while(1) {
    DDRB= 0b00111110;
    int pushbutton= PINB5;

    if (pushbutton == 0) {
      PORTB= 0b00000001;
    } else {
      PORTB= 0b00000000;
    }
  }
  }
*/
ATTINY8520PU