// Automatic rainbow staircase lighting
// www.magicmanu.com
// 10/2020
// https://www.youtube.com/watch?v=gVdwrkDrrc0
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif

#define inIR_H 		  2  // Input PIR top
#define inIR_B 		  3  // Input PIR bottom
#define PIND        6  // Input Neopixel right
#define PING        5  // Input Neopixel left
#define PHOTOSENS   A0 // Input Photoresistor
#define POTARLUM    A2 // Input Brightness detection adjustment
#define POTARTPS    A4 // Input Light duration adjustment
#define NUMPIXELS   13 // Number of pixel by side

bool IR_H = LOW;
bool IR_B = LOW;
bool MemH = LOW;
bool MemB = LOW;

int PhotoVal;
int AdjLum;
int AdjTps;
long AdjTpsMil;


Adafruit_NeoPixel pixelsD = Adafruit_NeoPixel(NUMPIXELS, PIND, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixelsG = Adafruit_NeoPixel(NUMPIXELS, PING, NEO_GRB + NEO_KHZ800);

void setup() { 
  pinMode(inIR_H,INPUT);
  pinMode(inIR_B,INPUT);
  
  pixelsD.begin();
  pixelsG.begin();
  
  pixelsD.clear();
  pixelsG.clear();

  pixelsD.show();
  pixelsG.show();
}

void loop() {
  
  PhotoVal = analogRead(PHOTOSENS);
  AdjLum   = analogRead(POTARLUM);
  AdjTps   = analogRead(POTARTPS);

  AdjTpsMil = AdjTps / (1024 / 300); // 0 to 300 seconds (5 minutes)
  AdjTpsMil *= 1000;         // to miliseconds
  
  IR_H = digitalRead(inIR_H);
  IR_B = digitalRead(inIR_B);

  if (IR_H) Serial.println("capteur Haut");
  if (IR_B) Serial.println("capteur Bas");
  
  if (IR_H != MemH){
    if (IR_H == HIGH and PhotoVal < AdjLum){
      Serial.println("Haut");
      downHigh();
      delay(AdjTpsMil); 
      downLow();
    }
    MemH = IR_H;
  }

  if (IR_B != MemB){
    if (IR_B == HIGH and PhotoVal < AdjLum){
      Serial.println("Bas");
      upHigh();
      delay(AdjTpsMil); 
      upLow();
    }
    MemB = IR_B;
  }  
  
}

void downLow() {
  int16_t i, j;
  
  for(i=0; i<=NUMPIXELS; i++) {
   	long lngRGB = pixelsD.getPixelColor(i);	// actual color
   	uint8_t u8R = (uint8_t)((lngRGB >> 16) & 0xff),
    	    u8G = (uint8_t)((lngRGB >> 8) & 0xff),
    	    u8B = (uint8_t)(lngRGB & 0xff);
 
    for(j=1; j<10; j++) {
      pixelsD.setPixelColor(i, u8R / j, u8G / j, u8B / j);
      pixelsG.setPixelColor(i, u8R / j, u8G / j, u8B / j);
      pixelsD.show();
      pixelsG.show();
      delay(15);  
    }      
    pixelsD.setPixelColor(i, 0, 0, 0);
    pixelsG.setPixelColor(i, 0, 0, 0);
    pixelsD.show();
    pixelsG.show();    
    delay(500);      
  }
}


void downHigh() {
  int16_t i, j;
  int32_t Color[3];
  
  for(i=0; i<NUMPIXELS; i++) {
    for(j=20; j>0; j--) {
      Rainbow(256 / NUMPIXELS * i, Color);   
      pixelsD.setPixelColor(i, Color[0] / j, Color[1] / j, Color[2] / j);
      pixelsG.setPixelColor(i, Color[0] / j, Color[1] / j, Color[2] / j);
      pixelsD.show();
      pixelsG.show();
      delay(5);  
    }
    delay(200);    
  }
}

void upLow() {
  int16_t i, j;
  
  for(i=NUMPIXELS; i>=0; i--) {
    //Serial.println(i);
   	long lngRGB = pixelsD.getPixelColor(i);	// actual color
   	uint8_t u8R = (uint8_t)((lngRGB >> 16) & 0xff),
    	    u8G = (uint8_t)((lngRGB >> 8) & 0xff),
    	    u8B = (uint8_t)(lngRGB & 0xff);
 
    for(j=1; j<10; j++) {
      pixelsD.setPixelColor(i, u8R / j, u8G / j, u8B / j);
      pixelsG.setPixelColor(i, u8R / j, u8G / j, u8B / j);
      pixelsD.show();
      pixelsG.show();
      delay(15);  
    }      
    pixelsD.setPixelColor(i, 0, 0, 0);
    pixelsG.setPixelColor(i, 0, 0, 0);
    pixelsD.show();
    pixelsG.show();    
    delay(500);      
  }
}

void upHigh() {
  int16_t i, j;
  int32_t Color[3];
  
  for(i=NUMPIXELS; i>=0; i--) {
    for(j=20; j>0; j--) {
      Rainbow(256 / NUMPIXELS * (i * -1 + NUMPIXELS - 1), Color);   
      pixelsD.setPixelColor(i, Color[0] / j, Color[1] / j, Color[2] / j);
      pixelsG.setPixelColor(i, Color[0] / j, Color[1] / j, Color[2] / j);
      pixelsD.show();
      pixelsG.show();
      delay(5);  
    }
    delay(200);    
  }
}

void Rainbow(byte WheelPos, int32_t TheColors[3]) {
  WheelPos = 255 - WheelPos;
  
  if(WheelPos < 85) {
    TheColors[0] = 255 - WheelPos * 3;
    TheColors[1] = 0;
    TheColors[2] = WheelPos * 3;
  }
  else if(WheelPos < 170) {
    WheelPos -= 85;
    TheColors[0] = 0;
    TheColors[1] = WheelPos * 3;
    TheColors[2] = 255 - WheelPos * 3;    
  }
  else {
  	WheelPos -= 170;
    TheColors[0] = WheelPos * 3;
    TheColors[1] = 255 - WheelPos * 3;
    TheColors[2] = 0;    
  }
}
