// LCD Keypad Shield
#include <LiquidCrystal.h>
#include "lcdkey.h"
// Création de l'objet lcd (avec les différents ports numériques qu'il utilise)
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
// Variables
int moteur_res=400;
float debut=0.00;
float fin=20.55;
signed int erreur;
int compteur=0;
int increment=1;
int NumMenu=1;
int LCDxPOScurrent=0;
int LCDxPOS;
int xcurs=0;
String MainMenu=" Debut Fin vitesse ";//max 10 choix et max 40 caracteres un espace au debut et fin
//              
int MainMenulength;
int lcdXpos=0;
static byte cursBlink;
unsigned long last_key_read = 0;
unsigned long time_key_read = 0;
void setup()//*****************************SETUP******************************
{
   // set prescale to 16
 // sbi(ADCSRA,ADPS2) ;
 // cbi(ADCSRA,ADPS1) ;
 // cbi(ADCSRA,ADPS0) ;

  pinMode(A0, INPUT);
  pinMode(2, OUTPUT); 
  pinMode(3, OUTPUT); 
  
  delay(500);
  
              Serial.begin(9600);
              delay(500); 
              lcd.begin(16, 5);
              ini_Lcd() ;
              lcd.setCursor(0, 0); 
              lcd.print(MainMenu);
              delay(300);
              lcd.noCursor();
              lcd.noBlink();
              MainMenulength = MainMenu.length();
}
 
void loop()//********************************LOOP********************************
{

   int key;        
   time_key_read = millis();
   static int key_delay=100;
   static int scrool=0;
   if (time_key_read - last_key_read >= 100) {                         // Vérifier si au moins 100ms se sont écoulées depuis la dernière lecture du bouton
        if (key_delay>100){key_delay-=100;}
        if(scrool>0){scrool--;lcd.scrollDisplayLeft();}
        if(scrool<0){scrool++;lcd.scrollDisplayRight();}
       
        last_key_read = time_key_read;
        key = read_buttons(); 
        lcd.setCursor(xcurs,0);
        if((cursBlink)%6 > 3&& key==btnNONE) {
            lcd.write(1);
        }
        else{
            lcd.print(" ");     
        }
        cursBlink++;
        if (key != btnNONE &&  key_delay==100 ) {
            key_delay=500;
            static int cptMenu=0;
            static int index1=MainMenu.indexOf(" ",1);
            int LongStringChoix;
            if(key==btnLEFT){
               if(NumMenu>1){
               NumMenu--;
               for(int i=xcurs-1 ;i >= 0; i--){                  
                     xcurs--;
                           if(xcurs<=lcdXpos && lcdXpos > 0){
                                     //lcd.scrollDisplayRight();  
                                     scrool--;
                                     lcdXpos--;    
                           }                    
                           if(MainMenu[i]==' '){index1=MainMenu.indexOf(" ",xcurs+1);break;} 
                    
                     }
           
                }     
            }      
            
            if(key==btnRIGHT){
                if(NumMenu<10 && index1<MainMenulength-1){
                              NumMenu++;
                              xcurs=index1;//MainMenu.indexOf(" ",xcurs+1);
                              index1=MainMenu.indexOf(" ",xcurs+1);
                              if((index1>15 && lcdXpos<MainMenulength-16 )){// && index1<MainMenulength){
                                 // lcd.scrollDisplayLeft();
                                   for(int i=0 ;i <(index1-xcurs)-(xcurs<16?16-xcurs:0); i++){
                                       scrool++;
                                       lcdXpos++;
                                    } 
                              }
                }
            }    
           
        }      
   }
    else{key=btnNONE;}

    if (key==btnSELECT){

      Serial.print("Vous avez choisi ");
      switch (NumMenu){
        case 1:                                         //menu raz
           debut=choose_number("Debut ",debut,0,100,0.1);
            Serial.print("Debut\n");
            result=0;
            break;
        case 2:                                        //menu set
            Serial.print("Fin\n");
            //moteur_res=choose_number("moteur_res ",moteur_res,10,10000);
            fin=choose_number("Fin ",fin,0,100,0.001);
            Serial.print(moteur_res);
            break;
        case 3:                                         //menu dir
            Serial.print("DIR\n");
           
            break;
       case 4:                                         //menu stop
              lcd.setCursor(0, 1); 
              if(increment==1)lcd.print("RUN " );
              else lcd.print("STOP" );

            Serial.print("STOP\n");
            Serial.print(increment);
            increment=(increment+1)&1;
            break;
        case 5:  
            break;
        case 6:  
            break;
           
        default:
            Serial.print("Choix invalide\n");
            break;
    
      }
    }
  
        lcd.setCursor(lcdXpos-scrool, 1);
        lcd.print("      ");
        lcd.print(compteur);
         lcd.print("  ");
        compteur++;
  
}

//******************************************************



int choose_number(String title,int number,int min,int max) {
    lcd.setCursor(0, 0);
    lcd.print(title);
    lcd.print(number);
    int button=0;
    static int tempo=100;
    int title_length = title.length();
    delay(500);
    do {
       button = read_buttons(); // Lire le bouton pressé

       switch (button) {
        case btnUP: // Touche "Up" : Augmente le nombre
            if (number < max) {
                number++;
            }
            lcd.setCursor(title_length, 0);
            lcd.print(number);
            lcd.print("  ");
            break;
        case btnDOWN: // Touche "Down" : Diminue le nombre
            if (number > min) {
                number--;
            }
            lcd.setCursor(title_length, 0);
            lcd.print(number);
            lcd.print("  ");
            break;
          default:
            // Touche non valide, rien à faire
            break;
      }
      
      //Serial.print(button);
      delay(100); // Délai pour éviter la répétition rapide des touches
      button==5? tempo=100:tempo>0?tempo=tempo-(tempo/10):tempo;
      
   } while (button != btnSELECT);
lcd.setCursor(0, 0);
lcd.print(MainMenu);
//delay(500);
return number;
}
 
float choose_number(String title,float number,float min,float max,float step) {
    lcd.setCursor(0, 0);
    float iniStep=step;
    int nbDecimale;
    String str = String(step,8);
     while (str.endsWith("0")) {
        str.remove(str.length() - 1);
    }
    int dotIndex = str.indexOf('.');
    if (dotIndex != -1) {
        nbDecimale = str.length() - dotIndex - 1;      // -1 pour exclure le séparateur lui-même
    }
    lcd.print(title);
    lcd.print(number,nbDecimale);
    lcd.print("  ");
    int button=0;
    static int tempo=100;
    int title_length = title.length();
    delay(500);
    do {
       button = read_buttons(); // Lire le bouton pressé

       switch (button) {
        case btnUP: // Touche "Up" : Augmente le nombre
            if (number < max) {
                number=number+step;
                if(number>max)number=max;
            }
            lcd.setCursor(title_length, 0);
            lcd.print(number,nbDecimale);
            lcd.print("  ");
            break;
        case btnDOWN: // Touche "Down" : Diminue le nombre
            if (number > min) {
                number=number-step;
                if(number<min)number=min;
            }
            lcd.setCursor(title_length, 0);
            lcd.print(number,nbDecimale);
            lcd.print("  ");
            break;
        default:
            // Touche non valide, rien à faire
            break;
      }
      
      //Serial.print(button);
      delay(tempo); // Délai pour éviter la répétition rapide des touches
      button==5? tempo=99:tempo>50?tempo--:tempo;
      button==5? step=iniStep:step;
      Serial.print(tempo%10);
           // tempo%10==0 && max/step > 100? step=step*2:step;
            max/step >200? step=step*1.1:step;
     // (tempo<50 && button!=5)? step=step+(step/10):step;
   } while (button != btnSELECT);
lcd.setCursor(0, 0);
lcd.print(MainMenu);
//delay(500);
return number;
}
 

int getDecimalPlaces(float number) {            // Fonction pour obtenir le nombre de chiffres après la virgule
   
    String str = String(number, 8);  // Utilisez une précision suffisamment élevée pour capturer tous les décimales

    int dotIndex = str.indexOf('.');
    if (dotIndex != -1) {
        int decimalPlaces = str.length() - dotIndex - 1;  // -1 pour exclure le séparateur lui-même
        return decimalPlaces;
    } else {
        // Aucun séparateur décimal trouvé, donc il n'y a pas de chiffres après la virgule
        return 0;
    }
}
LCDKEYPAD SHIELDBreakout
Acceleration Fast Slow