Table des matières:
- Étape 1: Configurer la carte
- Étape 2: ajouter le bouton et la résistance
- Étape 3: Connexions des boutons
- Étape 4: Le code…
- Étape 5: Un peu de rebond
- Étape 6: La confection d'un menu
- Étape 7: Répartition du code - Global
- Étape 8: Répartition du code - Configuration et fonctions personnalisées
- Étape 9: La boucle…
- Étape 10: Bloc de code final
Vidéo: Un menu dans Arduino et comment utiliser les boutons : 10 étapes (avec images)
2024 Auteur: John Day | [email protected]. Dernière modifié: 2024-01-30 09:08
Dans mon tutoriel Arduino 101, vous apprendrez à configurer votre environnement dans Tinkercad. J'utilise Tinkercad car c'est une plate-forme en ligne assez puissante qui me permet de démontrer un éventail de compétences aux étudiants pour la construction de circuits. N'hésitez pas à construire tous mes tutoriels en utilisant l'IDE Arduino et un vrai Arduino !
Dans ce tutoriel, nous allons découvrir les boutons ! Nous avons besoin de savoir:
- Comment les câbler
- Lire leur valeur
- Debounce, et pourquoi c'est important
- Une application pratique (création d'un menu)
La plupart des gens pensent que la chose la plus pratique à faire avec un bouton est d'allumer et d'éteindre une lumière. Nous le ferons, pas ici ! Nous allons utiliser le nôtre pour créer un menu et définir quelques options sur l'Arduino.
Prêt? Commençons!
Étape 1: Configurer la carte
La première étape consiste à placer un Arduino et une Breadboard Small sur la zone de prototypage. Consultez les images ci-dessus pour voir comment câbler les rails d'alimentation.
Un Breadboard Mini a deux rails d'alimentation en haut et en bas. Nous les connectons à l'Arduino afin de pouvoir alimenter davantage de composants. Plus tard dans ce tutoriel, nous utiliserons 3 boutons, nous aurons donc besoin de plus de puissance. La chose à noter est que sur une petite planche à pain, les rails d'alimentation traversent la planche, horizontalement. Ceci est différent des colonnes de la zone de prototypage principale au milieu; ceux-ci fonctionnent verticalement. Vous pouvez utiliser n'importe laquelle des broches d'alimentation pour alimenter n'importe quelle colonne de la zone principale au milieu.
Lorsque vous ajoutez de l'alimentation, utilisez des fils noir et rouge respectivement pour le négatif et le positif. Ajoutez des fils à l'extrémité qui alimentent l'autre côté de la carte. Nous n'utiliserons pas ce côté, mais c'est une bonne pratique.
Étape 2: ajouter le bouton et la résistance
Ajoutez un petit bouton poussoir depuis le plateau des composants. Il devrait ressembler à celui de l'image. Assurez-vous que ce n'est pas un interrupteur ! Ajoutez également une résistance. Cliquez dessus et définissez sa valeur sur 10kΩ. C'est suffisant pour tirer la broche vers le bas lorsqu'elle n'est pas connectée, ce qui est très important plus tard dans le code.
Placez le composant au milieu de la planche à pain. Le fonctionnement d'un bouton est le suivant:
- D'un coin à l'autre, le bouton n'est pas connecté. Appuyer sur le bouton ferme les contacts et relie les coins.
- Les côtés du bouton sont connectés. Si vous avez connecté un fil en haut à gauche et en bas à gauche, le circuit serait fermé.
C'est pourquoi nous plaçons le composant à travers l'espace au milieu. Il s'assure que les coins ne sont pas connectés sous les broches de la carte.
L'étape suivante fournit quelques images qui illustrent ces points.
Placez la résistance de la broche en bas à droite sur les colonnes, de sorte qu'elle se trouve horizontalement.
Étape 3: Connexions des boutons
Les images ci-dessus montrent assez clairement comment les boutons se connectent. C'était toujours un point de confusion quand vous pensez que quelque chose est tout bon et que cela ne fonctionne pas !
Maintenant, ajoutons les fils.
- Placez un fil rouge d'une broche d'alimentation positive à la même colonne que la broche en bas à droite sur le bouton
- Placez un fil noir d'une broche d'alimentation négative à la même colonne que la résistance.
- Placez un fil de couleur (pas rouge/noir) de la broche en haut à gauche à la broche numérique 2 sur l'Arduino
Vérifiez les images ci-dessus pour vous assurer que votre câblage est correct.
Étape 4: Le code…
Regardons le code d'un bouton de base.
Ouvrez l'éditeur de code et passez de Blocks à Text. Effacez l'avertissement qui s'affiche. Nous sommes satisfaits du texte !
Vous connaissez la configuration de base, définissons donc le bouton et effectuons une lecture de base. Nous imprimerons la sortie sur Serial.
J'ai mis quelques commentaires supplémentaires dans le code ci-dessous afin qu'il soit plus facile à lire que l'image.
// Définir des constantes
#define button 2 void setup() { pinMode(button, INPUT); Serial.begin(9600); } void loop() { // Lire la broche numérique pour vérifier l'état du bouton int pressé = digitalRead(button); // Le bouton renvoie HIGH s'il est enfoncé, LOW sinon si (appuyé == HIGH){ Serial.println("Pressed!"); } }
Bon ben ça marche !
Essentiellement, tout ce que nous faisons est de vérifier l'état de la broche numérique à chaque fois que le code boucle. Si vous cliquez sur Démarrer la simulation et appuyez sur le bouton, vous verrez le moniteur série (cliquez sur le bouton sous le code) afficher "Appuyé!" à plusieurs reprises.
Une fonctionnalité que vous verrez dans le code ci-dessus est l'évaluation de la condition if(). Tout ce que fait le code, c'est poser une question et évaluer si c'est vrai, dans ce cas. Nous utilisons le est égal (double signe égal, comme ceci: ==) pour vérifier si la valeur de la variable est égale à une certaine valeur. Un digitalRead() renvoie soit HIGH soit LOW.
En utilisant if() else if / else, nous pouvons vérifier de nombreuses conditions ou toutes les conditions, et si vous revenez aux bases d'Arduino, vous verrez certaines des comparaisons que vous pouvez faire.
Maintenant… Notre code peut sembler complet… Mais nous avons un problème.
Vous voyez, cela fonctionne très bien dans le simulateur. Mais la vraie électricité a du bruit, en particulier l'électronique à courant continu. Ainsi, notre bouton peut parfois renvoyer une fausse lecture. Et c'est un problème, car votre projet peut ne pas répondre de la bonne manière pour l'utilisateur.
Réparons-le !
Étape 5: Un peu de rebond
Nous utilisons une procédure appelée debounce pour surmonter notre problème de bouton. Cela attend essentiellement un laps de temps spécifié entre le moment où le bouton a été enfoncé et la réponse réelle à la pression. Cela semble toujours naturel pour l'utilisateur (à moins que le temps ne soit trop long). Vous pouvez également l'utiliser pour vérifier la longueur de la presse, afin que vous puissiez répondre différemment à chaque fois. Vous n'avez pas besoin de changer le câblage !
Regardons le code:
#define button 2#define debounceTimeout 100
Le premier changement concerne le périmètre global. Vous vous souviendrez que c'est là que nous définissons les variables que beaucoup de nos fonctions peuvent utiliser ou celles qui ne peuvent pas être réinitialisées à chaque fois que la boucle se déclenche. Nous avons donc ajouté debounceTimeout aux constantes définies. Nous avons fait ce 100 (qui se traduira plus tard par 100 ms), mais il pourrait être plus court. Plus longtemps et cela ne semblera pas naturel.
long int lastDebounceTime;
Cette variable est déclarée sous les constantes. Il s'agit d'un type int long, qui nous permet essentiellement de stocker des nombres longs en mémoire. Nous l'avons appelé lastDebounceTime.
Nous n'avons pas besoin de changer quoi que ce soit dans la fonction void setup(). Laissons celui-là.
void loop() { // Lire la broche numérique pour vérifier l'état du bouton int pressed = digitalRead(button); long int currentTime = millis(); //Code du bouton }
Le premier changement que nous apportons à la fonction loop() est sous l'appel pour lire le bouton. Nous devons garder une trace de l'heure actuelle. La fonction millis () renvoie l'heure actuelle de l'horloge depuis le démarrage de l'Arduino en millisecondes. Nous devons stocker cela dans une variable de type int long.
Maintenant, nous devons nous assurer que nous connaissons le temps écoulé depuis que le bouton a été enfoncé, nous réinitialisons donc la minuterie lorsqu'elle n'est pas enfoncée. Regarde:
void loop() { // Lire la broche numérique pour vérifier l'état du bouton int pressed = digitalRead(button); long int currentTime = millis(); if(pressed == LOW){ // Réinitialise le temps de comptage tant que le bouton n'est pas enfoncé lastDebounceTime = currentTime; } // Code du bouton }
L'algorithme if(pressed == LOW) vérifie si le bouton n'est pas enfoncé. Si ce n'est pas le cas, le code stocke l'heure actuelle depuis le dernier anti-rebond. De cette façon, chaque fois que le bouton est enfoncé, nous avons un moment à partir duquel nous pouvons vérifier quand le bouton a été enfoncé. Nous pouvons ensuite faire un calcul mathématique rapide pour voir combien de temps le bouton a été enfoncé et répondre correctement. Regardons le reste du code:
void loop() { // Lire la broche numérique pour vérifier l'état du bouton int pressed = digitalRead(button); long int currentTime = millis(); if(pressed == LOW){ // Réinitialise le temps de comptage tant que le bouton n'est pas enfoncé lastDebounceTime = currentTime; } // Le bouton a été enfoncé pendant un temps donné if(((currentTime - lastDebounceTime) > debounceTimeout)){ // Si le délai est atteint, le bouton est enfoncé ! Serial.println("Appuyé !"); } }
Le dernier bloc de code prend l'heure actuelle, soustrait le dernier temps anti-rebond et le compare au délai d'attente que nous avons défini. S'il est supérieur, le code suppose que le bouton a été enfoncé pendant ce temps et répond. Soigné!
Exécutez votre code et vérifiez qu'il fonctionne. Si vous avez des erreurs, vérifiez votre code !
Voyons maintenant un exemple pratique.
Étape 6: La confection d'un menu
Les boutons sont intéressants, car il y a tellement de possibilités avec eux ! Dans cet exemple, nous allons créer un menu. Disons que vous avez créé cet appareil vraiment génial et que vous avez besoin que les utilisateurs puissent modifier les options pour activer ou désactiver certaines choses, ou définir une valeur particulière pour un paramètre. Cette conception à trois boutons peut le faire !
Donc, pour ce projet, nous avons besoin de:
- Trois boutons
- Trois résistances réglées sur 10kΩ
Nous en avons déjà un, nous avons juste besoin des deux autres. Alors ajoutez-les au tableau. Le câblage est un peu plus complexe, mais uniquement parce que je voulais le garder vraiment compact. Vous pouvez suivre le même modèle pour le premier bouton, ou suivre l'image ci-dessus.
Les trois boutons sont une option d'ouverture/suivant du menu, une option de modification (comme dans, modifier le paramètre) et un bouton d'enregistrement/fermeture du menu.
Branchez-le, regardons le code !
Étape 7: Répartition du code - Global
Ok, ça va être une longue étape, mais je vais passer en revue chaque section de code.
Tout d'abord, examinons les variables globales nécessaires.
// Définir les constantes#define menuButton 2 #define menuSelect 3#define menuSave 4 #define debounceTimeout 50 // Définir les variables int menuButtonPreviousState = LOW; int menuSelectPreviousState = LOW; int menuSavePreviousState = LOW; long int lastDebounceTime; // Options de menu char * menuOptions = {"Vérifier la température", "Vérifier la lumière"}; bool featureSetting = {false, false}; bool menuMode = false; bool menuNeedsPrint = false; int optionSélectionné = 0;
Ces trois blocs sont assez similaires à ce que nous avons vu auparavant. Dans le premier, j'ai défini les trois boutons et le délai d'attente. Pour cette partie du projet, je l'ai réglé sur 50 ms, il faut donc une pression délibérée pour que cela fonctionne.
Le deuxième bloc contient toutes les variables. Nous devons garder une trace du buttonPreviousState, et nous devons garder une trace du lastDebounceTime. Ce sont toutes des variables de type int, mais la dernière est de type long car je suppose que nous avons besoin d'espace en mémoire.
Le bloc d'options de menu a quelques nouvelles fonctionnalités. Tout d'abord, le caractère * (oui, c'est un astérisque délibéré), qui est une variable littérale de caractère/chaîne. C'est un pointeur vers un stockage statique en mémoire. Vous ne pouvez pas le modifier (comme vous le pouvez en Python, par exemple). Cette ligne char *menuOptions crée un tableau de littéraux de chaîne. Vous pouvez ajouter autant d'éléments de menu que vous le souhaitez.
La variable bool featureSetting n'est que le tableau de valeurs qui représente chaque élément de menu. Oui, vous pouvez stocker tout ce que vous voulez, changez simplement le type de variable (elles doivent toutes être du même type). Maintenant, il existe peut-être de meilleures façons de gérer cela, comme des dictionnaires ou des tuples, mais c'est simple pour cette application. Je créerais probablement l'un de ces derniers dans une application déployée.
J'ai gardé une trace du menuMode, donc si je voulais d'autres choses sur mon écran, je pourrais le faire. De plus, si j'avais une logique de capteur, je pourrais la mettre en pause pendant le fonctionnement du menu, juste au cas où quelque chose entrerait en conflit. J'ai une variable menuNeedsPrint parce que je veux imprimer le menu à des moments précis, pas seulement tout le temps. Enfin, j'ai une variable optionSelected, je peux donc garder une trace de l'option sélectionnée lorsque j'y accède à plusieurs endroits.
Regardons le prochain ensemble de fonctions.
Étape 8: Répartition du code - Configuration et fonctions personnalisées
La fonction setup() est assez simple, juste trois déclarations d'entrée:
void setup() { pinMode(menuSelect, INPUT); pinMode(menuEnregistrer, INPUT); pinMode(menuSelect, INPUT); Serial.begin(9600); }
Viennent ensuite les trois fonctions personnalisées. Regardons les deux premiers, puis le dernier séparément.
Nous avons besoin de deux fonctions qui renvoient des informations. La raison en est que nous voulons nous assurer que cela est en quelque sorte lisible par l'homme. Cela aidera également à déboguer le code si nous avons un problème. Code:
// Fonction pour retourner l'optionchar actuellement sélectionnée *ReturnOptionSelected(){ char *menuOption = menuOptions[optionSelected]; // Return optionSelected return menuOption; } // Fonction pour renvoyer l'état de l'option actuellement sélectionnée char *ReturnOptionStatus(){ bool optionSetting = featureSetting[optionSelected]; char *optionSettingVal; if (optionSetting == false){ optionSettingVal = "False"; }else{ optionSettingVal = "True"; } // Retour optionSetting return optionSettingVal; }
La fonction char *ReturnOptionSelected() vérifie l'option sélectionnée (si vous voyez ci-dessus, nous définissons une variable pour en garder une trace) et extrait le littéral de chaîne du tableau que nous avons créé précédemment. Il le renvoie ensuite sous forme de type char. Nous le savons car la fonction indique le type de retour.
La deuxième fonction, char *ReturnOptionStatus() lit l'état de l'option enregistrée dans le tableau et renvoie un littéral de chaîne qui représente la valeur. Par exemple, si le paramètre que nous avons stocké est false, je retournerais "False". C'est parce que nous montrons à l'utilisateur cette variable et il est préférable de garder toute cette logique ensemble. Je pourrais le faire plus tard, mais il est plus logique de le faire ici.
// Fonction pour basculer l'option actuellebool ToggleOptionSelected(){ featureSetting[optionSelected] = !featureSetting[optionSelected]; renvoie vrai; }
La fonction bool ToggleOptionSelected() est une fonction pratique pour modifier la valeur du paramètre que nous avons sélectionné dans le menu. Il renverse juste la valeur. Si vous aviez un ensemble d'options plus complexe, cela pourrait être très différent. Je retourne vrai dans cette fonction, car mon rappel (l'appel plus tard dans le code qui déclenche cette fonction) attend une réponse vrai/faux. Je suis sûr à 100% que cela fonctionnera, donc je n'ai pas tenu compte du fait que cela ne fonctionnait pas, mais je le ferais dans une application déployée (juste au cas où).
Étape 9: La boucle…
La fonction loop() est assez longue, nous allons donc le faire en plusieurs parties. Vous pouvez supposer que tout ce qui suit est imbriqué dans cette fonction:
boucle vide() {
// Travaillez ici <----- }
D'accord, nous avons déjà vu ce genre de choses:
// Lecture des boutons int menuButtonPressed = digitalRead(menuButton); int menuSelectPressed = digitalRead(menuSelect); int menuSavePressed = digitalRead(menuSave); // Récupère l'heure actuelle long int currentTime = millis(); if(menuButtonPressed == LOW && menuSelectPressed == LOW && menuSavePressed == LOW){ //Réinitialise le temps de comptage tant que le bouton n'est pas enfoncé lastDebounceTime = currentTime; menuButtonPreviousState = FAIBLE; menuSelectPreviousState = LOW; menuSavePreviousState = LOW; }
Tout ce que j'avais à faire ici était d'ajouter les trois appels digitalRead() et de m'assurer que j'avais pris en compte le fait que si tous les boutons étaient bas, nous devions réinitialiser la minuterie (lastDebounceTime = currentTime) et définir tous les états précédents sur bas. Je stocke également millis() dans currentTime.
La section suivante s'emboîte à l'intérieur de la ligne
if(((currentTime - lastDebounceTime) > debounceTimeout)){
// Travaillez ici <---- }
Il y a trois sections. Oui, j'aurais pu les déplacer dans leurs propres fonctions, mais par souci de simplicité, j'ai conservé les trois algorithmes de boutons principaux ici.
if((menuButtonPressed == HIGH) && (menuButtonPreviousState == LOW)){ if(menuMode == false){ menuMode = true; // Informez l'utilisateur Serial.println("Le menu est actif"); }else if (menuMode == true && optionSelected = 1){ // Réinitialiser l'option optionSelected = 0; } // Imprimer le menu menuNeedsPrint = true; // Bascule le bouton prec. état pour afficher uniquement le menu // si le bouton est relâché et appuyé à nouveau menuButtonPreviousState = menuButtonPressed; // Serait ÉLEVÉ }
Ce premier gère lorsque menuButtonPressed est HIGH, ou lorsque le bouton de menu est enfoncé. Il vérifie également que l'état précédent était BAS, de sorte que le bouton devait être relâché avant d'être à nouveau enfoncé, ce qui empêche le programme de déclencher constamment le même événement encore et encore.
Il vérifie alors que si le menu n'est pas actif, il l'active. Il imprimera la première option sélectionnée (qui est le premier élément du tableau menuOptions par défaut. Si vous appuyez sur le bouton une deuxième ou une troisième (etc.), vous obtiendrez l'option suivante dans la liste. Quelque chose que je pourrais corriger est que lorsqu'il arrive à la fin, il revient au début. Cela pourrait lire la longueur du tableau et faciliter le retour en arrière si vous modifiiez le nombre d'options, mais c'était simple pour le moment.
La dernière petite section (//Imprime le menu) imprime évidemment le menu, mais elle définit également l'état précédent sur HAUT afin que la même fonction ne boucle pas (voir ma note ci-dessus pour vérifier si le bouton était auparavant BAS).
// menuSelect est pressé, fournir logicif((menuSelectPressed == HIGH) && (menuSelectPreviousState == LOW)){ if(menuMode){ // Changer l'option sélectionnée // Pour le moment, c'est juste vrai/faux // mais pourrait être n'importe quoi bool toggle = ToggleOptionSelected(); if(toggle){ menuNeedsPrint = true; }else{ Serial.println("Une erreur s'est produite. Veuillez réessayer"); } } // Basculer l'état pour basculer uniquement s'il est relâché et pressé à nouveau menuSelectPreviousState = menuSelectPressed; }
Ce morceau de code gère le bouton menuSelectPressed de la même manière, sauf que cette fois nous déclenchons simplement la fonction ToggleOptionSelected(). Comme je l'ai déjà dit, vous pouvez modifier cette fonction pour qu'elle en fasse plus, mais c'est tout ce dont j'ai besoin.
La principale chose à noter est la variable toggle, qui suit le succès du rappel et imprime le menu si vrai. S'il ne renvoie rien ou faux, il imprimera le message d'erreur. C'est là que vous pouvez utiliser votre rappel pour faire d'autres choses.
if((menuSavePressed == HIGH) && (menuSavePreviousState == LOW)){ // Quittez le menu // Ici, vous pouvez faire n'importe quel rangement // ou enregistrer dans l'EEPROM menuMode = false; Serial.println("Menu quitté"); // Bascule l'état pour que le menu ne se ferme qu'une seule fois menuSavePreviousState = menuSavePressed; } }
Cette fonction gère le bouton menuSave, qui ne fait que quitter le menu. C'est là que vous pouvez avoir une option d'annulation ou d'enregistrement, peut-être faire un peu de nettoyage ou enregistrer dans l'EEPROM. Je viens d'imprimer "Menu quitté" et de régler l'état du bouton sur ÉLEVÉ pour qu'il ne boucle pas.
if(menuMode && menuNeedsPrint){ // Nous avons imprimé le menu, donc à moins qu'il ne se passe // quelque chose, pas besoin de l'imprimer à nouveau menuNeedsPrint = false; char *optionActive = ReturnOptionSelected(); char *optionStatus = ReturnOptionStatus(); Serial.print("Sélectionné: "); Serial.print(optionActive); Serial.print(": "); Serial.print(optionStatus); Serial.println(); }
Il s'agit de l'algorithme menuPrint, qui ne se déclenche que lorsque le menu est actif et lorsque la variable menuNeedsPrint est définie sur true.
Cela pourrait certainement être déplacé vers sa propre fonction, mais par souci de simplicité..!
Eh bien c'est ça! Voir l'étape suivante pour l'ensemble du bloc de code.
Étape 10: Bloc de code final
// Définir des constantes
#define menuButton 2 #define menuSelect 3 #define menuSave 4 #define debounceTimeout 50 int menuButtonPreviousState = LOW; int menuSelectPreviousState = LOW; int menuSavePreviousState = LOW; // Définit les variables long int lastDebounceTime; bool lightSensor = true; bool tempSensor = true; // Options de menu char * menuOptions = {"Vérifier la température", "Vérifier la lumière"}; bool featureSetting = {false, false}; bool menuMode = false; bool menuNeedsPrint = false; int optionSélectionné = 0; // Fonction de configuration
void setup() { pinMode(menuSelect, INPUT); pinMode(menuEnregistrer, INPUT); pinMode(menuSelect, INPUT); Serial.begin(9600); }
// Fonction pour retourner l'option actuellement sélectionnée char *ReturnOptionSelected(){ char *menuOption = menuOptions[optionSelected]; // Return optionSelected return menuOption; } // Fonction pour renvoyer l'état de l'option actuellement sélectionnée char *ReturnOptionStatus(){ bool optionSetting = featureSetting[optionSelected]; char *optionSettingVal; if (optionSetting == false){ optionSettingVal = "False"; }else{ optionSettingVal = "True"; } // Retour optionSetting return optionSettingVal; } // Fonction pour basculer l'option actuelle bool ToggleOptionSelected(){ featureSetting[optionSelected] = !featureSetting[optionSelected]; renvoie vrai; } // La boucle principale
void loop(){ // Lire les boutons int menuButtonPressed = digitalRead(menuButton); int menuSelectPressed = digitalRead(menuSelect); int menuSavePressed = digitalRead(menuSave); // Récupère l'heure actuelle long int currentTime = millis(); if(menuButtonPressed == LOW && menuSelectPressed == LOW && menuSavePressed == LOW){ //Réinitialise le temps de comptage tant que le bouton n'est pas enfoncé lastDebounceTime = currentTime; menuButtonPreviousState = FAIBLE; menuSelectPreviousState = LOW; menuSavePreviousState = LOW; } if(((currentTime - lastDebounceTime) > debounceTimeout)){ // Si le délai d'attente est atteint, bouton enfoncé !
// menuButton est pressé, fournir la logique
// Ne se déclenche que lorsque le bouton a été préalablement relâché if((menuButtonPressed == HIGH) && (menuButtonPreviousState == LOW)){ if(menuMode == false){ menuMode = true; // Informez l'utilisateur Serial.println("Le menu est actif"); }else if (menuMode == true && optionSelected = 1){ // Réinitialiser l'option optionSelected = 0; } // Imprimer le menu menuNeedsPrint = true; // Bascule le bouton prec. état pour afficher uniquement le menu // si le bouton est relâché et appuyé à nouveau menuButtonPreviousState = menuButtonPressed; // Serait HAUT } // menuSelect est pressé, fournir la logique if((menuSelectPressed == HIGH) && (menuSelectPreviousState == LOW)){ if(menuMode){ // Changer l'option sélectionnée // Pour le moment, c'est juste vrai/faux // mais peut être n'importe quoi bool toggle = ToggleOptionSelected(); if(toggle){ menuNeedsPrint = true; }else{ Serial.print("Une erreur s'est produite. Veuillez réessayer"); } } // Basculer l'état pour basculer uniquement s'il est relâché et pressé à nouveau menuSelectPreviousState = menuSelectPressed; } if((menuSavePressed == HIGH) && (menuSavePreviousState == LOW)){ // Quitter le menu // Ici, vous pouvez faire n'importe quel rangement // ou enregistrer dans l'EEPROM menuMode = false; Serial.println("Menu quitté"); // Bascule l'état pour que le menu ne se ferme qu'une seule fois menuSavePreviousState = menuSavePressed; } } // Imprime l'option de menu actuelle active, mais ne l'imprime qu'une seule fois if(menuMode && menuNeedsPrint){ // Nous avons imprimé le menu, donc à moins qu'il ne se passe // quelque chose, pas besoin de l'imprimer à nouveau menuNeedsPrint = false; char *optionActive = ReturnOptionSelected(); char *optionStatus = ReturnOptionStatus(); Serial.print("Sélectionné: "); Serial.print(optionActive); Serial.print(": "); Serial.print(optionStatus); Serial.println(); } } }
Le circuit est disponible sur le site Tinkercad. J'ai intégré le circuit ci-dessous pour que vous puissiez le voir aussi !
Comme toujours, si vous avez des questions ou des problèmes, n'hésitez pas à me le faire savoir !
Conseillé:
Comment utiliser le moteur pas à pas 28BYJ-48 avec 3 boutons-poussoirs : 5 étapes
Comment utiliser le moteur pas à pas 28BYJ-48 avec 3 boutons poussoirs : Voulez-vous contrôler votre moteur pas à pas à l'aide de boutons poussoirs ? Cela peut faire dans le sens horaire, dans le sens inverse des aiguilles d'une montre, puis dans la fonction d'arrêt ? Alors cette vidéo est pour toi
Comment utiliser le module de boutons avec SkiiiD : 9 étapes
Comment utiliser le module de boutons avec SkiiiD: Ce projet est une instruction de "comment utiliser le buzzer HW-508 (applicable pour KY-006) avec Arduino via skiiiDBavant de démarrer, ci-dessous est un tutoriel de base sur l'utilisation de skiiiD https:// www.instructables.com/id/Getting-Started-With-SkiiiD-Editor
Comment utiliser un piézo pour produire un son : les bases : 4 étapes (avec des images)
Comment utiliser un piézo pour produire le son Un Piezo est un appareil électronique qui peut être utilisé à la fois pour produire et détecter du son. Applications : Vous pouvez utiliser le même circuit pour jouer
Comment utiliser le terminal Mac et comment utiliser les fonctions clés : 4 étapes
Comment utiliser le terminal Mac et comment utiliser les fonctions clés : Nous allons vous montrer comment ouvrir le terminal MAC. Nous vous montrerons également quelques fonctionnalités du terminal, telles que ifconfig, le changement de répertoire, l'accès aux fichiers et arp. Ifconfig vous permettra de vérifier votre adresse IP, et votre annonce MAC
Gérez 100 appareils dans les applications, les organisations, les rôles et les utilisateurs Ubidots : 11 étapes
Gérer 100 appareils dans les applications, les organisations, les rôles et les utilisateurs d'Ubidots : à cette occasion, j'ai décidé de tester la fonctionnalité de la plate-forme IoT Ubidots pour la gestion des utilisateurs dans le cas où elle aurait de nombreux appareils pour plusieurs organisations ou entreprises sous la même Plateforme Ubidots. Information du maire : vous