// controle moteur DC avec valeur cible fixé par un signal rc et lecture sur un potentiometre de la position 
// Ce sketch pilote un pont en H BTS7960B (maximum 40 ampères)
// La recopie position se fait avec un potentiomètre multitours (10) de 10K.
// Avec potentiomètre (10K) pour définir le nombre de tours moteur
// Et potentiomètre (10k) pour définir la vitesse du moteur
// Sketch valide pour Arduino UNO et NANO
// Pour la mise au point choisir une petite vitesse à cause du temps de lecture moniteur série agissant sur le programme
// Après mise au point supprimer les lignes concernant l'affichage moniteur série

 int signal = 4;              // Signal recepteur
 int val1;                    //Valeur du signal recepteur
 int pot1 = A1;               //pin analogique A1 pour le potentiometre asservissement
 int pot2 = A2;               //pin analogique A2 pour le potentiometre nombre de tours moteur
 int pot3 = A3;               //pin analogique A3 pour le potentiometre vitesse moteur
 int val2;                    // variable pour la lecture de la valeur analogique du potentiomètre asservissement
 int val3;                    // variable pour la lecture de la valeur analogique du potentiomètre nombre de tours moteur
 int val4;                    // variable pour la lecture de la valeur analogique de la vitesse moteur
 int hyseteris = 15;          // 10 stoppe déjà les tremblement moteur mais dépend de l'ordre de vitesse
 int max;                     // variable pour la lecture de la valeur maxi nombre de tours moteur
 int min;                     // variable pour la lecture de la valeur maxi nombre de tours moteur

 int RPWM=5;
 int LPWM=6;
 int L_EN=7;
 int R_EN=8;


 
void setPWMfrequency(int freq){
    TCCR0B = TCCR0B & 0b11111000 | freq ;        // Ajustement du timer 0 en fréquence
   }
  
   void MotorActiveStatus(char Side,boolean s){
     boolean state=s;
     if(Side=='R'){
     digitalWrite(R_EN,s);
     }
     if(Side=='L'){
     digitalWrite(L_EN,s);
     }    
   }
   void setMotor(char side,byte pwm){
    if(side=='R'){
     analogWrite(RPWM,pwm);
    }
     if(side=='L'){
     analogWrite(LPWM,pwm);
    }
   }
   void closeMotor(char side){
      if(side=='R'){
     digitalWrite(RPWM,LOW);
      }
      if(side=='L'){
     digitalWrite(LPWM,LOW);
      }

      }
 
void setup() 
{ 
  Serial.begin(9600);       // Vitesse de transmission pour le moniteur série  (ligne à supprimer après mise au point)
   
  pinMode(signal, INPUT);    // Signal entrée 
  pinMode(pot1, INPUT);      // Potar asservissement entrée 
  pinMode(pot2, INPUT);      // Potar nombre de tours moteur entrée
  pinMode(pot3, INPUT);      // Potar vitesse moteur entrée
   
   setPWMfrequency(0x02);// timer 0 , 3.92KHz
   for(int i=5;i<9;i++){
    pinMode(i,OUTPUT);
   }
    for(int i=5;i<9;i++){
    digitalWrite(i,LOW);
   }
    delay(50);
    
    MotorActiveStatus('R',true);
    MotorActiveStatus('L',true);
     
   }
 

void loop() 
{ 
  val4 = analogRead(pot3);                // lis la valeur du potentiometre pour définir la vitesse du moteur entre 0 et 1023 
  val4 = map(val4, 1, 1023, 50, 255);     // limite la valeur entre 100 et 255 
  val4 = constrain(val4, 50, 255);
  Serial.print("Valeur potar vitesse = ");   // Ecrit sur l’écran "Valeur potar vitesse= " (ligne à supprimer après mise au point)
  Serial.println(val4);        // Ecrit sur l’écran le contenu de val4 (ligne à supprimer après mise au point)
  delay (50);                // Attente pour affichage (ligne à supprimer après mise au point)
  
  val3 = analogRead(pot2);                // lis la valeur du potentiometre pour définir le nombre de tours moteur entre 0 et 1023 
  val3 = map(val3, 1, 1023, 60, 440);     // limite la valeur entre 60 et 440 
  val3 = constrain(val3, 60, 440);
  max = (500 + val3);
  min = (500 - val3);
  Serial.print("Valeur potar tours moteur = ");   // Ecrit sur l’écran "Valeur potar tour moteur= " (ligne à supprimer après mise au point)
  Serial.println(val3);        // Ecrit sur l’écran le contenu de val3 (ligne à supprimer après mise au point)
  delay (50);                // Attente pour affichage (ligne à supprimer après mise au point)
   
  val1 = pulseIn(signal, HIGH);               //Alors stocker la valeur du signal dans Val1
  val1 = map(val1, 1000, 2000, min, max);     // min et max définnissent le nombre de tours moteur
  val1 = constrain(val1,min, max);            // ici on limite le signal
  Serial.print("Valeur signal = ");   // Ecrit sur l’écran "Valeur signal= " (ligne à supprimer après mise au point)
  Serial.println(val1);        // Ecrit sur l’écran le contenu de Val1  (ligne à supprimer après mise au point)
  delay (50);                // Attente pour affichage (ligne à supprimer après mise au point)
   
  val2 = analogRead(pot1);                // lis la valeur du potentiometre d'asservissement entre 0 et 1023 
  val2 = map(val2, 1, 1023, 1, 1023);    
  val2 = constrain(val2, 1, 1023);
  Serial.print("Valeur potar asservissement = ");   // Ecrit sur l’écran "Valeur potar asservissement= " (ligne à supprimer après mise au point)
  Serial.println(val2);        // Ecrit sur l’écran le contenu de val2 (ligne à supprimer après mise au point)
  delay (50);                // Attente pour affichage (ligne à supprimer après mise au point)
  
  
  
 
 
   if (val1 > (val2 + hyseteris))
  {
    // reverse rotation
    int reversePWM = val4 ;  // ordre de vitesse 
     
    analogWrite(LPWM, 0);
    analogWrite(RPWM, reversePWM);
     
  
  }
  else if (val1 < (val2 - hyseteris))
  {
    // forward rotation
    int forwardPWM = val4 ; // ordre de vitesse 
     
     
  
    analogWrite(LPWM, forwardPWM);
    analogWrite(RPWM, 0);
      

   
  }  
    else if (val1 < (val2 + hyseteris) && val1 > (val2 - hyseteris))
  {
   
    int forwardPWM = 0; // stop
    int reversePWM = 0;  // stop 
     
  
    analogWrite(LPWM, forwardPWM);
    analogWrite(RPWM, reversePWM);
    
  
   
  }  
 delay (500);                // Attente pour affichage (ligne à supprimer après mise au point)

   
  
}