Joystick & Display
0 kommentarer

Hej och välkommen tillbaka till vår elektronikbloggserie! Det här är blogg 5 och i den här bloggen ska vi utforska ett praktiskt projekt. Vi kommer att titta på hur du kan använda en joystick för att skriva och redigera text på en LCD-skärm. Detta är ett interaktivt sätt att lära sig de grundläggande begreppen inom elektronik och programmering.

Vi kommer att använda en populär I2C LCD-skärm (samma LCD som från Ultrasound & Display -bloggen) och en joystick för att skapa vår interaktiva skrivmiljö. Med hjälp av Arduino-plattformen och lite programmering kommer vi att kunna flytta runt på skärmen och skriva, redigera och radera text med hjälp av joysticken.

 

Det här projektet är perfekt för alla som vill utforska grundläggande koncept som in- och utgångsenheter, analoga och digitala signaler och användningen av bibliotek och funktioner i Arduino-miljön. Så följ med oss ​​på denna spännande resa in i elektronikens värld. Låt oss börja!
Komponenter som används i detta projekt

Arduino UNO
KY-023 Joystick
20x4 LCD
hon kablar
Bygeltrådar
Bakbord

 

Här är en kort förklaring av komponenterna som ska användas i projektet:

  1. 20x4 LCD-skärm : En 20x4 LCD-skärm är en alfanumerisk skärm med 4 rader och 20 tecken per rad. linje. Det snygga med denna LCD är att den kan använda I2C-kommunikation för att ansluta till Arduino-kortet och visa text och symboler. Detta gör anslutningen enklare.
  2. Arduino Uno : Arduino Uno är en populär mikrokontroller som återigen fungerar som hjärnan i vårt projekt. Den styr LCD-displayen och bearbetar inmatningen från joysticken med hjälp av den programmerbara logiken.
  3. Hon-honkablar : Dessa kablar används för att upprätta anslutningen mellan LCD-skärmen och Arduino Uno. De har honkontakter i båda ändar och gör det enkelt att koppla ihop de två enheterna.
  4. Normala bygelkablar : Dessa kablar används för att ansluta Arduino Uno till joysticken såväl som andra anslutningar som behövs för projektet. De är flexibla och lätta att koppla till och från.
  5. Joystick KY-023 : Joysticken är vår primära inmatningsenhet i detta projekt. Den använder analoga signaler för att upptäcka rörelse i x- och y-riktningarna, samt en digital knapp för ytterligare interaktion. Vi använder en joystick från en PS2-kontroller som är enkel att ansluta och använda.
  6. Breadboard : En breadboard är en prototypplattform som tillåter tillfälliga anslutningar mellan elektroniska komponenter. Det ger ett enkelt och flexibelt sätt att organisera och ansluta komponenter under utvecklingen av vårt proffs

Dessa komponenter är tillräckliga för att skapa vårt skrivverktyg och börja utforska skriv- och redigeringsfunktionerna med hjälp av joysticken och LCD-skärmen.

KY-023

nu skulle vi vilja ta en närmare titt på joysticken som vi använder i vårt projekt. Joysticken vi använder är en KY-023 joystick . Det är en kompakt och mångsidig inmatningsenhet som låter oss styra vårt elektroniska system med två axlar och en tryckknapp.

 

Joysticken har två analoga axlar , VRx och VRy , som registrerar joystickens horisontella och vertikala rörelser. Dessa axlar genererar variabla spänningsnivåer som beror på joystickens position. Genom att läsa dessa spänningar kan vi avgöra vilken riktning joysticken rör sig.

Dessutom har joysticken även en tryckknapp , känd som SW , som fungerar som en digital ingång. Denna knapp låter oss upptäcka om knappen har tryckts ned eller inte. Vi kan programmera vårt system att utföra vissa åtgärder när knappen är aktiverad.

 

  1. 5V : Detta är matningsstiftet som ska anslutas till en +5V strömkälla på Arduino-kortet eller en annan strömförsörjningsmodul. Den driver joysticken.
  2. VRx : Detta stift är den analoga x-axelns utgång. Den levererar en variabel spänning som är beroende av joystickens horisontella läge. Detta stift måste anslutas till ett analogt ingångsstift på Arduino-kortet .
  3. VRy : Detta är den analoga y-axelns utgång. Den levererar en variabel spänning baserat på joystickens vertikala läge. Detta stift måste också anslutas till ett analogt ingångsstift på Arduino-kortet .
  4. SW : SW står för switch (knapp). Detta stift fungerar som en digital ingång och ger en logisk låg (GND) eller logisk hög (+5V) beroende på om knappen är intryckt eller inte. Detta stift måste anslutas till ett digitalt ingångsstift på Arduino-kortet .


Nu när vi har en bättre förståelse för joysticken, kommer vi att dyka djupare in i kretsarna i vårt projekt och förklara hur allt hänger ihop. Låt oss börja!

 

Projektcykeln

Kretsen för detta projekt är inte särskilt komplicerad. Vi kan koppla vår 20x4 LCD-skärm till Arduino Uno på samma sätt som vi tidigare lärt oss i vår blogg om att mäta avstånd med ultraljudssensorn. Displayens anslutning till Arduino Uno gör att vi kan skriva och visa text på displayen i realtid.

När det kommer till joysticken har vi några enkla kopplingar att göra. Först ansluter vi SW-stiftet på joysticken till stift 2Arduino Uno . Detta gör att vi kan upptäcka joystick-knapptryckningar.

För att driva joysticken ansluter vi VCC-stiftet på joysticken till 5V- stiftet på Arduino Uno . Detta säkerställer att joysticken får den nödvändiga matningsspänningen.

Slutligen ansluter vi joystickens VRx-stift till A0-stiftetArduino Uno och VRy-stiftet till A1-stiftetArduino Uno . Dessa anslutningar tillåter oss att läsa de analoga värdena som genereras av joystickens rörelser. Nedan är ett diagram över kretsen.

 


Koden

Även om kretsen för det här projektet kanske inte är särskilt komplicerad, är koden faktiskt den mest avancerade och komplexa koden vi har arbetat med hittills. Koden ansvarar för att styra och hantera input från joysticken samt styra LCD-displayen i realtid. Den här koden använder sig av olika programmeringskoncept och -tekniker, inklusive analoga ingångar, villkorliga uttalanden, loopstrukturer och hantering av LCD-skärmen .

Här är koden. Vi kommer att gå igenom det rad för rad.

 # include <Wire.h> // Inkluderar Wire-biblioteket som används för I2C-kommunikation 
# include <LiquidCrystal_I2C.h> // Inkluderar LiquidCrystal_I2C-biblioteket för att styra I2C LCD-skärmen

 LiquidCrystal_I2C lcd( 0x27 , 2 , 1 , 0 , 4 , 5 , 6 , 7 ); // Initierar ett LiquidCrystal_I2C-objekt för att styra LCD-skärmen
 
const int VRx = 0 ; // Definierar VRx-pinnumret för joystickens x-riktning
 const int VRy = 1 ; // Definierar VRy-pinnumret för joystickens y-riktning
 const int switchPin = 2 ; // Definierar switchPin-pinnumret för joystickknappen 
int LCDpos80 = 0 ; // Initierar variabeln LCDpos80 för att hålla reda på LCD-positionen
 bool flip = sant; // En variabel för att växla mellan att visa och dölja markören


 char line [ 80 ][ 21 ] = {
 // En tvådimensionell array för att lagra texten för varje rad på LCD-skärmen
 "|Hej! " , // Första raden 
"|Du kan " , // Andra raden
 "|skriv vad som helst " , // Tredje raden
 "|på denna display" // Fjärde raden
 };


 void setup () {
 lcd. börja ( 20 , 4 ); // Initierar LCD-displayen med 20 tecken per linje och 4 rader 
lcd.setBacklightPin( 3 , POSITIV); // Ställer in bakgrundsbelysningsstift till stift 3 och polaritet som positiv
 lcd.setBacklight( HIGH ); // Slår på bakgrundsbelysningen
 pinMode (switchPin, INPUT ); // Ställer switchPin till ingångsläge
 digitalWrite (switchPin, HIGH ); // Aktiverar det interna pull-up-motståndet på switchPin
 
line [ 0 ][ 19 ] = '|' ; // Infogar ett vertikalt linjetecken i slutet av den första raden
 line [ 1 ][ 19 ] = '|' ; // Infogar ett vertikalt linjetecken i slutet av den andra raden 
line [ 2 ][ 19 ] = '|' ; // Infogar ett vertikalt linjetecken i slutet av den tredje raden
 rad [ 3 ][ 19 ] = '|' ; // Infogar ett vertikalt linjetecken i slutet av den fjärde raden
 }


 void checkJoy() { 
statisk osignerad lång knappPressStartTime = 0 ;
 bool knapptryckt = ( digitalRead (switchPin) == LÅG );

 // Justera positionen åt vänster eller höger baserat på VRx-värdet
 if ( analogRead (VRx) < 175 && LCDpos80 > 0 ) {
 LCDpos80--; 
} annat om ( analogRead (VRx) > 530 && LCDpos80 < 79 ) {
 LCDpos80++;
 }

 // Justera värdet i den aktuella platshållaren uppåt eller nedåt baserat på VRy-värdet
 if (LCDpos80 >= 0 && LCDpos80 <= 79 ) { 
if ( analogRead (VRy) < 175 && rad [LCDpos80 / 20 ][LCDpos80 % 20 ] < 127 ) {
 linje [LCDpos80/ 20 ][LCDpos80% 20 ]++; 
} else if ( analogRead (VRy) > 530 && line [LCDpos80 / 20 ][LCDpos80 % 20 ] > 32 ) {
 linje [LCDpos80/ 20 ][LCDpos80% 20 ]--;
 }
 }

 // Om knappen trycks in sparas starttiden för knapptryckningen 
if (knapptryckt && knappTryckStartTid == 0 ) {
 buttonPressStartTime = millis (); // Lagra starttiden för knapptryckningen
 }

 // Om knappen har släppts och en starttid har registrerats för knapptryckningen
 if (!knappPressed && buttonPressStartTime != 0 ) {
 unsigned long buttonPressDuration = millis () - buttonPressStartTime; 
buttonPressStartTime = 0 ; // Återställ starttiden för knapptryckningen


 // Om knappen hålls nedtryckt i minst 1 sekund
 if (buttonPressDuration >= 1000 ) {
 // Rensa hela skärmen
 for ( int i = 0 ; i < 4 ; i++) { 
för ( int j = 0 ; j < 20 ; j++) {
 line [i][j] = ' ' ;
 }
 }
 }
 // Om knappen släpps inom 1 sekund och positionen är inom giltigt område
 else if (buttonPressDuration < 1000 && LCDpos80 >= 0 && LCDpos80 <= 79 ) { 
// Rensa den aktuella platshållaren
 linje [LCDpos80 / 20 ][LCDpos80 % 20 ] = ' ' ;
 }
 }
 }


 void LCD() { // Funktion för att uppdatera LCD-skärmen
 int rad = LCDpos80 / 20 ; // Beräkna raden baserat på värdet på LCDpos80 
int col = LCDpos80 % 20 ; // Beräkna kolumnen baserat på värdet på LCDpos80

 lcd. setCursor ( 0 , 0 ); // Ställ markören på (0, 0) (övre vänstra hörnet)
 lcd. print ( rad [ 0 ]); // Skriv ut innehållet i rad[0] på LCD-skärmen
 
lcd. setCursor ( 0 , 1 ); // Ställ pekaren på (0, 1) (andra raden)
 lcd. print ( rad [ 1 ]); // Skriv ut innehållet i rad[1] på LCD-skärmen

 lcd. setCursor ( 0 , 2 ); // Ställ markören på (0, 2) (tredje raden) 
lcd. print ( rad [ 2 ]); // Skriv ut innehållet i rad[2] på LCD-skärmen

 lcd. setCursor ( 0 , 3 ); // Ställ markören på (0, 3) (fjärde raden)
 lcd. print ( rad [ 3 ]); // Skriv ut innehållet i rad[3] på LCD-skärmen

 if (vänd) { 
lcd. setCursor (kol, rad); // Ställ markören på den aktuella positionen (kol, rad)
 lcd. print ( '_' ); // Skriv ut ett understreck på LCD-skärmen vid den aktuella positionen
 }

 flip = !flip; // Ändra värdet på flip-variabeln
 fördröjning ( 100 ); // Vänta i 100 millisekunder
 }


 void switchCategory() { 
static unsigned long pressStartTime = 0 ;
 unsigned long currentTime = millis (); // Deklarera variabeln currentTime

 // Kontrollera om knappen är nedtryckt och om den aktuella platshållaren är tom 
bool knapptryckt = ( analogRead (VRy) > 530 && rad [LCDpos80 / 20 ][LCDpos80 % 20 ] == ' ' );

 // Om knappen har tryckts ned och det är första gången sparas starttiden för tryckningen
 if (knapptryckt && tryckStartTime == 0 ) {
 pressStartTime = aktuellTid; // Lagra starttiden för trycket
 }
 
// Om knappen släpps och en starttid registreras för pressen
 if (!knapptryckt && tryckStartTid != 0 ) {
 unsigned long pressDuration = currentTime - pressStartTime; // Beräkna tryckets varaktighet
 pressStartTime = 0 ; // Återställ starttiden för trycket

 // Bestäm kategorin baserat på tappens varaktighet 
if (pressDuration >= 0 && pressDuration < 1000 ) {
 line [LCDpos80 / 20 ][LCDpos80 % 20 ] = 'A' ; // Kategori A
 } else if (pressDuration >= 1000 && pressDuration < 2000 ) { 
linje [LCDpos80 / 20 ][LCDpos80 % 20 ] = 'a' ; // Kategori a
 } else if (pressDuration >= 2000 && pressDuration < 3000 ) {
 linje [LCDpos80 / 20 ][LCDpos80 % 20 ] = '1' ; // Kategori 1 
} else if (pressDuration >= 3000 && pressDuration < 4000 ) {
 rad [LCDpos80 / 20 ][LCDpos80 % 20 ] = '.' ; // Kategori .

 // Lägg till fler villkor för ytterligare kategorier efter behov
 }
 }
 }


 void loop () { // Huvudslingan för programmet 
checkJoy(); // Anropa checkJoy-funktionen för att hantera joystickinmatning
 LCD(); // Anropa LCD-funktionen för att uppdatera LCD-skärmen
 switchCategory(); // Anropa switchCategory-funktionen för att skriva snabbare
 }

 

Låt oss ta en närmare titt på koden...

 # include <Wire.h> // Vi inkluderar Wire-biblioteket, som tillåter oss att kommunicera via I2C-protokollet. 
# include <LiquidCrystal_I2C.h> // Vi inkluderar LiquidCrystal_I2C-biblioteket som ger oss funktioner för att styra vår I2C LCD.
 
LiquidCrystal_I2C lcd( 0x27 , 2 , 1 , 0 , 4 , 5 , 6 , 7 ); // Vi initierar ett LiquidCrystal_I2C-objekt med den specifika I2C-adressen (0x27) och anslutna stift på Arduino (2, 1, 0, 4, 5, 6, 7). Detta objekt kommer att användas för att styra vår LCD-skärm

Denna del av koden inkluderar de nödvändiga biblioteken för att kunna kommunicera med vår I2C-LCD och initiera ett objekt, lcd , av typen LiquidCrystal_I2C . Vi specificerar också de relevanta anslutna stiften på Arduino. Genom att inkludera dessa bibliotek och initiera objektet är vi redo att styra vår LCD-skärm och visa text på den.

 

 

 const int VRx = 0 ; // Vi definierar VRx som variabel och tilldelar den pinnumret (0) för joystickens x-riktning. 
const int VRy = 1 ; // Vi definierar VRy som variabel och tilldelar den pinnumret (1) för joystickens y-riktning.
 const int switchPin = 2 ; // Vi definierar switchPin som variabel och tilldelar den pinnumret (2) på joystickens knapp.
 int LCDpos80 = 0 ; // Vi initierar variabeln LCDpos80 till 0 för att hålla reda på LCD:ns position. 
bool flip = sant; // Vi skapar en boolesk variabel som heter "flip" och tilldelar den värdet "true". Denna variabel används för att växla mellan att visa och dölja markören.

Dessa kodrader definierar och initierar de nödvändiga variablerna för vår joystick och LCD-skärm. VRx representerar pinnumret för joystickens x- riktning , VRy representerar pinnumret för joystickens y-riktning , och switchPin representerar pinnumret för knappen på joysticken .

 

Den variabla LCDpos80 används för att hålla reda på positionen på LCD-skärmen. Den kommer att användas senare i koden för att placera markören korrekt.

flip är en boolesk variabel som börjar med värdet true . Denna variabel kommer att användas för att växla mellan att visa och dölja markören på LCD-skärmen senare i koden.

 

 char line [ 80 ][ 21 ] = { 
// En tvådimensionell array för att lagra texten för varje rad på LCD-skärmen
 "|Hej! " , // Första raden
 "|Du kan " , // Andra raden
 "|skriv vad som helst " , // Tredje raden
 "|på denna display" // Fjärde raden
 };
Den här delen av koden skapar en tvådimensionell array med namnet line . Denna array används för att lagra texten som ska visas på varje rad på LCD-skärmen.

Arrayen har en storlek på 80 rader och varje rad har en storlek på 21 tecken. Den tillåter oss att lagra upp till 80 olika rader text på displayen, där varje rad kan ha upp till 21 tecken.

I exemplet har text redan skrivits in för de fyra första raderna i arrayen. Varje rad är omgiven av citattecken ( " ) och avslutas med kommatecken ( , ). Detta representerar en textrad som ska visas på LCD-skärmen .

Du kan anpassa eller lägga till dina egna texter till varje rad genom att helt enkelt redigera arrayen. Observera att varje textrad måste ha en maximal längd på 20 tecken (plus det extra tecknet för att avsluta strängen).

Med andra ord tillåter denna del av koden oss att initialisera vår LCD-skärm med fördefinierad text som vi kan arbeta med och manipulera senare i koden.


 

 void setup () {
 lcd. börja ( 20 , 4 ); // Initierar LCD-displayen med 20 tecken per linje och 4 rader 
lcd.setBacklightPin( 3 , POSITIV); // Ställer in bakgrundsbelysningsstift till stift 3 och polaritet som positiv
 lcd.setBacklight( HIGH ); // Slår på bakgrundsbelysningen
 pinMode (switchPin, INPUT ); // Ställer switchPin till ingångsläge
 digitalWrite (switchPin, HIGH ); // Aktiverar det interna pull-up-motståndet på switchPin
 
line [ 0 ][ 19 ] = '|' ; // Infogar ett vertikalt linjetecken i slutet av den första raden
 line [ 1 ][ 19 ] = '|' ; // Infogar ett vertikalt linjetecken i slutet av den andra raden 
line [ 2 ][ 19 ] = '|' ; // Infogar ett vertikalt linjetecken i slutet av den tredje raden
 rad [ 3 ][ 19 ] = '|' ; // Infogar ett vertikalt linjetecken i slutet av den fjärde raden
 }
 2/2 _ 
I funktionen setup () utförs den initiala konfigurationen och initialiseringen av vårt projekt. Låt oss granska koden rad för rad:
 cpp
 void setup () {
 lcd. börja ( 20 , 4 ); // Initierar LCD-displayen med 20 tecken per linje och 4 rader
 lcd.setBacklightPin( 3 , POSITIV); // Ställer in bakgrundsbelysningsstift till stift 3 och polaritet som positiv 
lcd.setBacklight( HIGH ); // Slår på bakgrundsbelysningen
 pinMode (switchPin, INPUT ); // Ställer switchPin till ingångsläge
 digitalWrite (switchPin, HIGH ); // Aktiverar det interna pull-up-motståndet på switchPin
 
line [ 0 ][ 19 ] = '|' ; // Infogar ett vertikalt linjetecken i slutet av den första raden
 line [ 1 ][ 19 ] = '|' ; // Infogar ett vertikalt linjetecken i slutet av den andra raden 
line [ 2 ][ 19 ] = '|' ; // Infogar ett vertikalt linjetecken i slutet av den tredje raden
 rad [ 3 ][ 19 ] = '|' ; // Infogar ett vertikalt linjetecken i slutet av den fjärde raden
 }

I setup() -funktionen gör vi följande:

  1. lcd.begin(20, 4); : Vi initierar LCD-skärmen genom att anropa metoden begin() på vårt lcd -objekt. Vi anger att displayen har 20 tecken per linje och totalt 4 rader.
  2. lcd.setBacklightPin(3, POSITIV); : Vi indikerar att bakgrundsbelysningsstickan är ansluten till stift 3 på Arduino och att polariteten är positiv. Detta talar om för LCD-biblioteket var bakgrundsbelysningen är ansluten.
  3. lcd.setBacklight(HIGH); : Vi sätter på bakgrundsbelysningen på LCD-skärmen genom att anropa metoden setBacklight() och ge den argumentet HIGH .
  4. pinMode(switchPin, INPUT); : Vi ställer in switchPin till inmatningsläge genom att anropa pinMode() -funktionen och ange pinnumret och tillståndet.
  5. digitalWrite(switchPin, HIGH); : Vi aktiverar det interna pull-up-motståndet på switchPin genom att anropa digitalWrite() -funktionen och ange pinnumret och värdet HIGH . Detta säkerställer att knappens ingång är hög när den inte har tryckts in.

De sista fyra raderna i setup()- funktionen är avsedda att visa hur man manipulerar den initiala texten på LCD-skärmen när enheten startar. Genom att lägga till ett vertikalt linjetecken ( | ) i slutet av var och en av de fyra raderna i linjematrisen , ändrar vi den ursprungliga texten som visas på displayen under uppstart. Detta gör att vi kan lägga till en visuell separation mellan texterna på displayen och anpassa den initiala presentationen av information. Du kan experimentera med att ändra text och layout för att uppnå önskad visuell effekt på LCD-skärmen.

 

 

 void checkJoy() { 
statisk osignerad lång knappPressStartTime = 0 ;
 bool knapptryckt = ( digitalRead (switchPin) == LÅG );

 // Justera positionen åt vänster eller höger baserat på VRx-värdet
 if ( analogRead (VRx) < 175 && LCDpos80 > 0 ) {
 LCDpos80--; 
} annat om ( analogRead (VRx) > 530 && LCDpos80 < 79 ) {
 LCDpos80++;
 }

CheckJoy() -funktionen är ansvarig för att övervaka och hantera joystickens rörelser och knapptryckningar. Först skapas en statisk variabel buttonPressStartTime , som används för att hålla reda på starttiden för en knapptryckning.

Då skapas en boolesk variabel knappPressed som kontrollerar om knappen har tryckts ned. Detta görs genom att läsa tillståndet för switchPin och jämföra det med LOW -tillståndet.

Detta följs av ett villkorsblock. Om joystickens VRx-värde (x-riktningen) är mindre än 175 och LCDpos80 (positionen på LCD-skärmen) är större än 0 , vänsterjusteras LCDpos80 genom att minska med 1. Detta orsakar en rörelse av markören till vänster om LCD-skärmen.

På liknande sätt, om VRx-värdet är större än 530 och LCDpos80 är mindre än 79 , justeras LCDpos80 till höger genom att öka med 1 . Detta flyttar markören till höger på LCD-skärmen.

Denna del av koden låter användaren styra markörens position på displayen genom att flytta joystickens x-riktning åt vänster eller höger.

Observera att värdena 175 och 530 kan justeras efter behov för att justera joystickens rörelsekänslighet och markörens rörelsehastighet på displayen.

 

 

 // Justera värdet i den aktuella platshållaren uppåt eller nedåt baserat på VRy-värdet 
if (LCDpos80 >= 0 && LCDpos80 <= 79 )
 { if ( analogRead (VRy) < 175 && linje [LCDpos80 / 20 ][LCDpos80 % 20 ] < 127 ) { rad [LCDpos80 / 20 ][LCDpos80 % 20 ]++; }  
else if ( analogRead (VRy) > 530 && line [LCDpos80 / 20 ][LCDpos80 % 20 ] > 32 ) { line [LCDpos80 / 20 ][LCDpos80 % 20 ]--;
 }
 }

I ovanstående del av koden i funktionen checkJoy() bearbetas VRy-värdet (y-riktning) för joysticken för att justera värdet i den aktuella platshållaren (teckenpositionen) på LCD-skärmen.

Först kontrollerar den om LCDpos80 är inom det tillåtna intervallet för platshållarpositionsintervallet (0-79) . Detta säkerställer att ändringar endast sker när markören är placerad inom det synliga området på LCD-skärmen.

Sedan följer ett tillståndsblock som hanterar olika situationer beroende på joystickens VRy-värde . Om VRy-värdet är mindre än 175 och det aktuella platshållarvärdet ( line[LCDpos80 / 20][LCDpos80 % 20] ) är mindre än 127 (ASCII-värdet för det högsta tecknet ), ökas platshållarvärdet med 1 . Detta skiftar tecknet till nästa i ASCII-teckenkoden och ökar dess värde.

På liknande sätt, om VRy-värdet är större än 530 och det aktuella platshållarvärdet är större än 32 (ASCII-värdet för det lägsta tecknet) , minskas platshållarvärdet med 1 . Detta växlar tecknet till det föregående i ASCII-teckenkoden och minskar dess värde.

Dessa justeringar av platshållarvärdet gör att användaren kan ändra det aktuella tecknet på LCD-skärmen uppåt eller nedåt genom att flytta joystickens y-riktning.


 rita på LCD-skärmen uppåt eller nedåt genom att flytta joystickens y-riktning.
 // Om knappen trycks in sparas starttiden för knapptryckningen
 if (knapptryckt && knappTryckStartTid == 0 ) {
 buttonPressStartTime = millis (); // Lagra starttiden för knapptryckningen
 }

 // Om knappen har släppts och en starttid har registrerats för knapptryckningen 
if (!knappPressed && buttonPressStartTime != 0 ) {
 unsigned long buttonPressDuration = millis () - buttonPressStartTime;
 buttonPressStartTime = 0 ; // Återställ starttiden för knapptryckningen
 // Om knappen hålls nedtryckt i minst 1 sekund
 if (buttonPressDuration >= 1000 ) {
 // Rensa hela skärmen 
for ( int i = 0 ; i < 4 ; i++) {
 för ( int j = 0 ; j < 20 ; j++) {
 line [i][j] = ' ' ;
 }
 }
 }
 // Om knappen släpps inom 1 sekund och positionen är inom giltigt område 
else if (buttonPressDuration < 1000 && LCDpos80 >= 0 && LCDpos80 <= 79 ) {
 // Rensa den aktuella platshållaren
 linje [LCDpos80 / 20 ][LCDpos80 % 20 ] = ' ' ;
 }
 }
 }

Den sista delen av checkJoy() -funktionen hanterar knapptryckningar och deras varaktighet. Här är en genomgång av koden:

Först kontrolleras om knappen har tryckts ned ( knapptryckt ) och om en starttid för knapptryckningen redan har sparats ( knappPressStartTime == 0 ) . Om så är fallet sparas den aktuella tiden med funktionen millis() .

Därefter kontrolleras om knappen har släppts ( !buttonPressed) och om det finns en giltig starttid för knapptryckningen (knappPressStartTime!=0) . Om så är fallet, beräknas varaktigheten av knapptryckningen genom att subtrahera starttiden från den aktuella tiden ( millis() - buttonPressStartTime ) . Återställ sedan starttiden för knapptryckningen ( knappPressStartTime = 0 ) .

Om knappen har hållits intryckt i minst 1 sekund ( knappPressDuration >= 1000 ) , raderas hela innehållet på displayen . Detta görs genom att gå igenom varje rad och varje platshållare och lägga till dem till mellanslagstecknet (' ').

Om knappen å andra sidan släpps inom 1 sekund ( knappPressDuration < 1000 ) och markören är inom det giltiga intervallet ( LCDpos80 >= 0 && LCDpos80 <= 79 ), raderas endast det aktuella tecknet i platshållare n genom att lägga till det till mellanslagstecknet (' ' ).

Denna del av koden gör det möjligt att svara på knapptryckningar och utföra olika åtgärder beroende på knappens varaktighet och markörens position på LCD-skärmen.

 

 

 void LCD() { // Funktion för att uppdatera LCD-skärmen
 int rad = LCDpos80 / 20 ; // Beräkna raden baserat på värdet på LCDpos80
 int col = LCDpos80 % 20 ; // Beräkna kolumnen baserat på värdet på LCDpos80 
lcd. setCursor ( 0 , 0 ); // Ställ markören på (0, 0) (övre vänstra hörnet)
 lcd. print ( rad [ 0 ]); // Skriv ut innehållet i rad[0] på LCD-skärmen
 lcd. setCursor ( 0 , 1 ); // Ställ pekaren på (0, 1) (andra raden) 
lcd. print ( rad [ 1 ]); // Skriv ut innehållet i rad[1] på LCD-skärmen
 lcd. setCursor ( 0 , 2 ); // Ställ markören på (0, 2) (tredje raden)
 lcd. print ( rad [ 2 ]); // Skriv ut innehållet i rad[2] på LCD-skärmen
 
lcd. setCursor ( 0 , 3 ); // Ställ markören på (0, 3) (fjärde raden)
 lcd. print ( rad [ 3 ]); // Skriv ut innehållet i rad[3] på LCD-skärmen
 if (vänd) {
 lcd. setCursor (kol, rad); // Ställ markören på den aktuella positionen (kol, rad) 
lcd. print ( '_' ); // Skriv ut ett understreck på LCD-skärmen vid den aktuella positionen
 }
 flip = !flip; // Ändra värdet på flip-variabeln
 fördröjning ( 100 ); // Vänta i 100 millisekunder
 }
LCD() -funktionen används för att uppdatera LCD-skärmen med texten från line[]- matrisen . Här är en förklaring av koden:

Först beräknas den aktuella raden och kolumnen baserat på värdet på LCDpos80 . Raden beräknas som LCDpos80 / 20 och kolumnen som LCDpos80 % 20 .

Sedan används funktionen lcd.setCursor() för att ställa in markörens position på LCD-skärmen. För varje rad (0 till 3), ställ in pekaren på rätt rad (0 till 3) och skriv sedan ut innehållet i motsvarande rad i rad[] med funktionen lcd.print () .

Efter att raderna har skrivits ut kontrolleras värdet på flip . Om sant, ställs markören till den aktuella positionen ( col, row ) med lcd.setCursor() , och ett understreck ('_') skrivs ut på den aktuella positionen med lcd.print() .

Om du slutligen negerar den ( flip = !flip ) ändras värdet på flip att markören ändrar position vid varje uppdatering av LCD-skärmen. Väntar i 100 millisekunder med delay(100) för att skapa en visuell effekt.

Denna funktion säkerställer att texten från line[] -matrisen visas korrekt på LCD-skärmen och att en markör ('_') blinkar vid den aktuella positionen för att indikera var användaren kan redigera texten.

 

 void switchCategory() { 
static unsigned long pressStartTime = 0 ;
 unsigned long currentTime = millis (); // Deklarera variabeln currentTime

 // Kontrollera om knappen är nedtryckt och om den aktuella platshållaren är tom 
bool knapptryckt = ( analogRead (VRy) > 530 && rad [LCDpos80 / 20 ][LCDpos80 % 20 ] == ' ' );

 // Om knappen trycks ned och det är första gången sparas starttiden för tryckningen
 if (knapptryckt && tryckStartTime == 0 ) {
 pressStartTime = aktuellTid; // Lagra starttiden för trycket
 }
 
// Om knappen släpps och en starttid registreras för pressen
 if (!buttonPressed && pressStartTime != 0 ) {
 unsigned long pressDuration = currentTime - pressStartTime; // Beräkna tryckets varaktighet
 pressStartTime = 0 ; // Återställ starttiden för trycket

 // Bestäm kategorin baserat på tappens varaktighet 
if (pressDuration >= 0 && pressDuration < 1000 ) {
 line [LCDpos80 / 20 ][LCDpos80 % 20 ] = 'A' ; // Kategori A
 } else if (pressDuration >= 1000 && pressDuration < 2000 ) { 
linje [LCDpos80 / 20 ][LCDpos80 % 20 ] = 'a' ; // Kategori a
 } else if (pressDuration >= 2000 && pressDuration < 3000 ) {
 linje [LCDpos80 / 20 ][LCDpos80 % 20 ] = '1' ; // Kategori 1 
} else if (pressDuration >= 3000 && pressDuration < 4000 ) {
 rad [LCDpos80 / 20 ][LCDpos80 % 20 ] = '.' ; // Kategori .

 // Lägg till fler villkor för ytterligare kategorier efter behov
 }
 }
 }

Funktionen switchCategory() används för att byta kategori för den aktuella platshållaren baserat på joystickknappen som trycks ned. Här är en förklaring av koden:

Först initieras en variabel pressStartTime för att lagra starttiden för knapptryckningen, och currentTime uppdateras med den aktuella tiden med hjälp av funktionen millis() .

Sedan kontrolleras om knappen är nedtryckt ( knapptryckt ) och om den aktuella platshållaren är tom ( rad[LCDpos80 / 20][LCDpos80 % 20] == ' ' ) .

Om knappen trycks in och det är första gången ett tryck detekteras ( pressStartTime == 0 ), sparas starttiden för pressen ( pressStartTime = currentTime ) .

När knappen släpps ( !buttonPressed ) och det finns en giltig starttid för pressen ( pressStartTime != 0 ), beräknas pressens varaktighet genom att subtrahera starttiden från den aktuella tiden ( currentTime - pressStartTime ). Därefter återställs starttiden för trycket ( pressStartTime = 0 ) .

Kategorin bestäms sedan utifrån tryckets varaktighet. Om varaktigheten är mellan 0 och 1 000 millisekunder, sätts platshållaren till 'A' (kategori A) . Om varaktigheten är mellan 1 000 och 2 000 millisekunder ställs platshållaren in på 'a' (kategori a) och så vidare för ytterligare kategorier. Du kan lägga till fler villkor för att definiera fler kategorier efter behov.

Den här funktionen låter dig ändra kategorin för den aktuella platshållaren genom att trycka på joystickknappen vid olika tidsintervall. Den kan användas för att organisera och gruppera information på LCD-skärmen.

 void loop () { // Huvudslingan för programmet
 checkJoy(); // Anropa checkJoy-funktionen för att hantera joystickinmatning
 LCD(); // Anropa LCD-funktionen för att uppdatera LCD-skärmen
 switchCategory(); // Anropa switchCategory-funktionen för att skriva snabbare
 }

 

Funktionen loop() är huvudslingan där programmet körs kontinuerligt. Här är en förklaring av koden:

I loop() -funktionen kallas tre olika funktioner:

  1. Funktionen checkJoy() anropas för att hantera indata från joysticken. Denna funktion kontrollerar om joysticken flyttas i x-riktningen för att justera positionen åt vänster eller höger. Den styr också joysticken i y-riktningen för att justera värdet i den aktuella platshållaren uppåt eller nedåt. Dessutom hanterar den knapptryckningar och reaktioner på knapptryckningar som beskrivits tidigare.
  2. LCD() -funktionen anropas för att uppdatera LCD-skärmen. Denna funktion ställer in markörens position och skriver ut innehållet i varje rad från line[] -arrayen på motsvarande plats på LCD-skärmen. Det gör också att markören blinkar vid den aktuella positionen.
  3. SwitchCategory() -funktionen anropas för att möjliggöra snabbare skrivning genom att byta kategori för den aktuella platshållaren på LCD-skärmen. Den här funktionen upptäcker knapptryckningar och beräknar varaktigheten av tryckningen. Baserat på pressens varaktighet bestäms en kategori och den aktuella platshållaren på LCD-skärmen uppdateras med motsvarande värde.

Dessa tre funktioner anropas i slingan för att säkerställa att input från joysticken hanteras, LCD-displayen uppdateras och snabbskrivning är aktiverad i programmet. Slingan fortsätter att köras i en kontinuerlig cykel, vilket ger en lyhörd och interaktiv användarupplevelse.


Med den här guiden har vi gått igenom ett projekt där vi har använt en KY-023 joystick för att interagera med en LCD-skärm med hjälp av en Arduino. Även om kretsen för detta projekt kanske inte är särskilt komplicerad, har koden visat sig vara den mest utmanande och spännande delen idag. Vi har utforskat olika funktioner som att justera markörens position, ändra värdet i platshållare och byta kategorier, allt med hjälp av joystick-ingång.

Vi hoppas att du gillade den här guiden och tyckte att den var användbar. Joysticks kan öppna dörren till många spännande möjligheter, och vi uppmuntrar dig att utforska och experimentera med dem. Lycka till med kodning och kul så ses vi på nästa projekt!

Skriv en kommentar!

Relevanta produkter

TS101 digital loddekolbeTS101 digital loddekolbe i hånd
TS101 digital lödkolv med USB C-försörjning
Erbjudande prisFrån 1 119 kr
14 i lager
TS80P USB-C Loddekolbe kitTS80P Loddekolbe
TS80P USB-C mini Lödpenna sats
Erbjudande prisFrån 1 279 kr
2 i lager
bruge Loddekolbe Renser til at rengøre loddekolbespidsenLoddekolbe Renser
Lyxigt rengöringsmedel för lödkolv
Erbjudande pris143 kr
8 i lager