Je cherche à réaliser un compteur de point à l'aide d'un bouton poussoir. J'affiche une réponse sur mon écran LCD et si l'utilisateur a la bonne réponse, il doit appuyer sur le bouton poussoir pour que le compteur s'incrémente de 1. Cependant l’utilisateur appuis et relâche directement le bouton. Or dans le cas là, mon bouton ne s'incrémente pas, il ne s'incrémente que si l'utilisateur reste longtemps appuyé et appuis avant même que la réponse s'affiche. Pouvez vous m'aider svp ?
Voici une partie de mon code
lcd.print(departement[indice]);
lcd.setCursor(0, 0);
lcd.print("Reponse: ");
lcd.setCursor(0, 1);
strcpy_P(temp_string2, (char *)pgm_read_word(&(chaines2[departement[indice] - 1]))); // Copie le texte à partir du PROGMEM dans temp_string
if (digitalRead(BUTTON_ROUGE) == HIGH) {
count_red++;
delay(300);
Serial.println(count_red);
Serial.println("boucle");
}
Serial.println("marche");
lcd.print(temp_string2);
delay(2000);
lcd.clear();
delay(500);
Je n'ai pas vu dans ton code, le moment ou tu incrémente.
quel est le nom de la variable qui contient ton compteur ?
Sinon la première fois que tu appuis sur bouton et que isProgramRunning passe à True.
tu reviendra pour tester l'état de ton bouton à peu près 20s plus tard.
Cela est-il vraiment ce que tu veux faire?
je simplifierais le stockage des départements sous forme de structure quitte à occuper un peu plus de place en flash (vous avez du rab, même sur UNO). Conserver le N° du département n'est pas forcément nécessaire puisque le tableau est trié donc l'indice + 1 dans le tableau donnera le N° de département mais il me semblait que la corse c'était 2A et 2B non (auquel cas il faudrait une chaîne aussi pour N° si on peut avoir des lettres) ?
pour le reste je prendrais une bibliothèque pour les boutons et c'est typiquement une définition de programme qui se prête bien à la programmation par machine à états (cf mon tuto éventuellement)
Je n’ai pas fais de structure car je prends un nombre aléatoire. Ce nombre aléatoire correspond à mon indice. J’affiche le département correspondant à cet indice, ensuite je supprime ce département de ma liste. De cette manière il n’est pas possible d’afficher 2x le même département. Avec les structure je n’arrivais pas à faire en sorte que le département n’apparaissent pas 2 fois.
Du coup, il faut que ton bouton soit enfoncé exactement au bon moment, c'est à dire 5s après le premier appuis qui active isProgramRunning
Si tu utilise des délais, tu force la temporalité des actions que tu fait.
En l'occurrence tu attends le temps cumulé de tous tes délais, puis tu interroge l'état du bouton.
Pour avoir une bonne réactivité sur un bouton, tu dois interroger l'état très régulièrement.
Dans ton cas, soit tu fait comme @J-M-L, ce qui est le meilleur façon de faire de mon point de vue.
Soit tu utilise une fonction qui ferra le bon nombre de délais unitaire cours (200ms maximum) et entre chaque délais pour arriver au temps qui t'intéresse tu demande l'état de ton bouton.
je pourrais te faire un petit exemple, si cela t'intéresse?
vous pouvez décrire le fonctionnement spécifique attendu ?
l'utilisateur ne rentre rien, l'arduino sert juste à afficher les N° de départements de manière aléatoire mais sans répétition et les boutons servent juste comme compteurs de point - c'est ça ?
Le but de ce programme est de crée un programme pour apprendre les départements français. Le jeu consiste à afficher un département sur l’écran LCD puis on a décompte de 3s sur l’afficheur 7-segments. Ensuite la réponse s’affiche et si l’utilisateur a donné parlement la bonne réponse, il appuie sur le bouton poussoir pour compter ces pts.
Lors du lancement du programme, j’affiche les consignes du jeu sur l’écran LCD. On a une LED verte allume qui se trouve prêt du 1er bouton poussoir. Pour commencer le jeu, l’utilisateur doit appuyé sur le 1er bouton poussoir de la LED verte.
Le jeu démarre.
On prends un nombre aléatoire compris entre 0 et la taille de la liste des départements -1. Ce nombre correspondra a l’indice du département qu’on prendra dans la liste. Ensuite on retire cette élément de la liste des numéros de département. De cette manière un même département ne peut être appelé 2 fois.
Une fois le numéros du département affiché et le décompte de 3 seconde. On affiche le nom du département correspondant au numéro. C’est à ce moment qu’intervient les deux autres boutons poussoirs. Qui sert à comptabiliser les points de 2 joueurs
Est ce que c’est plus claire ?
Vous oubliez les départements d'outre mer -la Réunion a pour numéro 974; là le stockage par numéro (qui ne permettait aux Corses que de massacre un préfet à la fois) devient pafaitemet inefficace... Il faut mettre une clef sur 3 caractères, coincidant avec les numéros de déprtement uniquement en France Metropolitaine.
Pour arriver à saisir rapidement une telle clef dans un jeu avec seulement des boutons et un LCD à deux lignes, ça risque d'être héroîque...
Un peu comme la fonction tirageAvecRemise (pour PC/RPi) cidessous:
#ifdef PC
#include <stdint.h>
#include <stdio.h>
#include <math.h>
/* PC est une option transmise à la compilation g++ -DPC ...
#endif
constexpr uint8_t TAILLELIBELLE = 40;
constexpr uint8_t TAILLECLE = 4;
struct Departement {
// const uint8_t numero;
const char code[TAILLECLE +1 ]; // 3 pour l'OutreMer + 1 pour null terninated
const char nom[TAILLELIBELLE];
};
#ifdef PC
static const Departement lesDepartements[] = {
#else
static const Departement lesDepartements[] PROGMEM = {
#endif
{" 1", "Ain"},
{" 2", "Aisne"},
{" 3", "Allier"},
{" 4", "Alpes-de-Haute-Provence"},
{" 5", "Hautes-Alpes"},
{"2A", "Corse du Nord"},
{"2B", "Corse du Sud"},
{"2582", "Iles de la Desolation /Kerguelen"},
{"974", "La Reunion"}
};
void tirageAvecRemise(const int taille, const int longueurUtile,
uint16_t numeros[]) {
int lg = taille;
for (uint8_t i = 0; i < longueurUtile; i++) {
#ifdef PC
uint16_t aEchanger = i + rand() % lg;
#else
afaire = pour arduino // rand n'et pas le même AFAIK
#endif
uint16_t aux = numeros[aEchanger];
numeros[aEchanger] = numeros[i];
numeros[i] = aux;
#ifdef PC
printf("%d {%d %d} ",aEchanger, numeros[i], numeros[aEchanger]);
#endif
lg--;
}
}
#ifdef PC
void imprimer(uint16_t numero) {
printf("%s %s\n", lesDepartements[numero].code,
lesDepartements[numero].nom);
}
int main() {
const int taille = sizeof(lesDepartements) / sizeof(lesDepartements[0]) ;
printf("Taille : %d\n", taille);
uint16_t numeros[taille];
// uint8_t unusedTest =5; // teste le Makefile
for (uint8_t i = 0; i < taille; i++) numeros[i] = i;
tirageAvecRemise(taille, taille, numeros);
#ifdef yyy
for (uint8_t i = 0; i < taille; i++) {
uint16_t aEchanger = i + rand() % longueurUtile;
printf("%d ", aEchanger);
uint16_t aux = numeros[aEchanger];
numeros[aEchanger] = numeros[i];
numeros[i] = aux;
printf("{%d %d} ", numeros[i], numeros[aEchanger]);
longueurUtile--;
}
#endif
printf("\n");
for (uint8_t i = 0; i < taille; i++) imprimer(numeros[i]);
return(0);
}
#endif
A noter que si vous mettez une temporisation fixe entre l'affichage de deux departements, quelqu'un ayant le sens du rythme peut gagner" en répondant machinalement -un peu comme dans les Temps Modernes- (et il n'apprendra certainement pas les départements). Mettre des départements fantaisistes, avec une structure de données à peine plus compliquée, permet d'éviter de donner un bon score à cette réponse machinale
dans le wokwi que j'ai posté précédemment j'ai pris une approche différente : je remplis comme vous un tableau dans l'ordre de 0 au nombre de départements moins un et j'applique ensuite un mélange (dit de Fisher-Yates) sur le tableau. Je n'ai ensuite qu'à parcourir ce tableau en l'utilisant comme table d'indirection pour parcourir tous les départements qu'une seule fois, dans un ordre aléatoire. ça évite d'avoir à remettre en ordre le tableau à chaque fois.