/*
Cave_a_Papa
Copyright (C) 2017  Pierrick C.

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3 of the License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.
If not, see <http://www.gnu.org/licenses/>
*/

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif

#define LED_PIN     0
#define RELAY_PIN   1
#define BAT_PIN     1     // Analog Input 1 = digital PIN 2
#define VMAX        486   // = ~13.5V  avec des résistances de 47k et 10k
#define V_GREEN     431   // = ~12V    tension pour vert pur
#define VMIN        395   // = ~11 V   
#define V_ALERTE    413   // = ~11.5V  provoque clignotement 3 fois rapide
#define V_OFF       388   // = ~10.8V  provoque clignotement pendant 15s puis OFF
#define OFF_DELAY   15    // delais de clignotement (en secondes) avant extinction à l'atteinte de V_OFF
#define INIT_BLINK  100

Adafruit_NeoPixel neopix = Adafruit_NeoPixel(1, LED_PIN, NEO_RGB + NEO_KHZ800);

byte timer = 100;
byte low_bat_counter = 0;
int vbat   = 0;
int red   = 0;
int green = 0;
bool warned = 0;

void blink(int n=3, int t=500) {
  for(int i=0;i<n;i++) {
      digitalWrite(RELAY_PIN, LOW);
      delay(t);
      digitalWrite(RELAY_PIN, HIGH);
      delay(t);
  }
}

void setup() {
  // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
  #if defined (__AVR_ATtiny85__)
    if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
  #endif
  // End of trinket special code

  pinMode(RELAY_PIN, OUTPUT);
  //pinMode(BAT_PIN, INPUT);

  neopix.begin();
  neopix.show(); // Initialize all pixels to 'off'

  for (int i=0; i<4;i++) {
    neopix.setPixelColor(0, 0, 0, 255);
    neopix.show();
    delay(INIT_BLINK);
    neopix.setPixelColor(0, 0, 0, 0);
    neopix.show();
    delay(INIT_BLINK);
  }

  digitalWrite(RELAY_PIN, HIGH);
  
}

void loop() {

  //Mesure de VBAT : moyenne de 10 mesures à 20ms d'intervale
  vbat =0;
  for(int i=0;i<10;i++) {
    vbat += analogRead(BAT_PIN);
    delay(20);
  }
  vbat /= 10;

  // Calcul de la couleur et affichage sur la neopixel
  red =   map(constrain(vbat, VMIN, V_GREEN), VMIN, V_GREEN, 255, 0);
  green = map(constrain(vbat, VMIN, V_GREEN), VMIN, V_GREEN, 0, 255);
  neopix.setPixelColor(0, red, green, 0);
  neopix.show();

  if(vbat<V_ALERTE && !warned) { 
    blink();
    warned = 1;
  }

  // Quand on atteint la limite basse, on incrémente un compteur
  if(vbat<VMIN) { low_bat_counter++; }

  // Si le compteur atteint la limite, la faible tension est validée : procédure d'extinction
  if(vbat<VMIN && low_bat_counter>10) { 
    blink(OFF_DELAY, 500); 
    digitalWrite(RELAY_PIN, LOW);
    while(1);
  }
  
  delay(1000);
}
