#include <SoftwareSerial.h>         //utilisation du port série pour l'afficheur numérique
#include <LiquidCrystal_I2C.h>      //utilisation de l'écran LCD sur bus I2C
#include <VirtualWire.h>            //utilisation d'une liaison radio 433Mhz
#include <Wire.h>
#include <Keypad_I2C.h>             //utilisation du clavier sur bus I2C
#include <Keypad.h>                  
  
// These are the Arduino pins required to create a software serial
// instance. We'll actually only use the TX pin.
const int softwareTx = 5;
const int softwareRx = 6;

const String CodeSecret ="1212";

//Adresse I2C du clavier
#define keypad_addr   0x20

//définition des touches du clavier
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {0,1,2,3}; //connect P0-P3 to the row R1-R4 pinouts of the keypad
byte colPins[COLS] = {4,5,6,7}; //connect P4-P7 to the column C1-C4 pinouts of the keypad


#define GoButton      7     //pin connecté au bouton GO
#define Allumage      4     //pin connecté au relais allumeur
#define Sirene        3     //pin connecté au buzzer
#define TpsAlerte     60    //temps d'alerte avant mise à feu en secondes
#define AllumImmin    20    //mise à feu imminente

int FinSequence=0;

SoftwareSerial s7s(softwareRx, softwareTx); 
LiquidCrystal_I2C lcd(0x27,16,2);
Keypad_I2C I2C_Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS, keypad_addr, PCF8574);

unsigned int counter = 0;   // This variable will count up to 65k
char tempString[10];        // Will be used with sprintf to create strings


void setup() 
{
  pinMode(Sirene,OUTPUT);           //Le pin connecté au buzzer est une sortie
  pinMode(GoButton, INPUT_PULLUP);  //Le pin connecté au bouton armement est une entrée
  pinMode(Allumage,OUTPUT);         //Sortie de commande du relais d'allumage  

 
  vw_setup(2000);                     //initialisation radio
  vw_set_tx_pin(12);
  
 lcd.init();
 lcd.cursor_on();
 lcd.blink_on();
 lcd.backlight();
 lcd.setCursor(0,0);
 lcd.print("Initialisation..");  
 lcd.cursor_off();
 lcd.blink_off();
  
  // Must begin s7s software serial at the correct baud rate.
  // The default of the s7s is 9600.
  s7s.begin(9600);
  clearDisplay();     // Clears display, resets cursor
  s7s.print(" HI ");  // Displays " HI "

  // Flash brightness values at the beginning
  setBrightness(0);     // Lowest brightness
  delay(1500);
  setBrightness(127);   // Medium brightness
  delay(1500);
  setBrightness(255);  // High brightness
  delay(1500);
  // Clear the display before jumping into loop
  clearDisplay();

  Wire.begin();
  I2C_Keypad.begin(makeKeymap(keys));
  Serial.begin(9600);
}
int i;
int Chrono;
String Code;
String CodeReinit; 
void loop()
{
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Entrez code...");
  while (Code != CodeSecret)  //Attente de la saisie du code secret
  {
    //Put value of pressed key on keypad in key variable
    char key = I2C_Keypad.getKey();
    if (key)
    {
      lcd.setCursor(0,1);
      lcd.print(key);
      Code=Code+key;
      if (key=='*') //reset de la saisie avec la touche "*"
      {
        Code=CodeReinit;
      }
     }
    }

  byte message[27];               //Message radio
  byte taille_message = 27;
  
  lcd.clear();
  delay(500);
  lcd.setCursor(0,0);
  lcd.print("Attente");
  lcd.setCursor(0,1);
  lcd.print("lancement...");
  delay(500);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Evacuez zone et");
  lcd.setCursor(0,1);
  lcd.print("armez la ligne");
  delay(500);
  
  Chrono=TpsAlerte;
  while(!(digitalRead(GoButton))&&(Chrono>0))  //Compte à rebour
  {                 
    Chrono--;
    ShowTimer();
    lcd.clear();
    delay(100);
    lcd.setCursor(0,0);
    lcd.print("Sequence lancee");
    lcd.setCursor(0,1);
    lcd.print("Evacuez la zone");
    delay(100);
    if(Chrono<=AllumImmin)
    {
      tone(Sirene,300,700); //sirène à tempo. rapide
      delay(800);  
    }
    else
    {
      tone(Sirene,500,400); //sirène à tempo. lent
      delay(1000); 
    }
  }
  if(!digitalRead(GoButton))      //Si pas d'annulation de la séquence
  {
      tone(Sirene,100,100);
      //digitalWrite(Allumage,HIGH);      //ALLUMAGE !

      s7s.print("FEU ");                  //afficher "FEU " sur l'afficheur 7 segments
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Mise a feu !");          //afficher "Mise a feu" sur la première ligne de l'écran LCD

      strcpy(message, "Feu");             //Message de mise à feu à transmettre par radio
      for (i=0; i<=10; i++)
      {
        vw_send(message, taille_message);   //Transmission du message de mise à feu
        vw_wait_tx();                       //Attente de la transmission
        delay(500);
      }
  }
  i=0;
  Chrono=0;
  pinMode(Sirene,INPUT_PULLUP);   //Palliatif à buzzer trop sensible   
  digitalWrite(Allumage,LOW);     //Fin d'allumage
}

void ShowTimer()                 //Affcihage du temps restant sur l'afficheur 7 seguements
{
  String seconds = String (Chrono, DEC);                
  while(seconds.length()<4)seconds= "0" + seconds;      //format to 4 numbers.
  s7s.print(seconds);                                   //Write number of seconds left to display
}

// Send the clear display command (0x76)
//  This will clear the display and reset the cursor
void clearDisplay()
{
  s7s.write(0x76);  // Clear display command
}

// Set the displays brightness. Should receive byte with the value
//  to set the brightness to
//  dimmest------------->brightest
//     0--------127--------255
void setBrightness(byte value)
{
  s7s.write(0x7A);  // Set brightness command byte
  s7s.write(value);  // brightness data byte
}
