Taula de continguts:

Un menú a Arduino i com utilitzar els botons: 10 passos (amb imatges)
Un menú a Arduino i com utilitzar els botons: 10 passos (amb imatges)

Vídeo: Un menú a Arduino i com utilitzar els botons: 10 passos (amb imatges)

Vídeo: Un menú a Arduino i com utilitzar els botons: 10 passos (amb imatges)
Vídeo: Аномально вкусно‼️ ЧЕХОСЛОВАЦКИЙ СУП ИЗ ФАРША. Жена Липована в шоке. 2024, Desembre
Anonim
Un menú a Arduino i com s’utilitzen els botons
Un menú a Arduino i com s’utilitzen els botons

Al meu tutorial Arduino 101, se us ensenyarà a configurar el vostre entorn a Tinkercad. Utilitzo Tinkercad perquè és una plataforma en línia bastant potent que em permet demostrar una àmplia gamma d’habilitats als estudiants per construir circuits. Siéntase lliure de crear tots els meus tutorials amb Arduino IDE i un autèntic Arduino.

En aquest tutorial, coneixerem els botons. Hem de saber:

  • Com connectar-los
  • Llegint el seu valor
  • Debounce i per què és important
  • Una aplicació pràctica (creació d'un menú)

La majoria de la gent pensa que el més pràctic amb un botó és encendre i apagar el llum. Ho farem, no aquí! Utilitzarem el nostre per crear un menú i establir algunes opcions a l’Arduino.

A punt? Comencem!

Pas 1: configureu el tauler

Configureu el tauler
Configureu el tauler
Configureu el tauler
Configureu el tauler

El primer pas és posar un Arduino i Breadboard Small a la zona de prototipatge. Consulteu les imatges anteriors per veure com connectar els rails elèctrics.

Un Breadboard Mini té dos carrils superiors i inferiors. Els connectem fins a l’Arduino per poder alimentar més components. Més endavant en aquest tutorial utilitzarem 3 botons, de manera que necessitarem més energia. El que cal tenir en compte és que, en una taula petita, els rails elèctrics travessen el tauler horitzontalment. Això és diferent a les columnes de la zona principal de prototipatge al centre; aquests funcionen verticalment. Podeu utilitzar qualsevol dels pins d'alimentació per proporcionar energia a qualsevol columna de la zona principal del centre.

Quan afegiu energia, utilitzeu cables negres i vermells al negatiu i al positiu respectivament. Afegiu cables al final que funcionen a l'altre costat del tauler. No utilitzarem aquest costat, però és una bona pràctica.

Pas 2: afegiu el botó i la resistència

Afegiu el botó i la resistència
Afegiu el botó i la resistència
Afegiu el botó i la resistència
Afegiu el botó i la resistència
Afegiu el botó i la resistència
Afegiu el botó i la resistència

Afegiu un petit polsador a la safata de components. Ha de semblar el de la imatge. Assegureu-vos que no és un interruptor. Afegiu una resistència també. Feu-hi clic i establiu-ne el valor a 10 kΩ. N’hi ha prou per tirar el pin baix quan no està connectat, cosa que és molt important més endavant al codi.

Col·loqueu el component a la meitat de la taula de treball. La manera com funciona un botó és:

  • De cantonada a cantonada, el botó no està connectat. En prémer el botó es tanquen els contactes i es connecten les cantonades.
  • Els costats del botó estan connectats. Si connectés un cable a la part superior esquerra i inferior esquerra, el circuit es tancaria.

Per això, posem el component a través de l’espai al centre. Assegura que les cantonades no estan connectades sota els pins del tauler.

El següent pas proporciona un parell d’imatges que il·lustren aquests punts.

Col·loqueu la resistència des del pin inferior dret a través de les columnes, de manera que quedi horitzontalment.

Pas 3: botó de connexions

Connexions de botons
Connexions de botons
Connexions de botons
Connexions de botons

Les imatges anteriors deixen bastant clar com es connecten els botons. Sempre va ser un punt de confusió quan penses que alguna cosa està bé i no funciona.

Ara, afegim els cables.

  • Col·loqueu un cable vermell des d'un pin d'alimentació positiva a la mateixa columna que el pin inferior dret del botó
  • Col·loqueu un cable negre des d’un pin negatiu a la mateixa columna que la resistència.
  • Col·loqueu un cable de color (no vermell / negre) des del pin superior esquerre al pin digital 2 de l'Arduino

Comproveu les imatges anteriors per assegurar-vos que el cablejat sigui correcte.

Pas 4: el codi …

El codi…
El codi…
El codi…
El codi…

Vegem el codi d’un botó bàsic.

Obriu l’editor de codi i canvieu de blocs a text. Esborreu l'advertència que apareix. Estem contents amb el text.

Coneixeu la configuració bàsica, així que definim el botó i fem una lectura bàsica. Imprimirem la sortida a Serial.

He posat uns quants comentaris addicionals al codi següent perquè sigui més fàcil de llegir que la imatge.

// Definiu constants

#define button 2 void setup () {pinMode (botó, INPUT); Serial.begin (9600); } void loop () {// Llegiu el pin digital per comprovar l'estat del botó int pressionat = digitalRead (botó); // El botó torna ALTA si es prem, BAIX si no (si es prem == ALTA) {Serial.println ("Premut!"); }}

D’acord, bé, això funciona!

Bàsicament, tot el que estem fent és comprovar l’estat del pin digital cada vegada que el codi fa bucles. Si feu clic a Inicia la simulació i premeu el botó, veureu la pantalla Serial Monitor (feu clic al botó que hi ha a sota del codi) "Pressed!" repetidament.

Una característica que veureu al codi anterior és l'avaluació de la condició if () que té lloc. Tot el que fa el codi és fer una pregunta i avaluar si és cert, en aquest cas. Utilitzem el símbol és igual (signes iguals dobles, com aquest: ==) per comprovar si el valor de la variable és igual a un valor determinat. Un digitalRead () retorna HIGH o LOW.

Mitjançant l’if () else if / else podem comprovar moltes condicions o totes les condicions, i si torneu a l’Arduino Basics, veureu algunes de les comparacions que podeu fer.

Ara … El nostre codi pot semblar complet … Però tenim un problema.

Mireu, això funciona molt bé al simulador. Però l’electricitat real té soroll, especialment l’electrònica de corrent continu. Per tant, de vegades el nostre botó pot retornar una lectura falsa. I això és un problema, perquè és possible que el vostre projecte no respongui de la manera correcta a l'usuari.

Arreglem-ho!

Pas 5: una petita desgràcia

Un petit debounce
Un petit debounce

Utilitzem un procediment anomenat debounce per superar el nostre problema de botons. Això, essencialment, espera un temps especificat entre el moment en què es va prémer el botó i la resposta real a l’empenta. Encara se sent natural per a l'usuari (tret que allargueu el temps massa). També podeu utilitzar-lo per comprovar la durada de la premsa, de manera que podeu respondre de manera diferent cada vegada. No cal canviar cap cablejat.

Vegem el codi:

#define button 2 # define debounceTimeout 100

El primer canvi és l’abast global. Recordareu que és on definim les variables que poden utilitzar moltes de les nostres funcions o aquelles que no es poden restablir cada vegada que s’activa el bucle. Per tant, hem afegit debounceTimeout a les constants definides. Hem fet aquest 100 (que més endavant es traduirà a 100 ms), però podria ser més curt. Per més temps i se sentirà antinatural.

long int lastDebounceTime;

Aquesta variable es declara per sota de les constants. Es tracta d’un tipus int long, que bàsicament ens permet emmagatzemar nombres llargs a la memòria. L’hem anomenat lastDebounceTime.

No necessitem canviar res a la funció void setup (). Deixem-ne aquell.

void loop () {// Llegiu el pin digital per comprovar l'estat del botó int pressionat = digitalRead (botó); long int currentTime = millis (); // Codi de botó}

El primer canvi que fem a la funció loop () és sota la trucada per llegir el botó. Hem de fer un seguiment de l’hora actual. La funció millis () retorna l'hora actual del rellotge des que l'Arduino es va iniciar en mil·lisegons. Hem d’emmagatzemar-ho en una variable de tipus int llarga.

Ara hem d’assegurar-nos que som conscients del temps des que es va prémer el botó, de manera que restablim el temporitzador quan no es prem. Fes un cop d'ull:

void loop () {// Llegiu el pin digital per comprovar l'estat del botó int pressionat = digitalRead (botó); long int currentTime = millis (); if (premut == BAIX) {// Restableix el temps de recompte mentre no es prem el botó lastDebounceTime = CurrentTime; } // Codi de botó}

L'algorisme if (pressionat == BAIX) comprova si no es prem el botó. Si no és així, el codi emmagatzema l'hora actual des de l'últim debounce. D’aquesta manera, cada vegada que es prem el botó, tenim un moment en el qual podem comprovar quan s’ha premut el botó. A continuació, podem fer un càlcul matemàtic ràpid per veure quant de temps es va prémer el botó i respondre correctament. Vegem la resta del codi:

void loop () {// Llegiu el pin digital per comprovar l'estat del botó int pressionat = digitalRead (botó); long int currentTime = millis (); if (premut == BAIX) {// Restableix el temps de recompte mentre no es prem el botó lastDebounceTime = CurrentTime; } // El botó s'ha premut durant un temps determinat si (((CurrentTime - lastDebounceTime)> debounceTimeout)) {// Si s'arriba al temps d'espera, premeu el botó. Serial.println ("Premeu!"); }}

L'últim bloc de codi pren l'hora actual, resta l'últim temps de rebounce i el compara amb el temps d'espera que hem establert. Si és més gran, el codi assumeix que el botó s'ha premut durant aquest temps i respon. Neat!

Executeu el codi i comproveu que funcioni. Si teniu errors, comproveu el vostre codi.

Ara, vegem un exemple pràctic.

Pas 6: l'elaboració d'un menú

L’elaboració d’un menú
L’elaboració d’un menú

Els botons són interessants perquè hi ha moltes possibilitats. En aquest exemple, farem un menú. Suposem que heu creat aquest dispositiu realment fantàstic i que necessiteu que els usuaris puguin canviar les opcions per activar o desactivar determinades coses o establir un valor concret per a una configuració. Aquest disseny de tres botons ho pot fer!

Per tant, per a aquest projecte necessitem:

  • Tres botons
  • Tres resistències configurades a 10kΩ

Ja en tenim un, només necessitem els altres dos. Afegiu-los al tauler. El cablejat és una mica més complex, però només perquè volia mantenir-lo molt compacte. Podeu seguir el mateix patró per al primer botó o seguir la imatge superior.

Els tres botons són una opció de menú obert / següent, una opció de canvi (com ara, modifica la configuració) i un botó de menú desa / tanca.

Connecteu-ho, mirem el codi!

Pas 7: Desglossament del codi: global

D’acord, serà un pas llarg, però vaig a revisar cada secció de codi.

En primer lloc, vegem les variables globals necessàries.

// Defineix constants # define menuButton 2 #define menuSelect 3 # define menuSave 4 #define debounceTimeout 50 // Define variables int menuButtonPreviousState = LOW; int menuSelectPreviousState = BAIX; int menuSavePreviousState = BAIX; long int lastDebounceTime; // Opcions del menú char * menuOptions = {"Comprova la temperatura", "Comprova la llum"}; bool featureSetting = {false, false}; bool menuMode = false; bool menuNeedsPrint = fals; int optionSelected = 0;

Aquests tres blocs són bastant similars al que hem vist abans. Al primer, he definit els tres botons i el temps d'espera. Per a aquesta part del projecte, l'he establert a 50 ms, de manera que es necessita una premsa deliberada perquè funcioni.

El segon bloc són totes les variables. Hem de fer un seguiment del buttonPreviousState i hem de fer un seguiment de l’últimDebounceTime. Totes són variables de tipus int, però l'última és de tipus llarg perquè suposo que necessitem l'espai a la memòria.

El bloc d'opcions de menú té algunes funcions noves. En primer lloc, el char * (sí, que és un asterisc deliberat), que és una variable literal de caràcters / cadenes. És un punter cap a un emmagatzematge estàtic a la memòria. No el podeu canviar (com podeu fer a Python, per exemple). Aquesta línia char * menuOptions crea una matriu de literals de cadena. Podeu afegir tants elements de menú com vulgueu.

La variable bool featureSetting és només la matriu de valors que representa cada element del menú. Sí, podeu emmagatzemar qualsevol cosa que vulgueu, només cal canviar el tipus de variable (tots han de ser del mateix tipus). Ara pot ser que hi hagi maneres millors de gestionar-ho, com ara diccionaris o tuples, però això és senzill per a aquesta aplicació. Probablement crearia un d’aquests darrers en una aplicació desplegada.

He seguit el menúMode, de manera que si volgués altres coses a la pantalla, podria fer-ho. A més, si tingués lògica de sensor, podria fer una pausa durant el funcionament del menú, per si alguna cosa entra en conflicte. Tinc una variable menuNeedsPrint perquè vull imprimir el menú en moments concrets, no només tot el temps. Finalment, tinc una variable optionSelected, de manera que puc fer un seguiment de l’opció seleccionada mentre hi accedeixo en diversos llocs.

Vegem el següent conjunt de funcions.

Pas 8: Desglossament del codi: configuració i funcions personalitzades

La funció setup () és prou fàcil, només hi ha tres declaracions d’entrada:

void setup () {pinMode (menuSelect, INPUT); pinMode (menúSave, INPUT); pinMode (menuSelect, INPUT); Serial.begin (9600); }

A continuació es mostren les tres funcions personalitzades. Vegem els dos primers i, després, l’últim per separat.

Necessitem dues funcions que proporcionin informació. La raó és que volem assegurar-nos que això sigui llegible per humans. També ens ajudarà a depurar el codi si tenim algun problema. Codi:

// Funció per tornar l'opció seleccionada actual char * ReturnOptionSelected () {char * menuOption = menuOptions [optionSelected]; // Opció de retorn Menú de retorn seleccionat Opció; } // Funció per retornar l'estat de l'opció seleccionada actual char * ReturnOptionStatus () {bool optionSetting = featureSetting [optionSelected]; char * optionSettingVal; if (optionSetting == false) {optionSettingVal = "False"; } else {optionSettingVal = "Verdader"; } // Opció de retorn Configuració de l'opció de retornSettingVal; }

La funció char * ReturnOptionSelected () comprova l'opció seleccionada (si veieu més amunt, establim una variable per fer-ne un seguiment) i treu la literal de la cadena de la matriu que hem creat anteriorment. Aleshores el retorna com a tipus char. Ho sabem perquè la funció indica el tipus de retorn.

La segona funció, char * ReturnOptionStatus () llegeix l'estat de l'opció desada a la matriu i retorna un literal de cadena que representa el valor. Per exemple, si la configuració que hem emmagatzemat és falsa, tornaria "False". Això passa perquè mostrem a l'usuari aquesta variable i és millor mantenir tota aquesta lògica junta. Ho podria fer més endavant, però té més sentit fer-ho aquí.

// Funció per alternar l'opció actual bool ToggleOptionSelected () {featureSetting [optionSelected] =! FeatureSetting [optionSelected]; tornar cert; }

La funció bool ToggleOptionSelected () és una funció de comoditat per canviar el valor de la configuració que hem seleccionat al menú. Simplement dóna la volta al valor. Si teniu un conjunt d’opcions més complexes, pot ser que sigui molt diferent. Torno a true en aquesta funció, perquè la meva devolució de trucada (la trucada posterior al codi que activa aquesta funció) espera una resposta veritable / falsa. Estic 100% segur que això funcionarà, de manera que no he tingut en compte que no funcionaria, però ho faria en una aplicació desplegada (per si de cas).

Pas 9: el bucle …

La funció loop () és bastant llarga, així que ho farem per parts. Podeu assumir tot el que hi ha a sota dels nius dins d'aquesta funció:

bucle buit () {

// Feu feina aquí <-----}

D'acord, hem vist aquestes coses abans:

// Llegiu els botons int menuButtonPressed = digitalRead (menuButton); int menuSelectPressed = digitalRead (menuSelect); int menuSavePressed = digitalRead (menuSave); // Obtenir el temps actual llarg int currentTime = millis (); if (menuButtonPressed == LOW && menuSelectPressed == LOW && menuSavePressed == LOW) {// Restableix el temps de recompte mentre no es prem el botó lastDebounceTime = currentTime; menuButtonPreviousState = BAIX; menuSelectPreviousState = BAIX; menuSavePreviousState = BAIX; }

Tot el que havia de fer aquí era afegir a les tres trucades digitalRead () i assegurar-me que tenia en compte que si tots els botons estaven baixos, hauríem de restablir el temporitzador (lastDebounceTime = currentTime) i establir tots els estats anteriors a mínims. També emmagatzemo millis () a currentTime.

La següent secció fa nius dins de la línia

if (((currentTime - lastDebounceTime)> debounceTimeout)) {

// Feu feina aquí <----}

Hi ha tres seccions. Sí, els hauria pogut traslladar a les seves pròpies funcions, però per simplicitat, vaig mantenir aquí els tres algorismes de botons principals.

if ((menuButtonPressed == HIGH) && (menuButtonPreviousState == BAIX)) {if (menuMode == false) {menuMode = true; // Feu saber a l'usuari Serial.println ("El menú està actiu"); } else if (menuMode == true && optionSelected = 1) {// Restableix l'opció optionSelected = 0; } // Imprimeix el menú menuNeedsPrint = true; // Commuta el botó prev. estat per mostrar només el menú // si es deixa anar el botó i es torna a prémer menuButtonPreviousState = menuButtonPressed; // seria ALT}

Aquest primer maneja quan menuButtonPressed és HIGH, o quan es prem el botó de menú. També comprova que l'estat anterior fos BAIX, de manera que s'hagués de deixar anar el botó abans de tornar-lo a prémer, cosa que impedeix que el programa dispara constantment el mateix esdeveniment una i altra vegada.

A continuació, comprova que si el menú no està actiu, l’activa. Imprimirà la primera opció seleccionada (que és el primer element del menú Opcions per defecte. Si premeu el botó una segona o tercera (etc) vegada, obtindreu la següent opció a la llista. Alguna cosa que podria solucionar és: que quan arriba al final, torna al cicle. Això podria llegir la longitud de la matriu i fer que el ciclisme tornés més fàcil si canvieu el nombre d'opcions, però ara per ara era senzill.

L’última petita secció (// Imprimeix el menú), òbviament, imprimeix el menú, però també estableix l’estat anterior a ALTA, de manera que la mateixa funció no funcionarà (vegeu la meva nota anterior sobre com comprovar si el botó anteriorment era BAIX).

// es pressiona menuSelect, proporcioneu logicif ((menuSelectPressed == HIGH) && (menuSelectPreviousState == LOW)) {if (menuMode) {// Canvieu l’opció seleccionada // De moment, això és cert / fals // però podria ser qualsevol cosa bool toggle = ToggleOptionSelected (); if (commutar) {menuNeedsPrint = true; } else {Serial.println ("S'ha produït un error. Torneu-ho a provar"); }} // Alterna l'estat per commutar només si es deixa anar i es torna a prémer menuSelectPreviousState = menuSelectPressed; }

Aquest bit de codi gestiona el botó menuSelectPressed de la mateixa manera, tret que aquesta vegada només activem la funció ToggleOptionSelected (). Com he dit abans, podeu canviar aquesta funció perquè faci més coses, però això és tot el que necessito.

El més important a tenir en compte és la variable de commutació, que fa un seguiment de l'èxit de la devolució de trucada i imprimeix el menú si és cert. Si no retorna res o és fals, s'imprimirà el missatge d'error. Aquí és on podeu fer servir la devolució de trucada per fer altres coses.

if ((menuSavePressed == HIGH) && (menuSavePreviousState == LOW)) {// Sortiu del menú // Aquí podeu fer qualsevol ordre // o desar-lo a EEPROM menuMode = false; Serial.println ("S'ha sortit el menú"); // Commuta l'estat perquè el menú només surti una vegada menuSavePreviousState = menuSavePressed; }}

Aquesta funció gestiona el botó menuSave, que només surt del menú. Aquí és on podríeu tenir una opció de cancel·lar o desar, potser fer una mica de neteja o desar-la a l'EEPROM. Acabo d'imprimir "Menú sortit" i he establert l'estat del botó a ALTA perquè no faci un bucle.

if (menuMode && menuNeedsPrint) {// Hem imprès el menú, per tant, tret que passi //, no cal tornar a imprimir-lo menuNeedsPrint = false; char * optionActive = ReturnOptionSelected (); char * optionStatus = ReturnOptionStatus (); Serial.print ("Seleccionat:"); Serial.print (opcióActiu); Serial.print (":"); Serial.print (optionStatus); Serial.println (); }

Es tracta de l'algorisme menuPrint, que només s'activa quan el menú està actiu i quan la variable menuNeedsPrint s'estableix a true.

Definitivament, això es podria traslladar a la seva pròpia funció, però per simplificar …

Bé, ja està! Consulteu el següent pas per a tot el bloc de codi.

Pas 10: bloc de codi final

// Definiu constants

#define menuButton 2 #define menuSelect 3 #define menuSave 4 #define debounceTimeout 50 int menuButtonPreviousState = BAIX; int menuSelectPreviousState = BAIX; int menuSavePreviousState = BAIX; // Definiu variables long int lastDebounceTime; bool lightSensor = true; bool tempSensor = cert; // Opcions del menú char * menuOptions = {"Comprova la temperatura", "Comprova la llum"}; bool featureSetting = {false, false}; bool menuMode = false; bool menuNeedsPrint = fals; int optionSelected = 0; // Funció de configuració

void setup () {pinMode (menuSelect, INPUT); pinMode (menúSave, INPUT); pinMode (menuSelect, INPUT); Serial.begin (9600); }

// Funció per tornar l'opció seleccionada actual char * ReturnOptionSelected () {char * menuOption = menuOptions [optionSelected]; // Opció de retorn Menú de retorn seleccionat Opció; } // Funció per retornar l'estat de l'opció seleccionada actual char * ReturnOptionStatus () {bool optionSetting = featureSetting [optionSelected]; char * optionSettingVal; if (optionSetting == false) {optionSettingVal = "False"; } else {optionSettingVal = "Verdader"; } // Opció de retorn Configuració de l'opció de retornSettingVal; } // Funció per alternar l'opció actual bool ToggleOptionSelected () {featureSetting [optionSelected] =! FeatureSetting [optionSelected]; tornar cert; } // El bucle principal

void loop () {// Llegiu els botons int menuButtonPressed = DigitalRead (menuButton); int menuSelectPressed = digitalRead (menuSelect); int menuSavePressed = digitalRead (menuSave); // Obtenir el temps actual llarg int currentTime = millis (); if (menuButtonPressed == LOW && menuSelectPressed == LOW && menuSavePressed == LOW) {// Restableix el temps de recompte mentre no es prem el botó lastDebounceTime = currentTime; menuButtonPreviousState = BAIX; menuSelectPreviousState = BAIX; menuSavePreviousState = BAIX; } if (((currentTime - lastDebounceTime)> debounceTimeout)) {// Si s'arriba al temps d'espera, premeu el botó.

// es prem el menúButton, proporcioneu una lògica

// Només s'activa quan el botó s'ha alliberat prèviament si ((menuButtonPressed == HIGH) && (menuButtonPreviousState == LOW)) {if (menuMode == false) {menuMode = true; // Feu saber a l'usuari Serial.println ("El menú està actiu"); } else if (menuMode == true && optionSelected = 1) {// Restableix l'opció optionSelected = 0; } // Imprimeix el menú menuNeedsPrint = true; // Commuta el botó prev. estat per mostrar només el menú // si es deixa anar el botó i es torna a prémer menuButtonPreviousState = menuButtonPressed; // Seria ALTA} // es prem menu_Select, proporcioneu la lògica if ((menuSelectPressed == HIGH) && (menuSelectPreviousState == LOW)) {if (menuMode) {// Canvieu l’opció seleccionada // De moment, aquesta és només cert / fals // però podria ser qualsevol cosa bool toggle = ToggleOptionSelected (); if (commutar) {menuNeedsPrint = true; } else {Serial.print ("S'ha produït un error. Torneu-ho a provar"); }} // Alterna l'estat per commutar només si es deixa anar i es torna a prémer menuSelectPreviousState = menuSelectPressed; } if ((menuSavePressed == HIGH) && (menuSavePreviousState == LOW)) {// Sortiu del menú // Aquí podeu fer qualsevol ordenació // o desar-la a EEPROM menuMode = false; Serial.println ("S'ha sortit el menú"); // Commuta l'estat perquè el menú només surti una vegada menuSavePreviousState = menuSavePressed; }} // Imprimiu l'opció de menú actual activa, però només imprimiu-la una vegada si (menuMode && menuNeedsPrint) {// Hem imprès el menú, de manera que, tret que passi //, no cal tornar a imprimir-lo menuNeedsPrint = false; char * optionActive = ReturnOptionSelected (); char * optionStatus = ReturnOptionStatus (); Serial.print ("Seleccionat:"); Serial.print (opcióActiu); Serial.print (":"); Serial.print (optionStatus); Serial.println (); }}}

El circuit està disponible al lloc de Tinkercad. He inclòs el circuit següent perquè també el vegeu.

Com sempre, si teniu cap pregunta o problema, feu-m’ho saber.

Recomanat: