Automatisation d'un malaxeur

Salut la famille j'espère que vous allez bien en tout cas !
j'suis débutant avec Arduino
j'ai un soucis ici sur mon projet j'suis bloqué depuis un temps je vous en prie de vouloir m'aider en tout cas

mon soucis est d'introduire 3 valeurs différentes grâce à un pavé matriciel 4*4 pour les stocker dans un tableau ou trois variables que je veux utiliser plus tard dans mon programme mais j'essaie et je ne parviens pas

aidez moi s'il vous plait !!!!
merci d'avance
voici mon code:

#include <Keypad.h>

const byte ROWS = 4; // Nombre de rangées du pavé numérique
const byte COLS = 4; // Nombre de colonnes du pavé numérique

char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};

byte pin_rows[ROWS] = {9, 8, 7, 6}; // Broches connectées aux rangées
byte pin_cols[COLS] = {5, 4, 3, 2}; // Broches connectées aux colonnes

Keypad keypad = Keypad(makeKeymap(keys), pin_rows, pin_cols, ROWS, COLS);

int motorPin = 10; // Broche de commande du moteur
int minutes = 0; // Durée de fonctionnement du moteur en minutes

void setup() {
Serial.begin(9600);
pinMode(motorPin, OUTPUT);
}

void loop()
{
// Variables pour stocker les valeurs entrées par l'utilisateur
int value1 = 0;
int value2 = 0;
int value3 = 0;

// Demander à l'utilisateur d'entrer la première valeur
Serial.println("Entrez la premiere valeur :");
value1 = getValueFromKeypad();

if( value1 != 0)
{
// Demander à l'utilisateur d'entrer la deuxième valeur
Serial.println("Entrez la deuxieme valeur :");
value2 = getValueFromKeypad();

if( value2 != 0)
{

	// Demander à l'utilisateur d'entrer la troisième valeur
	Serial.println("Entrez la troisieme valeur :");
	value3 = getValueFromKeypad();

}
}

// Afficher les valeurs entrées par l'utilisateur
Serial.print("Valeur 1 : ");
Serial.println(value1);
Serial.print("Valeur 2 : ");
Serial.println(value2);
Serial.print("Valeur 3 : ");
Serial.println(value3);

delay(1000); // Attendre un peu avant de recommencer
}

int getValueFromKeypad() {
char key;
int value = 0;

// Attendre que des données soient disponibles sur le clavier matriciel
while (!keypad.getState()) {
// Attendre que des données soient disponibles sur le clavier matriciel
}

key = keypad.getKey();
if (keypad.getState()) {
Serial.print("Touche appuyée : ");
Serial.println(key);
}

if (key >= '0' && key <= '9') {
value = key - '0';
} else {
value = -1; // Valeur par défaut si la touche n'est pas un chiffre
}

return value;
}

C'est-à-dire?
Qu'est-ce qui bloque ou ne fonctionne pas correctement?

Pour la saisie / gérer un flux asynchrone genre keypad vous pouvez jeter un oeil à mon petit tuto sur le sujet

Ton code semble gérer uniquement la saisie d'un nombre avec un seul chiffre, c'est ce que tu veux ?

merci de réagir
au faite il m'est impossible de stocker les valeurs

d'accord je veux voir merci

Un petit exemple avec le code du tuto

#include <Keypad.h>

const byte ROWS = 4; //4 rangées
const byte COLS = 3; //3 colonnes

char keys[ROWS][COLS] = {   //les symboles, déclarés par leur code ASCII dans le tableau à 2 dimension
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte rowPins[ROWS] = { 8, 7, 6, 5 };
byte colPins[COLS] = {4, 3, 2};

Keypad membraneKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS);  //On initialise une instance de la classe Keypad

const byte tailleMessageMax = 50;
char message[tailleMessageMax + 1]; // +1 car on doit avoir un caractère de fin de chaîne en C, le '\0'

const char marqueurDeFin = '#';

boolean ecouter() {
  static byte indexMessage = 0; // static pour se souvenir de cette variable entre 2 appels consécutifs. initialisée qu'une seule fois.
  boolean messageEnCours = true;

  char c = membraneKeypad.getKey();
  if (c != NO_KEY) {
    if (c == marqueurDeFin) {
      message[indexMessage] = '\0'; // on termine la c-string
      indexMessage = 0; // on se remet au début pour la prochaine fois
      messageEnCours = false;
    } else if (indexMessage <= tailleMessageMax - 1) message[indexMessage++] = (char) c; // on stocke le caractère et on passe à la case suivante
  }
  return messageEnCours;
}

void setup() {
  Serial.begin(115200);
  Serial.println("Entrez un chiffre et validez avec #");
}

void loop() {
  if (! ecouter()) {
    Serial.print("Reçu :"); Serial.println(message);
  }
  // ici on peut faire autre chose
}

ensuite pour saisir plusieurs entrées, une petite machine à état peut vous aider (cf mon tuto éventuellement)

Non ce n'est pas ce que je veux
mon soucis est d'introduire trois valeurs différentes que je dois stocker dans trois variables différentes donc
une valeur pour la quantité d'eau;
la deuxième pour la durée de cuisson et
la troisième pour la durée de fonctionnement du malaxeur

merci!

merci beaucoup je veux essayer

avec la machine à état ça donnerait cela par exemple

#include <Keypad.h>

const byte ROWS = 4; //4 rangées
const byte COLS = 3; //3 colonnes

char keys[ROWS][COLS] = {   //les symboles, déclarés par leur code ASCII dans le tableau à 2 dimension
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte rowPins[ROWS] = { 8, 7, 6, 5 };
byte colPins[COLS] = {4, 3, 2};

Keypad membraneKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS);  //On initialise une instance de la classe Keypad

const byte tailleMessageMax = 10;
char message[tailleMessageMax + 1]; // +1 car on doit avoir un caractère de fin de chaîne en C, le '\0'
const char marqueurDeFin = '#';

enum {DEBUT, ACQUISITION, GO} etat = DEBUT;
const byte nombreDAcquisitions = 3;
const unsigned long valeurMax = 9999;
unsigned long nombres[nombreDAcquisitions];
byte indexAcquisition;

boolean ecouter() {
  static byte indexMessage = 0; // static pour se souvenir de cette variable entre 2 appels consécutifs. initialisée qu'une seule fois.
  boolean messageEnCours = true;

  char c = membraneKeypad.getKey();
  if (c != NO_KEY) {
    if (c == marqueurDeFin) {
      message[indexMessage] = '\0'; // on termine la c-string
      indexMessage = 0; // on se remet au début pour la prochaine fois
      messageEnCours = false;
    } else if (indexMessage <= tailleMessageMax - 1)
      message[indexMessage++] = (char) c; // on stocke le chiffre et on passe à la case suivante
  }
  return messageEnCours;
}

void demande() {
  Serial.print("Entrez nombre N° ");
  Serial.print(indexAcquisition + 1);
  Serial.print(" (<= ");
  Serial.print(valeurMax);
  Serial.println(") suivi de # pour valider");
}

void setup() {
  Serial.begin(115200);
}

void loop() {
  switch (etat) {
    case DEBUT:
      indexAcquisition = 0;
      demande();
      etat = ACQUISITION;
      break;

    case ACQUISITION:
      if (! ecouter()) {
        char * endPtr = nullptr;
        nombres[indexAcquisition] = strtoul(message, &endPtr, 10);
        if (endPtr != message && *endPtr == '\0' && nombres[indexAcquisition] <= valeurMax) {
          Serial.print("Reçu : '"); Serial.print(message);
          Serial.print("', j'ai extrait le nombre : "); Serial.println(nombres[indexAcquisition]);
          indexAcquisition++;
          if (indexAcquisition >= nombreDAcquisitions) etat = GO;
          else demande();
        } else { // il n'y avait pas moyen de lire un nombre correct
          Serial.print("Reçu :'"); Serial.print(message);
          Serial.print("' => entrée erronée");
          if (endPtr != message && *endPtr == '\0') Serial.println(" (trop grand)");
          else Serial.println();
          demande();
        }
      }
      break;

    case GO:
      Serial.print("Les ");
      Serial.print(nombreDAcquisitions);
      Serial.print(" nombres sont :");
      for (unsigned long v : nombres) {
        Serial.print(v);
        Serial.print(' ');
      }
      Serial.println("\n------------------\n\n\n");

      etat = DEBUT; // on recommence
     break;
  }

  // ici on peut faire autre chose
}

merci !
je veux modifier après je vous reviens :heart_eyes:

merci pour ce code
je l'ai essayé, ça fonctionne bien
je veux que si les trois valeurs sont entrées le programme passe à autres choses

et comment je dois faire pour récupérer les valeurs entrées pour en faire autres choses ?

merci !

si vous lisez le tuto sur les machines à états, vous verrez que l'on passe d'état en état quand des conditions sont remplies

ici quand les 3 valeurs sont saisies, l'état devient GO, c'est là que votre code peut s'exécuter. ici j'ai juste imprimé les 3 valeurs puis je suis retourné à l'état DEBUT qui redemande 3 valeurs

    case GO:
      Serial.print("Les ");
      Serial.print(nombreDAcquisitions);
      Serial.print(" nombres sont :");
      for (unsigned long v : nombres) {
        Serial.print(v);
        Serial.print(' ');
      }
      Serial.println("\n------------------\n\n\n");

      etat = DEBUT; // on recommence
     break;
1 Like

oui je vois je n'avais pas tiré mon attention sur ça
merci :smiling_face_with_three_hearts:
je vous reviens

à partir d'ici je ne vois pas comment je veux récupérer les valeurs en question parce que les trois sont stockées dans long v

est-ce que je peux faire ça ?

      unsigned long valeur1 = nombres[0];
      unsigned long valeur2 = nombres[1];
      unsigned long valeur3 = nombres[2];

Oui tu peux, mais pourquoi t'embêter à faire ça puisque nombres[0] contient la valeur de la quantité d'eau.
le seul intérêt pourrait être d'avoir un nom de variable plus explicite, mais dans ce cas autant faire un traitement particulier à la ligne 67, ou l'élément du tableau est assigné avec la valeur saisie

1 Like

oui vous pouvez mais comme le dit @terwal pourquoi dupliquer les valeurs... ?

si cette écriture vous dérange

c'est comme

for (byte i=0; i< nombreDAcquisitions; i++) {
  Serial.print(nombres[i]);
  Serial.print(' ');
}

sinon si vous ne voulez pas de tableau, au lieu de ranger automatiquement les variables lues avec

        nombres[indexAcquisition] = strtoul(message, &endPtr, 10);

vous pouvez faire

case ACQUISITION:
      if (! ecouter()) {
        char * endPtr = nullptr;
        unsigned long valeur = strtoul(message, &endPtr, 10);
        if (endPtr != message && *endPtr == '\0' && nombres[indexAcquisition] <= valeurMax) {
          Serial.print("Reçu : '"); Serial.print(message);
          Serial.print("', j'ai extrait le nombre : "); Serial.println(valeur);

           // affecter la bonne variable 
           switch(indexAcquisition) {
             case 0:  temperatureMin = valeur; break;
             case 1:  temperatureMax = valeur; break;
             case 2:  pressionMax = valeur; break;
             default: break;
          }

          indexAcquisition++;
          if (indexAcquisition >= nombreDAcquisitions) etat = GO;
          else demande();
        } else { // il n'y avait pas moyen de lire un nombre correct
          Serial.print("Reçu :'"); Serial.print(message);
          Serial.print("' => entrée erronée");
          if (endPtr != message && *endPtr == '\0') Serial.println(" (trop grand)");
          else Serial.println();
          demande();
        }
      }
      break;

avec la partie

           // affecter la bonne variable 
           switch(indexAcquisition) {
             case 0:  temperatureMin = valeur; break;
             case 1:  temperatureMax = valeur; break;
             case 2:  pressionMax = valeur; break;
             default: break;
          }

qui se charge en fonction de indexAcquisition de mettre la valeur lue dans la bonne variable (j'ai mis des variables au pif ici, juste pour l'exemple)

salut @terwal
oui je vois
mais si j'ai dupliqué c'est parce que je ne voyais pas où devrais je récupérer les valeurs pour en faire autre chose

merci :hugs:

bah oui t'as raison @J-M-L c'est cette écriture que je comprenais pas
merci beaucoup !

Salut j'espère que vous allez bien
à partir de ce code j'essaie d'ajouter un bouton poussoir départ cycle en utilisant la boucle while je n'arrive pas

donc je veux qu'après avoir introduit les valeurs, le programme puisse attendre un appui sur le bouton pour que ça passe à autre chose

merci !!