Boutton appuie long ne marche pas toujours

Bonjour, je débute sur Arduino.
Je fabrique en ce moment un séquenceur midi, j'ai déjà fait un programme qui fonctionne mais il est très désordonné ce qui rend les améliorations compliqués. Je repart donc de zéro pour réorganiser le programme correctement.

Mon Séquenceur comporte 4 bouton, le premier est le tap tempo , les trois autres sont (CENTRE, LEFT, RIGHT).
1 Switch qui permet d'activer le mode EDIT.
4 Potentiomètres qui envoient une valeur différente en fonction de l'état du switch EDIT.

Les boutons ont trois états :
-OFF
-ON appuie court (si le bouton est pressé moins d'une demi-sec)
-ON appuie long (si le bouton est pressé plus d'une demi-sec)

Les trois sous parties du programme (TAP TEMPO-CLOCK, BTN, POT) fonctionnent bien indépendamment. Pareil lorsqu'il y a seulement les parties TAP-TEMPO-CLOCK et BTN mais lorsque je rajoute la partie POT, l'appuis long sur le BTN-CENTRE ne marche pas durant les 300 mlSec. Dans le serial print, il est afficher Clong.ON seulement une fois. De la même façon, l'état long du bouton Centre s'active au démarrage alors que cette ligne dans le setup est sensé le désactiver.

    BtnLongTimer[b] = millis() - 500;  //Permet de ne pas activer l'etat long au démarage

Mon code :

//BTN GENERAL
bool OFF = HIGH;
bool ON = LOW;

//BTN_C-L-R
const int N_BTN = 3;                        //Nombre de Btn
byte BOUTONS[N_BTN] = { 13, 5, 7 };         //Pin Input des Btn
bool etatBtn[N_BTN] = { 0 };                //Etat Btn
bool etatPBtn[N_BTN] = { 0 };               //Etat Precedant Btn
bool etatBtnCourt[N_BTN] = { 0 };           //Etat Btn appuie Court
bool etatBtnLong[N_BTN] = { 0 };            //Etat Btn appuie Long
unsigned long btnTimer[N_BTN] = { 0 };      //Timer Btn
unsigned long btnEndTimer[N_BTN] = { 0 };   //Fin Timer Btn
unsigned long BtnLongTimer[N_BTN] = { 0 };  //Timer Btn Long
enum { CENTRE = 0,
       LEFT = 1,
       RIGHT = 2 };

//BTN_EDIT
byte BTN_EDIT = 12;
bool etatEdit = 0;   //Etat Btn Edit
bool etatPEdit = 0;  //Etat Precedent Btn Edit

//POTARDS
const int N_POT = 4;                   //Nombre de Pot
byte POTARDS[N_POT] = { 0, 1, 2, 3 };  //Input des Potards
int valuePot[] = { 0 };                //Value du potard
unsigned long timerPot[] = { 0 };      //Agit comme un delay pour prendre en compte les variations du pot
int valuePotEdit[] = { 0 };            //Valeur du pot en Mode Edit
int valuePPotEdit[] = { 0 };           //Valeur precedent du pot en mode Edit
int valuePotLecture[] = { 0 };         //Valeur du pot en Mode Lecture
int valuePPotLecture[] = { 0 };        //Valeur precedent du pot en mode Lecture
const int potThreshold = 1;            //Threshold pour les variation de pot
const int potThreshold2 = 30;          //Threshold pour les cariations de pot entre le mode Lecture et le Mode Edit

//CLOCK
byte BTN_TAP_TEMPO = 2;
byte LED_TEMPO = 3;
bool etatTapTempo = 0;                       //Etat Btn Tap Tempo
bool etatPastTapTempo = 0;                   //Etat precedent Btn Tap Tempo
unsigned long timerTempo[2] = { 500, 500 };  //Espace entre les Clock (500mSec à l'allumage)
unsigned long timeoutTempo = 0;              //Temps depuis derniere Clock Tempo
unsigned long lastTap = 0;                   //Temps depui la derniere Tap
unsigned long timeoutTempoSeq = 0;           //Temps depuis dernier Clock Sequence
unsigned long indicatorTimeoutTempo = 0;     //Clock pour Led Tempo


void setup() {
  Serial.begin(57600);
  pinMode(BTN_TAP_TEMPO, INPUT_PULLUP);  //BTN Tap Tempo
  pinMode(LED_TEMPO, OUTPUT);            //LED Tempo
  for (int b = 0; b < N_BTN; b++) {      //BTN C-L-R
    pinMode(BOUTONS[b], INPUT_PULLUP);
    etatBtn[b] = OFF;
    BtnLongTimer[b] = millis() - 500;  //Permet de ne pas activer l'etat long au démarage
  }
  pinMode(BTN_EDIT, INPUT_PULLUP);  //BTN Edit
}

void loop() {

  //TAP TEMPO - CLOCK
  etatTapTempo = digitalRead(BTN_TAP_TEMPO);                     //Lecture etat Btn Tap Tempo
  if (etatTapTempo == ON && etatTapTempo != etatPastTapTempo) {  //Si Etat Btn Tap Tempo = ON et a changé
    timerTempo[1] = timerTempo[0];                               //la derniere Tap prend la valeur de celle d'avant
    timerTempo[0] = millis() - lastTap;                          //Temps entre deux Tap
    lastTap = millis();                                          //Valeur de la dernière Tap
    timeoutTempo = 0;                                            //Rst de la clock Tempo si Tap Tempo Activé
    timeoutTempoSeq = 0;                                         //Rst de la clock Seq si Tap Tempo Activé
  }
  etatPastTapTempo = etatTapTempo;                                    //Etat precedent Btn Tap Tempo devient etat Btn Tap Tempo
  if (millis() >= timeoutTempo) {                                     //Si la durée de la clock est depasser
    indicatorTimeoutTempo = millis() + 50;                            //Valeur pour allumé Led Tempo
    timeoutTempo = millis() + ((timerTempo[0] + timerTempo[1]) / 2);  //Calcul de la nouvelle clock
    Serial.println("Clock");
  }
  if (millis() < indicatorTimeoutTempo) {  //Alume la Led Tempo 50mlSec a chaque Clock
    digitalWrite(LED_TEMPO, HIGH);
  } else {
    digitalWrite(LED_TEMPO, LOW);
  }

  //BOUTONS CENTRE-LEFT-RIGHT
  for (int a = 0; a < N_BTN; a++) {                    //Pour Btn C-L-R
    etatPBtn[a] = etatBtn[a];                          //Etat Btn devient Precedent Btn
    etatBtnCourt[a] = OFF;                             //Rst Btn Court
    etatBtnLong[a] = OFF;                              //Rst Btn Long
    etatBtn[a] = digitalRead(BOUTONS[a]);              //Lecture Btn
    if ((etatPBtn[a] == OFF) && (etatBtn[a] == ON)) {  //Si Btn appuié
      btnTimer[a] = millis();                          //Dedut Timer Btn
    }
    if ((etatPBtn[a] == ON) && (etatBtn[a] == OFF)) {  //Si Btn desappuié
      btnEndTimer[a] = millis();                       //Fin Timer Btn
      if (etatBtn[a] != etatPBtn[a]) {                 //Si etat Btn à changer
        if ((btnEndTimer[a] - btnTimer[a]) < 500) {    //Si Btn Appuié moins de 500mlSec
          etatBtnCourt[a] = ON;                        //Btn Court
        }
        if ((btnEndTimer[a] - btnTimer[a]) > 500) {  //Si Btn Appuié plus de 500mlSec
          etatBtnLong[a] = ON;                       //Btn Long
          BtnLongTimer[a] = millis();                //Debut Timer Btn Long
        }
      }
    }
    if (millis() - BtnLongTimer[a] < 300) {  //Btn C long reste activé pendant 300mlSec
      etatBtnLong[a] = ON;
    }
  }
  if (etatBtnLong[CENTRE] == ON) {
    Serial.println("Clong.ON");
  }
  if (etatBtnLong[LEFT] == ON) {
    Serial.println("Llong.ON");
  }
  if (etatBtnLong[RIGHT] == ON) {
    Serial.println("Rlong.ON");
  }
  if (etatBtnCourt[CENTRE] == ON) {
    Serial.println("Ccourt.ON");
  }
  if (etatBtnCourt[LEFT] == ON) {
    Serial.println("Lcourt.ON");
  }
  if (etatBtnCourt[RIGHT] == ON) {
    Serial.println("Rcourt.ON");
  }

  //SWITCH MODE EDIT
  etatEdit = digitalRead(BTN_EDIT);  //Lecture Btn Edit

  //POTARDS
  for (int d = 0; d < N_POT; d++) {                             //Pour les quatre Pot
    valuePot[d] = analogRead(POTARDS[d]);                       //Lecture de la valeur du pot
    if (etatEdit == OFF) {                                      //Si Etat Edit = OFF
      int potVar = abs(valuePot[d] - valuePPotEdit[d]);         //Calcul de la variation du pot par raport a la valeur du pot en mode edit
      if (potVar > potThreshold2) {                             //Si la variation est superieur au treshold 3
        if (millis() - timerPot[d] > 20) {                      //On effectue cette boucle toute les 20mlSec pour pouvoir prendre en compte les variations du pot
          timerPot[d] = millis();                               //Rst du timer pot
          int potVar = abs(valuePot[d] - valuePPotLecture[d]);  //Calcul de la variation en mode Lecture
          if (potVar > potThreshold) {                          //Si la variation est supperieur au threshold 1
            valuePotLecture[d] = valuePot[d];                   //Value pot en mode Lecture prend la valeur du pot
            valuePPotLecture[d] = valuePot[d];                  //Value precedente pot en mode Lecture prend la valeur du pot
          }
        }
      }
    }
    if (etatEdit == ON) {                                    //Si Etat Edit = ON
      int potVar = abs(valuePot[d] - valuePPotLecture[d]);   //Calcul de la variation du pot par raport a la valeur du pot en mode edit
      if (potVar > potThreshold2) {                          //Si la variation est superieur au treshold 3
        if (millis() - timerPot[d] > 20) {                   //On effectue cette boucle toute les 20mlSec pour pouvoir prendre en compte les variations du pot
          timerPot[d] = millis();                            //Rst du timer pot
          int potVar = abs(valuePot[d] - valuePPotEdit[d]);  //Calcul de la variation en mode Edit
          if (potVar > potThreshold) {                       //Si la variation est supperieur au threshold 1
            valuePotEdit[d] = valuePot[d];                   //Value pot en mode Edit prend la valeur du pot
            valuePPotEdit[d] = valuePot[d];                  //Value precedente pot en mode Edit prend la valeur du pot
          }
        }
      }
    }
  }
}

Je penses que la solution n'est pas compliqué mais comme je l'ai dit je suis un débutant et je me suis pris la tête toute la journée sans résultat.
Si quelqu'un sait pourquoi l'appuie long ne marche pas lorsque je rajoute la partie POT.
Merci d'avance pour vos réponses.

A vérifier, je ne suis pas sûr de ce que je dis:

Pour moi, cela définit un tableau de 3 valeurs qui sont toutes initialisées à 0. Cela fonctionne.

Pour moi, le tableau valuePot n'a qu'un seul élément et il est initalisé à 0. Si on veut avoir 4 éléments, il faut faire int valuePot[N_POT] = { 0 }; ou int valuePot[] = { 0, 0, 0, 0 };

Du coup avec la boucle, on écrit en dehors des variables et tout peut arriver.

Je n'ai pas poursuivi plus loin.

Merci pour ta réponse :slight_smile: en effet tu as raison je n'ai pas défini le nombre de case pour le tableau des potentiomètres.
J'ai encore des choses à apprendre haha

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.