Rotačný enkodér: Rozdiel medzi revíziami
Zo stránky SensorWiki
Bez shrnutí editace  | 
				|||
| (37 medziľahlých úprav od rovnakého používateľa nie je zobrazených.) | |||
| Riadok 1: | Riadok 1: | ||
| Riadok 7: | Riadok 7: | ||
== Zadanie ==  | == Zadanie ==  | ||
[https://techfun.sk/produkt/rotacny-enkoder/ Rotačný enkóder] - vytvorime program pre zadávanie hodnoty nejakej veličiny na LCD displeji pomocou tohoto enkodéra. Jednoduché menu, výber hodnoty a zadávanie číselnej veličiny so zmenou nahor/nadol a potvrdenie stlačením.  | |||
[[Obrázok:  | [[Obrázok:Enkoder.jpg|400px|thumb|center|Vývojová doska ACROB.]]  | ||
'''Literatúra:'''    | '''Literatúra:'''    | ||
* [http://  | * [http://handsontec.com/dataspecs/module/Rotary%20Encoder.pdf Dokumentácia k Rotačnemu enkóderu]  | ||
* [  | * [https://www.openhacks.com/uploadsproductos/eone-1602a1.pdf Dokumentácia k LCD display-u]  | ||
__TOC__  | __TOC__  | ||
| Riadok 20: | Riadok 19: | ||
== Analýza  a opis riešenia ==  | == Analýza  a opis riešenia ==  | ||
[[Súbor:  | Najprv som podľa schémy zapojenia pripojil LCD displej a rotačný enkoder na dosku Arduino Uno.  | ||
[[Súbor:Projekt.jpg|400px|thumb|center|Schéma zapojenia ]]  | |||
| Riadok 35: | Riadok 33: | ||
<tabs>  | <tabs>  | ||
<tab name="AVR C-code"><source lang="  | <tab name="AVR C-code"><source lang="arduino" style="background: LightYellow;">  | ||
#include <avr/io.h>  | #include <avr/io.h>  | ||
#include <avr/interrupt.h>  | |||
#include <util/delay.h>  | |||
#define clk_pin PB3  | |||
#define data_pin PB4  | |||
#define swt_pin PB5  | |||
volatile int poutput;  | |||
volatile int counter = 0;  | |||
volatile bool buttonPressed = false;  | |||
enum MenuState { MENU_MAIN, MENU_VALUE };  | |||
volatile MenuState menuState = MENU_MAIN;  | |||
void initLCD()  | |||
{  | |||
    DDRD |= (1 << PD0) | (1 << PD1) | (1 << PD2) | (1 << PD3) | (1 << PD4) | (1 << PD5);  | |||
    PORTD = 0x20;  | |||
    PORTD |= 0x04;  | |||
    PORTD &= ~0x04;  | |||
    sendLCDCommand(0x28);  | |||
    sendLCDCommand(0x0C);  | |||
    sendLCDCommand(0x01);  | |||
    DDRB &= ~(1 << clk_pin) & ~(1 << data_pin) & ~(1 << swt_pin);  | |||
    PORTB |= (1 << clk_pin) | (1 << data_pin) | (1 << swt_pin);  | |||
    poutput = PINB & (1 << clk_pin);  | |||
}  | |||
void sendLCDCommand(uint8_t command)  | |||
{  | |||
    PORTD = (command & 0xF0);  | |||
    PORTD &= ~(1 << PD4);  | |||
    PORTD |= (1 << PD5);  | |||
    _delay_us(1);  | |||
    PORTD &= ~(1 << PD5);  | |||
    PORTD = ((command << 4) & 0xF0);  | |||
    PORTD &= ~(1 << PD4);  | |||
    PORTD |= (1 << PD5);  | |||
    _delay_us(1);  | |||
    PORTD &= ~(1 << PD5);  | |||
    _delay_us(40);  | |||
}  | |||
void sendLCDData(uint8_t data)  | |||
{  | |||
    PORTD = (data & 0xF0);  | |||
    PORTD |= (1 << PD4);  | |||
    PORTD |= (1 << PD5);  | |||
    _delay_us(1);  | |||
    PORTD &= ~(1 << PD5);  | |||
    PORTD = ((data << 4) & 0xF0);  | |||
    PORTD |= (1 << PD4);  | |||
    PORTD |= (1 << PD5);  | |||
    _delay_us(1);  | |||
    PORTD &= ~(1 << PD5);  | |||
    _delay_us(40);  | |||
}  | |||
void updateCounterDisplay()  | |||
{  | |||
    sendLCDCommand(0x80 | 0x40);   | |||
    sendLCDData('P');  | |||
    sendLCDData('o');  | |||
    sendLCDData('s');  | |||
    sendLCDData('i');  | |||
    sendLCDData('t');  | |||
    sendLCDData('i');  | |||
    sendLCDData('o');  | |||
    sendLCDData('n');  | |||
    sendLCDData(':');  | |||
    sendLCDCommand(0x80 | 0x40 | 0x09);    | |||
    sendLCDData(' ');  | |||
    sendLCDData(' ');  | |||
    sendLCDData(' ');  | |||
    sendLCDData(' ');  | |||
    sendLCDData(' ');  | |||
    sendLCDData(' ');  | |||
    sendLCDData(' ');  | |||
    sendLCDData(' ');  | |||
    sendLCDCommand(0x80 | 0x40 | 0x09);    | |||
    sendLCDData((counter / 100) + '0');  | |||
    sendLCDData(((counter / 10) % 10) + '0');  | |||
    sendLCDData((counter % 10) + '0');  | |||
}  | |||
void handleMainMenu()  | |||
{  | |||
    if ((PINB & (1 << clk_pin)) != poutput)  | |||
    {  | |||
        if ((PINB & (1 << data_pin)) != poutput)  | |||
        {  | |||
            counter++;  | |||
        }  | |||
        else  | |||
        {  | |||
            counter--;  | |||
        }  | |||
        updateCounterDisplay();  | |||
    }  | |||
    poutput = PINB & (1 << clk_pin);  | |||
    if ((PINB & (1 << swt_pin)) == 0 && !buttonPressed)  | |||
    {  | |||
        buttonPressed = true;  | |||
        sendLCDCommand(0x01);    | |||
        sendLCDData('P');  | |||
        sendLCDData('r');  | |||
        sendLCDData('e');  | |||
        sendLCDData('s');  | |||
        sendLCDData('s');  | |||
        sendLCDData('e');  | |||
        sendLCDData('d');  | |||
        _delay_ms(500);  | |||
        sendLCDCommand(0x01);   | |||
        menuState = MENU_VALUE;  | |||
        updateCounterDisplay();  | |||
    }  | |||
    else if ((PINB & (1 << swt_pin)) != 0)  | |||
    {  | |||
        buttonPressed = false;  | |||
    }  | |||
}  | |||
void handleValueMenu()  | |||
{  | |||
    if ((PINB & (1 << clk_pin)) != poutput)  | |||
    {  | |||
        if ((PINB & (1 << data_pin)) != poutput)  | |||
        {  | |||
            counter++;  | |||
        }  | |||
        else  | |||
        {  | |||
            counter--;  | |||
        }  | |||
        sendLCDCommand(0x80 | 0x40);    | |||
        sendLCDData('P');  | |||
        sendLCDData('o');  | |||
        sendLCDData('s');  | |||
        sendLCDData('i');  | |||
        sendLCDData('t');  | |||
        sendLCDData('i');  | |||
        sendLCDData('o');  | |||
        sendLCDData('n');  | |||
        sendLCDData(':');  | |||
        sendLCDCommand(0x80 | 0x40 | 0x09);    | |||
        sendLCDData((counter / 100) + '0');  | |||
        sendLCDData(((counter / 10) % 10) + '0');  | |||
        sendLCDData((counter % 10) + '0');  | |||
    }  | |||
    poutput = PINB & (1 << clk_pin);  | |||
    if ((PINB & (1 << swt_pin)) == 0 && !buttonPressed)  | |||
    {  | |||
        menuState = MENU_MAIN;  | |||
        sendLCDCommand(0x01);    | |||
        sendLCDData('V');  | |||
        sendLCDData('a');  | |||
        sendLCDData('l');  | |||
        sendLCDData('u');  | |||
        sendLCDData('e');  | |||
        sendLCDData(' ');  | |||
        sendLCDData('e');  | |||
        sendLCDData('n');  | |||
        sendLCDData('t');  | |||
        sendLCDData('e');  | |||
        sendLCDData('r');  | |||
        sendLCDData('e');  | |||
        sendLCDData('d');  | |||
        sendLCDCommand(0x80 | 0x40);    | |||
        sendLCDData(' ');  | |||
        sendLCDData(' ');  | |||
        sendLCDData(' ');  | |||
        sendLCDData(' ');  | |||
        sendLCDData(' ');  | |||
        sendLCDData(' ');  | |||
        sendLCDData(' ');  | |||
        sendLCDData(' ');  | |||
        sendLCDCommand(0x01);  | |||
        sendLCDData(' ');  | |||
        sendLCDData('R');  | |||
        sendLCDData('o');  | |||
        sendLCDData('t');  | |||
        sendLCDData('a');  | |||
        sendLCDData('r');  | |||
        sendLCDData('y');  | |||
        sendLCDData(' ');  | |||
        sendLCDData('E');  | |||
        sendLCDData('n');  | |||
        sendLCDData('c');  | |||
        sendLCDData('o');  | |||
        sendLCDData('d');  | |||
        sendLCDData('e');  | |||
        sendLCDData('r');  | |||
        sendLCDData(' ');  | |||
        sendLCDData(' ');  | |||
        sendLCDData(' ');  | |||
        sendLCDData(' ');  | |||
        sendLCDData(' ');  | |||
        sendLCDData(' ');  | |||
        sendLCDData(' ');  | |||
        sendLCDData(' ');  | |||
        updateCounterDisplay();  | |||
    }  | |||
    else if ((PINB & (1 << swt_pin)) != 0)  | |||
    {  | |||
        buttonPressed = false;  | |||
    }  | |||
}  | |||
// Hlavní smyčka programu  | |||
int main(void)  | int main(void)  | ||
{  | {  | ||
    initLCD();  | |||
    sei();    | |||
    while (1)  | |||
    {  | |||
        switch (menuState)  | |||
        {  | |||
            case MENU_MAIN:  | |||
                handleMainMenu();  | |||
                break;  | |||
            case MENU_VALUE:  | |||
                handleValueMenu();  | |||
                break;  | |||
        }  | |||
    }  | |||
}  | |||
   {  | </source></tab>  | ||
<tab name="Arduino"><source lang="c++" style="background: LightYellow;">  | |||
#include <LiquidCrystal.h>  | |||
const int clk = 3;  | |||
const int data = 4;  | |||
const int swt = 5;  | |||
int poutput;  | |||
int counter = 0;  | |||
bool buttonPressed = false;  | |||
enum MenuState { MENU_MAIN, MENU_VALUE };  | |||
MenuState menuState = MENU_MAIN;  | |||
LiquidCrystal lcd(0, 1, 8, 9, 10, 11);  | |||
void setup() {  | |||
  lcd.begin(16, 2);  | |||
  lcd.print(" Rotary Encoder ");  | |||
   lcd.setCursor(0, 1);  | |||
  lcd.print("  With Arduino  ");  | |||
  delay(2000);  | |||
  lcd.clear();  | |||
  pinMode(clk, INPUT);  | |||
  pinMode(data, INPUT);  | |||
  pinMode(swt, INPUT_PULLUP);  | |||
  poutput = digitalRead(clk);  | |||
}  | |||
void loop() {  | |||
  switch (menuState) {  | |||
    case MENU_MAIN:  | |||
      handleMainMenu();  | |||
      break;  | |||
    case MENU_VALUE:  | |||
      handleValueMenu();  | |||
      break;  | |||
  }  | |||
}  | |||
void handleMainMenu() {  | |||
   if (digitalRead(clk) != poutput) {  | |||
     if (digitalRead(data) != poutput) {  | |||
      counter++;  | |||
    } else {  | |||
      counter--;  | |||
    }  | |||
    updateCounterDisplay();  | |||
   }  |    }  | ||
   poutput = digitalRead(clk);  | |||
  if (digitalRead(swt) == LOW && !buttonPressed) {  | |||
    buttonPressed = true;  | |||
    lcd.clear();  | |||
    lcd.print("Pressed");  | |||
    delay(500);  | |||
    lcd.clear();  | |||
    menuState = MENU_VALUE;  | |||
    updateCounterDisplay();  | |||
  } else if (digitalRead(swt) == HIGH) {  | |||
    buttonPressed = false;  | |||
  }  | |||
}  | }  | ||
void handleValueMenu() {  | |||
  if (digitalRead(clk) != poutput) {  | |||
    if (digitalRead(data) != poutput) {  | |||
      counter++;  | |||
    } else {  | |||
      counter--;  | |||
    }  | |||
    lcd.setCursor(0, 1);  | |||
    lcd.print("Position: ");  | |||
    lcd.print(counter);  | |||
    lcd.setCursor(9, 1);  | |||
    lcd.print("       ");  // Clear the previous position  | |||
    lcd.setCursor(9, 1);  | |||
    lcd.print(counter);  | |||
  }  | |||
  poutput = digitalRead(clk);  | |||
  if (digitalRead(swt) == LOW && !buttonPressed) {  | |||
    menuState = MENU_MAIN;  | |||
    lcd.clear();  | |||
    lcd.print("Value entered:");  | |||
    lcd.setCursor(0, 1);  | |||
    lcd.print(counter);  | |||
    delay(2000);  | |||
    lcd.clear();  | |||
    lcd.print(" Rotary Encoder ");  | |||
    lcd.setCursor(0, 1);  | |||
    lcd.print("  With Arduino  ");  | |||
    delay(2000);  | |||
    lcd.clear();  | |||
    updateCounterDisplay();  | |||
  } else if (digitalRead(swt) == HIGH) {  | |||
    buttonPressed = false;  | |||
  }  | |||
}  | |||
void updateCounterDisplay() {  | |||
  lcd.setCursor(0, 1);  | |||
  lcd.print("Position: ");  | |||
  lcd.print(counter);  | |||
  lcd.setCursor(9, 1);  | |||
  lcd.print("       ");  // Clear the previous position  | |||
  lcd.setCursor(9, 1);  | |||
  lcd.print(counter);  | |||
}  | |||
</source></tab>  | </source></tab>  | ||
</tabs>  | </tabs>  | ||
Tento program riadi LCD displej a rotujúci enkodér pomocou  AVR studia. Po inicializácii LCD displeja a nastavení pinov pre enkodér, program prechádza cez hlavnú slučku, kde sa kontinuálne vykonáva obsluha stavového automatu. Stavový automat má dva stavy: MENU_MAIN (hlavné menu) a MENU_VALUE (menu pre zmenu hodnoty).  | |||
V stave MENU_MAIN sa program sleduje rotáciu enkodéra a na základe smeru rotácie sa upravuje hodnota premennej counter. Ak je stlačené tlačidlo enkodéra, program prechádza do stavu MENU_VALUE.  | |||
V stave MENU_VALUE sa program opäť sleduje rotáciu enkodéra a upravuje hodnotu counter. Zároveň sa na LCD displej vypisuje text "Pozition:" a za ním aktuálna hodnota counter. Ak je stlačené tlačidlo enkodéra, program sa vráti do stavu MENU_MAIN.  | |||
Celkovo program zabezpečuje riadenie LCD displeja a rotujúceho enkodéra, pričom aktualizuje hodnotu na displeji podľa rotácie enkodéra a umožňuje zmenu hodnoty pomocou stlačenia tlačidla enkodéra. ''zdrojaky.zip'':    | |||
Zdrojový kód: [[Médiá:projektMenoPriezvisko.zip|zdrojaky.zip]]  | Zdrojový kód: [[Médiá:projektMenoPriezvisko.zip|zdrojaky.zip]]  | ||
=== Overenie ===  | === Overenie ===  | ||
Program overujeme tak, že najprv restartujeme Arduino dosku, kde nám na LCD displeji vyškrtne "Rotary Encoder With Arduino". Následne sa nám na obrazovke zjavuje text "Pressed" a potom "Position: 0". V momente, keď začneme otáčať enkóderom, začne sa meniť aj hodnota na LCD displeji, ktorá bola na začiatku 0. Keď prídeme k nejakej vybranej pozícii na enkóderi, stlačíme tlačidlo a na LCD displeji sa nám zobrazí "Value Entered" a posledná zadaná hodnota.    | |||
[[Súbor:  | [[Súbor:Fds.jpg|400px|thumb|center|Aplikácia.]]  | ||
'''Video:'''  | '''Video:'''  | ||
<center><youtube>  | <center><youtube>pOf_roZGrjw</youtube></center>  | ||
Kľúčové slová 'Category', ktoré sú na konci stránky nemeňte.    | Kľúčové slová 'Category', ktoré sú na konci stránky nemeňte.    | ||
[[Category:AVR]] [[Category:MIPS]]  | [[Category:AVR]] [[Category:MIPS]]  | ||
Aktuálna revízia z 21:28, 9. jún 2023
Záverečný projekt predmetu MIPS / LS2023 - Viktor Fos
Zadanie
Rotačný enkóder - vytvorime program pre zadávanie hodnoty nejakej veličiny na LCD displeji pomocou tohoto enkodéra. Jednoduché menu, výber hodnoty a zadávanie číselnej veličiny so zmenou nahor/nadol a potvrdenie stlačením.

Literatúra:
Analýza a opis riešenia
Najprv som podľa schémy zapojenia pripojil LCD displej a rotačný enkoder na dosku Arduino Uno.

Algoritmus a program
Algoritmus programu je....
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define clk_pin PB3
#define data_pin PB4
#define swt_pin PB5
volatile int poutput;
volatile int counter = 0;
volatile bool buttonPressed = false;
enum MenuState { MENU_MAIN, MENU_VALUE };
volatile MenuState menuState = MENU_MAIN;
void initLCD()
{
   
    DDRD |= (1 << PD0) | (1 << PD1) | (1 << PD2) | (1 << PD3) | (1 << PD4) | (1 << PD5);
    
    
    PORTD = 0x20;
    PORTD |= 0x04;
    PORTD &= ~0x04;
    
    
    sendLCDCommand(0x28);
    
  
    sendLCDCommand(0x0C);
    
    sendLCDCommand(0x01);
    
    
    DDRB &= ~(1 << clk_pin) & ~(1 << data_pin) & ~(1 << swt_pin);
    PORTB |= (1 << clk_pin) | (1 << data_pin) | (1 << swt_pin);
    
    
    poutput = PINB & (1 << clk_pin);
}
void sendLCDCommand(uint8_t command)
{
    PORTD = (command & 0xF0);
    PORTD &= ~(1 << PD4);
    PORTD |= (1 << PD5);
    _delay_us(1);
    PORTD &= ~(1 << PD5);
    
    PORTD = ((command << 4) & 0xF0);
    PORTD &= ~(1 << PD4);
    PORTD |= (1 << PD5);
    _delay_us(1);
    PORTD &= ~(1 << PD5);
    
    _delay_us(40);
}
void sendLCDData(uint8_t data)
{
    PORTD = (data & 0xF0);
    PORTD |= (1 << PD4);
    PORTD |= (1 << PD5);
    _delay_us(1);
    PORTD &= ~(1 << PD5);
    
    PORTD = ((data << 4) & 0xF0);
    PORTD |= (1 << PD4);
    PORTD |= (1 << PD5);
    _delay_us(1);
    PORTD &= ~(1 << PD5);
    
    _delay_us(40);
}
void updateCounterDisplay()
{
    sendLCDCommand(0x80 | 0x40); 
    sendLCDData('P');
    sendLCDData('o');
    sendLCDData('s');
    sendLCDData('i');
    sendLCDData('t');
    sendLCDData('i');
    sendLCDData('o');
    sendLCDData('n');
    sendLCDData(':');
    
    sendLCDCommand(0x80 | 0x40 | 0x09);  
    sendLCDData(' ');
    sendLCDData(' ');
    sendLCDData(' ');
    sendLCDData(' ');
    sendLCDData(' ');
    sendLCDData(' ');
    sendLCDData(' ');
    sendLCDData(' ');
    
    sendLCDCommand(0x80 | 0x40 | 0x09);  
    sendLCDData((counter / 100) + '0');
    sendLCDData(((counter / 10) % 10) + '0');
    sendLCDData((counter % 10) + '0');
}
void handleMainMenu()
{
    if ((PINB & (1 << clk_pin)) != poutput)
    {
        if ((PINB & (1 << data_pin)) != poutput)
        {
            counter++;
        }
        else
        {
            counter--;
        }
        updateCounterDisplay();
    }
    
    poutput = PINB & (1 << clk_pin);
    
    if ((PINB & (1 << swt_pin)) == 0 && !buttonPressed)
    {
        buttonPressed = true;
        sendLCDCommand(0x01);  
        sendLCDData('P');
        sendLCDData('r');
        sendLCDData('e');
        sendLCDData('s');
        sendLCDData('s');
        sendLCDData('e');
        sendLCDData('d');
        _delay_ms(500);
        sendLCDCommand(0x01); 
        menuState = MENU_VALUE;
        updateCounterDisplay();
    }
    else if ((PINB & (1 << swt_pin)) != 0)
    {
        buttonPressed = false;
    }
}
void handleValueMenu()
{
    if ((PINB & (1 << clk_pin)) != poutput)
    {
        if ((PINB & (1 << data_pin)) != poutput)
        {
            counter++;
        }
        else
        {
            counter--;
        }
        sendLCDCommand(0x80 | 0x40);  
        sendLCDData('P');
        sendLCDData('o');
        sendLCDData('s');
        sendLCDData('i');
        sendLCDData('t');
        sendLCDData('i');
        sendLCDData('o');
        sendLCDData('n');
        sendLCDData(':');
        
        sendLCDCommand(0x80 | 0x40 | 0x09);  
        sendLCDData((counter / 100) + '0');
        sendLCDData(((counter / 10) % 10) + '0');
        sendLCDData((counter % 10) + '0');
    }
    
    poutput = PINB & (1 << clk_pin);
    
    if ((PINB & (1 << swt_pin)) == 0 && !buttonPressed)
    {
        menuState = MENU_MAIN;
        sendLCDCommand(0x01);  
        sendLCDData('V');
        sendLCDData('a');
        sendLCDData('l');
        sendLCDData('u');
        sendLCDData('e');
        sendLCDData(' ');
        sendLCDData('e');
        sendLCDData('n');
        sendLCDData('t');
        sendLCDData('e');
        sendLCDData('r');
        sendLCDData('e');
        sendLCDData('d');
        sendLCDCommand(0x80 | 0x40);  
        sendLCDData(' ');
        sendLCDData(' ');
        sendLCDData(' ');
        sendLCDData(' ');
        sendLCDData(' ');
        sendLCDData(' ');
        sendLCDData(' ');
        sendLCDData(' ');
        sendLCDCommand(0x01);
        sendLCDData(' ');
        sendLCDData('R');
        sendLCDData('o');
        sendLCDData('t');
        sendLCDData('a');
        sendLCDData('r');
        sendLCDData('y');
        sendLCDData(' ');
        sendLCDData('E');
        sendLCDData('n');
        sendLCDData('c');
        sendLCDData('o');
        sendLCDData('d');
        sendLCDData('e');
        sendLCDData('r');
        sendLCDData(' ');
        sendLCDData(' ');
        sendLCDData(' ');
        sendLCDData(' ');
        sendLCDData(' ');
        sendLCDData(' ');
        sendLCDData(' ');
        sendLCDData(' ');
        updateCounterDisplay();
    }
    else if ((PINB & (1 << swt_pin)) != 0)
    {
        buttonPressed = false;
    }
}
// Hlavní smyčka programu
int main(void)
{
    initLCD();
    sei();  
    
    while (1)
    {
        switch (menuState)
        {
            case MENU_MAIN:
                handleMainMenu();
                break;
            case MENU_VALUE:
                handleValueMenu();
                break;
        }
    }
}
#include <LiquidCrystal.h>
const int clk = 3;
const int data = 4;
const int swt = 5;
int poutput;
int counter = 0;
bool buttonPressed = false;
enum MenuState { MENU_MAIN, MENU_VALUE };
MenuState menuState = MENU_MAIN;
LiquidCrystal lcd(0, 1, 8, 9, 10, 11);
void setup() {
  lcd.begin(16, 2);
  lcd.print(" Rotary Encoder ");
  lcd.setCursor(0, 1);
  lcd.print("  With Arduino  ");
  delay(2000);
  lcd.clear();
  pinMode(clk, INPUT);
  pinMode(data, INPUT);
  pinMode(swt, INPUT_PULLUP);
  poutput = digitalRead(clk);
}
void loop() {
  switch (menuState) {
    case MENU_MAIN:
      handleMainMenu();
      break;
    case MENU_VALUE:
      handleValueMenu();
      break;
  }
}
void handleMainMenu() {
  if (digitalRead(clk) != poutput) {
    if (digitalRead(data) != poutput) {
      counter++;
    } else {
      counter--;
    }
    updateCounterDisplay();
  }
  poutput = digitalRead(clk);
  if (digitalRead(swt) == LOW && !buttonPressed) {
    buttonPressed = true;
    lcd.clear();
    lcd.print("Pressed");
    delay(500);
    lcd.clear();
    menuState = MENU_VALUE;
    updateCounterDisplay();
  } else if (digitalRead(swt) == HIGH) {
    buttonPressed = false;
  }
}
void handleValueMenu() {
  if (digitalRead(clk) != poutput) {
    if (digitalRead(data) != poutput) {
      counter++;
    } else {
      counter--;
    }
    lcd.setCursor(0, 1);
    lcd.print("Position: ");
    lcd.print(counter);
    lcd.setCursor(9, 1);
    lcd.print("       ");  // Clear the previous position
    lcd.setCursor(9, 1);
    lcd.print(counter);
  }
  poutput = digitalRead(clk);
  if (digitalRead(swt) == LOW && !buttonPressed) {
    menuState = MENU_MAIN;
    lcd.clear();
    lcd.print("Value entered:");
    lcd.setCursor(0, 1);
    lcd.print(counter);
    delay(2000);
    lcd.clear();
    lcd.print(" Rotary Encoder ");
    lcd.setCursor(0, 1);
    lcd.print("  With Arduino  ");
    delay(2000);
    lcd.clear();
    updateCounterDisplay();
  } else if (digitalRead(swt) == HIGH) {
    buttonPressed = false;
  }
}
void updateCounterDisplay() {
  lcd.setCursor(0, 1);
  lcd.print("Position: ");
  lcd.print(counter);
  lcd.setCursor(9, 1);
  lcd.print("       ");  // Clear the previous position
  lcd.setCursor(9, 1);
  lcd.print(counter);
}
Tento program riadi LCD displej a rotujúci enkodér pomocou AVR studia. Po inicializácii LCD displeja a nastavení pinov pre enkodér, program prechádza cez hlavnú slučku, kde sa kontinuálne vykonáva obsluha stavového automatu. Stavový automat má dva stavy: MENU_MAIN (hlavné menu) a MENU_VALUE (menu pre zmenu hodnoty).
V stave MENU_MAIN sa program sleduje rotáciu enkodéra a na základe smeru rotácie sa upravuje hodnota premennej counter. Ak je stlačené tlačidlo enkodéra, program prechádza do stavu MENU_VALUE.
V stave MENU_VALUE sa program opäť sleduje rotáciu enkodéra a upravuje hodnotu counter. Zároveň sa na LCD displej vypisuje text "Pozition:" a za ním aktuálna hodnota counter. Ak je stlačené tlačidlo enkodéra, program sa vráti do stavu MENU_MAIN.
Celkovo program zabezpečuje riadenie LCD displeja a rotujúceho enkodéra, pričom aktualizuje hodnotu na displeji podľa rotácie enkodéra a umožňuje zmenu hodnoty pomocou stlačenia tlačidla enkodéra. zdrojaky.zip:
Zdrojový kód: zdrojaky.zip
Overenie
Program overujeme tak, že najprv restartujeme Arduino dosku, kde nám na LCD displeji vyškrtne "Rotary Encoder With Arduino". Následne sa nám na obrazovke zjavuje text "Pressed" a potom "Position: 0". V momente, keď začneme otáčať enkóderom, začne sa meniť aj hodnota na LCD displeji, ktorá bola na začiatku 0. Keď prídeme k nejakej vybranej pozícii na enkóderi, stlačíme tlačidlo a na LCD displeji sa nám zobrazí "Value Entered" a posledná zadaná hodnota.

Video:
Kľúčové slová 'Category', ktoré sú na konci stránky nemeňte.