/* Credits: Optimus Digital S.R.L.
 * Acest cod este creat special pentru shield-ul cu LCD și tastatura
 * https://www.optimusdigital.ro/ro/shield-uri-pentru-arduino/274-shiel-pentru-arduino-cu-lcd-si-tastatura-.html
 * 
 * In setup() se apeleaza doua functii:
 * 1. Calibrare() 
 *    Aceasta functie are rolul a salva valorile corespunzatoare fiecarui buton.
 * 
 * 2. testLCD()   
 *    Functia aceasta testeaza daca pixelii LCD-ului sunt functionali.
 *    Testarea se face prin afisarea caracterului "█" pe fiecare pozitie.
 *    
 * Dupa ce se termina calibrarea si testarea, pe ecran se va afisa textul "Optimus Digital".
 * 
 * In loop() se verifica daca s-a apasat vreun buton folosind valorile salvate din functia
 * calibrare(). Daca se detecteaza apasarea, se va afisa pe linia a 2-a butonul apasat.
 */

//biblioteca inclusa in mediul de dezvoltare creata special pentru a facilita utilizarea
//LCD-urilor de tip 1602.
#include <LiquidCrystal.h>


//se declara variabilele in care se retin valorile de referinta corespunzătoare fiecarui buton
int right,left,up,down,sel;

//se declara pinii utilizati de ecranul LCD
const int rs = 8, en = 9, d4 = 4, d5 = 5, d6 = 6, d7 = 7;

//se creeaza un obiect LiquidCrystal, utilizat pentru a afisa mai usor
//text pe LCD-ul 1602
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void testLCD()
{
 //se sterg toate caracterele de pe ecran, se seteaza cursorul pe coloana 0, linia 0
 //si se afiseaza textul "Testare ecran", dupa care se asteapta 3 secunde (1000 ms = 1 s)
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print("Testare ecran");
 delay(3000);

 //se sterg toate caracterele de pe ecran, se seteaza cursorul pe coloana 0, linia 0,
 //si se afisează caracterul "█" pe fiecare pozitie de pe linia 0.
 //caracterul "█" este reprezentat prin codul 255.
 lcd.clear();
 lcd.setCursor(0,0);
 
 for(int i=0;i<16;i++)
  { 
    lcd.write(255);
    delay(150);
  }

 //se sterg toate caracterele de pe ecran, se seteaza cursorul pe coloana 0, linia 1,
 //si se afisează caracterul "█" pe fiecare pozitie de pe linia 1.
  //caracterul "█" este reprezentat prin codul 255.
 for(int i=15;i>=0;i--)
  { 
    lcd.setCursor(i,1);
    lcd.write(255);
    delay(150);
  }

  delay(2000);

}



void calibrare()
{ 
  //se sterg toate caracterele de pe ecran si se afiseaza 
  //cuvintele "calibrare" si "Butoane" pe linia 0, respectiv
  //linia 1, dupa care se asteapta 3 s.
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Calibrare");
  lcd.setCursor(0,1);
  lcd.print("Butoane");
  delay(3000);


  //se sterg toate caracterele de pe ecran si se afiseaza
  //textul "Apasati RIGHT",dupa care programul asteapta 
  //ca dumneavoastra sa apasati pe buton marcat cu RIGHT pe shield,
  //si salveaza valoarea inregistrata în variabila right.
  lcd.clear();
  lcd.print("Apasati RIGHT");
  lcd.setCursor(0,1);
  while(analogRead(A0)>1000);
  
  right = analogRead(A0)+50;


  delay(500);

  //se sterg toate caracterele de pe ecran si se afiseaza
  //textul "Apasati UP",dupa care programul asteapta 
  //ca dumneavoastra sa apasati pe buton marcat cu UP pe shield,
  //si salveaza valoarea inregistrata în variabila up.
  lcd.clear();
  lcd.print("Apasati UP");
  lcd.setCursor(0,1);
  while(analogRead(A0)>1000);
  
  up = analogRead(A0)+50;


  delay(500);



  //se sterg toate caracterele de pe ecran si se afiseaza
  //textul "Apasati DOWN",dupa care programul asteapta 
  //ca dumneavoastra sa apasati pe buton marcat cu DOWN pe shield,
  //si salveaza valoarea inregistrata în variabila down.
  lcd.clear();
  lcd.print("Apasati DOWN");
  lcd.setCursor(0,1);
  while(analogRead(A0)>1000);
  
  down = analogRead(A0)+50;
 

   delay(500);

  //se sterg toate caracterele de pe ecran si se afiseaza
  //textul "Apasati LEFT",dupa care programul asteapta 
  //ca dumneavoastra sa apasati pe buton marcat cu LEFT pe shield,
  //si salveaza valoarea inregistrata în variabila left.
  lcd.clear();
  lcd.print("Apasati LEFT");
  lcd.setCursor(0,1);
  while(analogRead(A0)>1000);
  
  left = analogRead(A0)+50;


  delay(500);

  //se sterg toate caracterele de pe ecran si se afiseaza
  //textul "Apasati SELECT",dupa care programul asteapta 
  //ca dumneavoastra sa apasati pe buton marcat cu SELECT pe shield,
  //si salveaza valoarea inregistrata în variabila sel.
  lcd.clear();
  lcd.print("Apasati SELECT");
  lcd.setCursor(0,1);
  while(analogRead(A0)>1000);
  
  sel = analogRead(A0)+50;
  delay(500);

  //se sterg toate caracterele de pe ecran si se confirma ca
  //s-a terminat calibrarea butoanelor.
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Configurare");
  delay(500);
  lcd.setCursor(0,1);
  lcd.print("Terminata");
  
  delay(1000);
 
}


void setup() {
  
  //se initializeaza LCD-ul prin functia begin() care are ca
  //parametri numarul de caractere de pe o linie si numarul
  //de linii
  lcd.begin(16,2);
  
  //aceasta functie este utilizată atunci când nu stiți ca valori
  //ofera fiecare buton atunci cand este apasat.
  //Daca stiti deja valorile puteți sa stergeți aceasta functie
  //si sa introduceti manual valorile in variabilele corespunzatoare
  //fiecarui buton
  calibrare();

  //functia testLCD() este utila pentru a verifica daca exista pixeli 
  //defecti sau daca LCD-ul nu este controlat corespunzator
  testLCD();

  //se sterg toate caractere de pe ecran si se afiseaza textul
  //"Optimus Digital" incepând cu coloana 0, linia 0
  lcd.clear();
  lcd.setCursor(0,0);
  
  lcd.print("Optimus Digital");
  
  delay(1000);
}



//variabila value este utilizata pentru a stoca valorile
//masurate pe pin-ul A0 atunci cand se apasa un buton
int value;
void loop() {


  //se stocheaza în value valorea inregistrara pe pin-ul A0.
  value = analogRead(A0);

  //daca s-a apasat un buton, se sterg toate caractere de pe ecran
  //si se reafiseaza textul "Optimus Digital" incepand cu coloana 0,
  //linia 0, dupa care se seteaza cursorul pe coloana 0, linia 1.
  if(value < 1000)
   {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Optimus Digital");
    lcd.setCursor(0,1);
  
   }

  //in functie de valorile de referinta stocate in variabilele
  //right, up, down, left, select se determina butonul apasat
  //si se afiseaza pe coloana 0, linia 1 un mesaj care indica 
  //butonul apasat.
  if(value < right)
      lcd.print("Right");
  else if(value < up)
      lcd.print("Up");
  else if(value < down)
      lcd.print("Down");
  else if(value < left)
      lcd.print("Left");
  else if(value < sel)
      lcd.print("Select");

 
  delay(50);

}
