Fonction paramétrée et soucis de débutant

Bonsoir , je viens chercher un peu d'aide ici ... je précise que je débute mais ça va se voir !!!

dans mon projet j'ai besoin de renseigner plusieurs temps au keypad , j'ai donc crée une fonction paramétrée ...

j'utilise plusieurs variables pour chaque chronos , je désire donc travailler avec une seule et même fonction

void saisieMMSS (unsigned long tempsMScalc , unsigned long mm , unsigned long ss) {

  // variable locale utilisées dans la fonction :
  unsigned int saisie_int[4] = {0 , 0 , 0 , 0}; // Tableau pour stocker minute
  unsigned char compteur_touche_saisie; // Variable pour compter les appuis sur le clavier
  char key; // Variable pour la valeur de touches saisie de 0 à 15


  // mise a zéro des variables utilisées:
  compteur_touche_saisie = 0; // Pas de saisie lors du demarrage
  mm = 0; // On demarre avec une saisie a zéro minute
  ss = 0; // On demarre avec une saisie a zéro seconde

  // gestion appuis touches :
  while (compteur_touche_saisie < 4) { // Tant que l'ont a pas mini 4 appuis :


    key = keypad.getKey();          // on lit la touche saisie
    
    if (key != NO_KEY) {            // Si une touche est pressée

      tone(buzz_Pin, 1600, 50); //on active le buzzer quand une touche est pressée
      
      for (byte i = 0; i < rows; i++) {
        for (byte j = 0 ; j < cols ; j++) {
          if (key == keys[i][j]) key = keys[i][j] - 48; // extrait la valeur numérique à partir ASII  -- key = local , keys = variable du clavier
        }
      }
      saisie_int[compteur_touche_saisie] = key; // On stocke la valeur de la touche appuyé dans le tableau
      compteur_touche_saisie++; // On incrémente le compteur de touche saisies
      key = 255; // On remet la valeur de la touche appuyée à 255 pour éviter prise en compte même appuis a plusieurs reprises
    } // Fin de gestion clavier

    // ---------- Calcul de la valeur saisie selon le shéma : 2 première pressions = MIN puis 2 dernière pression = SEC
    // ------------------ Calcul du nombre saisi ------------------
    if (compteur_touche_saisie == 0) mm = 0 ; ss = 0;
    if (compteur_touche_saisie == 1) mm = saisie_int[0];                                  // 1ere saisie
    if (compteur_touche_saisie == 2) mm = (saisie_int[0] * 10) + (saisie_int[1] * 1);     // 2eme saisie
    if (compteur_touche_saisie == 3) ss = saisie_int[2];                                  // 3eme saisie
    if (compteur_touche_saisie == 4) ss = (saisie_int[2] * 10) + (saisie_int[3] * 1);     // 4eme saisie
    // ------------------ ---------------------- ------------------

    tempsMScalc = (mm * 60000) + (ss * 1000); // temps entré en mm:ss convertit en ms

    // Affichage de la sasie :
    timeCalc = (tempsMScalc / 60000);
    lcd.setCursor(3, 2);
    lcd.print("==[ ");
    // Affichage Minutes Bleu
    if ((timeCalc % 60) < 10) {
      lcd.print("0");
      lcd.print(timeCalc % 60);
    }
    else {
      lcd.print(timeCalc % 60);
    }
    lcd.print(":");
    // Affichage Secondes Bleu
    timeCalc = (tempsMScalc / 1000);
    if ((timeCalc % 60) < 10) {
      lcd.print("0");
      lcd.print(timeCalc % 60);
    }
    else {
      lcd.print(timeCalc % 60);
    }
    lcd.print(" ]==");
    delay(50); // delay entres appuis
  } // Fin du while

  compteur_touche_saisie = 0; // remise a zero du compteur de touches
  delay(1000);         // Petit delay pour laisser le temps saisie afficher avant de quitter la saisie
  lcd.clear();         //Puis on efface l'ecran avant de sortir de la fonction

  return;

}// End fonction

ma fonction affiche bien le temps saisi au keypad sur l’écran LCD mais mes valeurs placées en paramètres ne prennent pas la valeur ...

quelle est mon / mes erreurs ?

en vous remerciant d'avance pour votre aide ...

À la sortie de l’appel les variables de la fonction sont perdues telles étaient sur la pile)
Soit vous passez des pointeurs; soit vous appelez par référence (avec le &) ce qui est le plus simple

 void saisieMMSS (unsigned long& tempsMScalc , unsigned long& mm , unsigned long& ss)
{
...

dans ce cas les cases mémoires que vous affectez au sein de la fonction sont les mêmes que celles des variables passées lors de l’appel

Je viens de tester cela mais ...

j'ai écris :

saisieMMSS (& Temps_de_Jeu, & minute , & seconde);
en appel de fonction.

Temps_de_Jeu est le compteur en ms du temps entré minute / seconde . mais ces variables ne prennent pas la valeur voulue .

les " & " sont a mettre sur la fonction ? uniquement lors de son appel avec les variables voulues ? ou les deux ?

Ça s'appelle un passage de paramètre par référence. Voici un exemple en c++ qui te montre la syntaxe.

void test(int &i) // i est une référence du paramètre.
{
   i = 2;    // Modifie le paramètre passé en référence.
   return;
}

int main(void)
{
   int i=3;
   test(i);
   // Après l'appel de test, i vaut 2.
   // L'opérateur & n'est pas nécessaire pour appeler
   // test.
   return 0;
}

L'appel se fait sans le &

Effectivement on ne met les & que dans la définition. ce faisant on dit au compilateur « quand tu vois un appel à cette fonction, au lieu de passer les paramètres en mettant une copie sur la pile, utilise directement l’adresse mémoire des variables en paramètres ». En pratique donc toutes les modifications effectuées sur les paramètres au sein de la fonction sont donc répercutés instantanément

C'est bon , tout marche comme je veux et je passe de 6 fonctions a une seule :slight_smile:

merci beaucoup messieurs !

mon autre erreur était peut être que mes variable passées en paramètre étaient en unsigned int et non unsigned long ...

bon dimanche à vous .

bravo !!
bonne bidouilles du dimanche !

je reviens sur le sujet pour approfondir les possibilités ...

peut ont détecter les variables utilisées en paramètre ?

exemple si je veux envoyer du texte sur le LCD en fonction de la variable passé en paramètre :

si j'utilise ma variable tempsDeJeu , alors j'affiche " Temps de jeu " sur le lcd

si j'utilise ma variable tempsDeCapture , alors j'affiche " Temps de capture " sur le LCD ...

je sais déjà que je peux passer ces bout de code en amont de l'appel de la fonction mais ... je cherche juste pour voir :slight_smile:

Oui on peut, vu le fonctionnement, suffit de comparer avec l'adresse des variables globales

par exemple essayez cela

uint32_t tempsDeJeu = 1000;
uint32_t tempsDeCapture  = 0;

void coucou(uint32_t& temps)
{
  if (&temps == &tempsDeJeu) {
    Serial.print(F("Temps de Jeu:"));
    Serial.println(temps--);
  } else if (&temps == &tempsDeCapture) {
    Serial.print(F("Temps de Capture:"));
    Serial.println(temps++);
  }
}

void setup() {
  Serial.begin(115200);
  for (int i = 0; i < 100; i++) {
    coucou(tempsDeJeu);
    coucou(tempsDeCapture);
    Serial.println();
    delay(1000);
  }
}

void loop() {}

mais bon, s'il y a bcp de dépendance avec la variable utilisée, autant faire 2 fonctions spécialisées qui appellent ensuite une fonction d'affichage commune (ie travaillez au bon niveau d'abstraction)