/*=================== CORRECTEUR D’ASSIETTE + FAIL SAFE====================

                    Programme pour Arduino Nano et ADXL335 avec Fail Safe en cas de perte signal ou détection d'eau

         Servo des barres AR sur le pin°A1
         Servo des barres AV sur le pin°A4
         Servo de pompe sur le pin°A2
         Potard de réglage de la sensibilité sur le pin A3
         Capteur accéléromètre sur le pin A0
         Détecteur d'eau sur le pin A5 //  le détecteur consiste à mettre un fil de détection sur la masse et un autre sur le pin A5
         Récepteur signal barre sur le pin D2
         Récepteur signal pompe sur le pin D4
         Led clignotante de Fail Safe sur le pin D6
===========================================================================*/


#include <SoftRcPulseOut.h>


SoftRcPulseOut myservo1;               // Création du servo barre AR
SoftRcPulseOut myservo2;               // Création du servo pompe
SoftRcPulseOut myservo4;               // Création du servo barre AV

#define POT_POTARD                  A3 // Potard réglant la sensibilité attaché au Pin A3 
#define POT_ACCELEROMETRE           A0 // Accéléromètre attaché au Pin A0 
#define SERVO_PIN1                  A1 // Servo barre attaché au Pin A1
#define SERVO_PIN2                  A2 // Servo pompe attaché au Pin A2
#define SERVO_PIN4                  A4 // Servo barre attaché au Pin A4
#define DET                         A5 // Détecteur d'eau attaché au Pin A5
#define signal1                      2 // Signal radio barre attaché au Pin D2
#define signal2                      4 // Signal radio pompe attaché au Pin D4
#define ledPin6                      6 // Led clignotante en cas de Fail-safe 

#define REFRESH_PERIOD_MS 20           // Période de rafraîchissement

#define MOY_SUR_1_VALEURS       0
#define MOY_SUR_2_VALEURS       1
#define MOY_SUR_4_VALEURS       2
#define MOY_SUR_8_VALEURS       3
#define MOY_SUR_16_VALEURS      4
#define MOY_SUR_32_VALEURS      5

#define TAUX_DE_MOYENNAGE       MOY_SUR_4_VALEURS  /* Choisir ici le taux de moyennage parmi les valeurs precedentes possibles listees ci-dessus */

#define MOYENNE(Valeur_A_Moyenner,DerniereValeurRecue,TauxDeMoyEnPuissanceDeDeux)  Valeur_A_Moyenner=((((Valeur_A_Moyenner)*((1<<(TauxDeMoyEnPuissanceDeDeux))-1)+(DerniereValeurRecue))/(1<<(TauxDeMoyEnPuissanceDeDeux)))+(TauxDeMoyEnPuissanceDeDeux-1))
int neutre = 1500;
int valp = 1370;                  // variable position servo pompe en cas de fail-safe (à ajuster selon position voulue)
int valb = 10;                    // variable position servo barre en cas de fail-safe (à ajuster selon position voulue)
int val;                          // Variable pour stocker la valeur de l’accéléromètre
int val1;                         // Variable pour stocker la valeur du signal barre
int val2;                         // Variable pour stocker la valeur du signal pompe
int val3;                         // Variable pour stocker la valeur du potard
int val4;                         // Variable pour stocker la valeur du détecteur d'eau
int pos;                          // Variable pour stocker la position du servo
int pos_A = 100;                  // détection d'eau
int pos_B = 0;                    // pas d'eau détectée

int ledState = LOW;               // Etat de la led en cas de Fail-safe
long previousMillis = 0;          // variable écoulement du temps pour la led en cas de Fail-safe
long interval = 500;              // Valeur pour l'intervale de clignotement de la led (milliseconds)

void setup()
{
  myservo1.attach(SERVO_PIN1);  // Servo attaché au pin SERVO_PIN A1
  myservo2.attach(SERVO_PIN2);  // Servo attaché au pin SERVO_PIN A2
  myservo4.attach(SERVO_PIN4);  // Servo attaché au pin SERVO_PIN A4

  pinMode(ledPin6, OUTPUT);     // Led clignotante de fail-safe déclarée en sortie
  digitalWrite(DET, HIGH);      // Activation du pull-up interne

  digitalWrite(ledPin6, LOW);   // Led clignotante de fail-safe éteinte au départ du programme

}

void loop()
{

  unsigned long currentMillis = millis();                         // Affectation du compteur de temps


#define TAUX_DE_MOYENNAGE       MOY_SUR_2_VALEURS              // Choix du taux de moyennage
  static int ValMoyennee3;                                       // Valeur à moyennée
  val3 = analogRead(POT_POTARD);                                 // Lecture de la sensibilité
  val3 = map(val3, 0, 1023, 1, 50);                              // Mise à l’échelle de la sensibilité de 1 à 50
  val3 = constrain(val3, 1, 50);
  ValMoyennee3 = MOYENNE(ValMoyennee3, val3, TAUX_DE_MOYENNAGE); // Correction du bruit en fonction du taux de moyennage
  val3 = ValMoyennee3;

#define TAUX_DE_MOYENNAGE       MOY_SUR_4_VALEURS              // Choix du taux de moyennage
  static int ValMoyennee1;                                       // Valeur à moyennée
  val1 = pulseIn(signal1, HIGH, 30000);                          // Lecture du signal radio pour le servo barre
  val1 = map(val1, neutre - 500, neutre + 500, 0, 180);          // Mise à l’échelle
  val1 = constrain(val1, 0, 180);
  ValMoyennee1 = MOYENNE(ValMoyennee1, val1, TAUX_DE_MOYENNAGE); // Correction du bruit en fonction du taux de moyennage
  val1 = ValMoyennee1;

  if (digitalRead(DET)) {
    val4 = pos_B;  //Valeur selon détection d'eau
  }  else {
    val4 = pos_A;
  }

#define TAUX_DE_MOYENNAGE       MOY_SUR_4_VALEURS              // Choix du taux de moyennage
  static int ValMoyennee2;                                       // Valeur à moyennée
  val2 = pulseIn(signal2, HIGH, 30000);                          // Lecture du signal radio pour le servo pompe

  if (val2 < 10 || val4 > 90 ) {
    val2 = valp; val1 = valb;         // Si le signal est inferieur à 10 ou détection d'eau on passe en Fail Safe

    if (currentMillis - previousMillis > interval) {

      previousMillis = currentMillis;                              // on regarde si le temps est écoulé


      if (ledState == LOW)
        ledState = HIGH;
      else
        ledState = LOW;
      digitalWrite(ledPin6, ledState);                             // Si le temps est écoulé on allume la led

    }
  }
  else
    digitalWrite(ledPin6, LOW);                                // Pour eteindre la led si pas de Fail-safe

  val2 = map(val2, neutre - 500, neutre + 450, 0, 180);          // Mise à l’échelle
  val2 = constrain(val2, 0, 180);
  ValMoyennee2 = MOYENNE(ValMoyennee2, val2, TAUX_DE_MOYENNAGE); // Correction du bruit en fonction du taux de moyennage
  val2 = ValMoyennee2;


#define TAUX_DE_MOYENNAGE        MOY_SUR_4_VALEURS             // Choix du taux de moyennage
  static int ValMoyennee;                                        // Valeur à moyennée
  val = analogRead(POT_ACCELEROMETRE);                           // Lecture de l’accéléromètre
  val = map(val, 300, 430, 0 + val3, 180 - val3);                // Mise à l’échelle en tenant compte du potar sensibilité
  val = constrain(val, 0, 180);
  ValMoyennee = MOYENNE(ValMoyennee, val, TAUX_DE_MOYENNAGE);    //Correction du bruit en fonction du taux de moyennage
  val = ValMoyennee;

  pos = (val1 + val) / 2;                                        // Calcul position servo barre en tenant compte de l'Accéléromètre
  pos = constrain(pos, 50, 110);                                 // Limite des positions du servo

  myservo1.write(pos);                                           // Positionne le servo barre AR
  myservo4.write(pos);                                           // Positionne le servo barre AV
  myservo2.write(val2);                                          // Positionne le servo pompe
  delay(REFRESH_PERIOD_MS);                                      // Temps nécessaire au mouvement des servos

  SoftRcPulseOut::refresh();                                     // Rafraîchissement de SoftRcPulseOut


}
//=============================FIN DE PROGRAMME ===========================================