Digitálny potenciometer
Zo stránky SensorWiki
Záverečný projekt predmetu MIPS / LS2026 - Yaroslav Buryk
Zadanie
Cieľom bolo navrhnúť a realizovať program pre mikrokontrolér (ATmega328P), ktorý slúži ako digitálny potenciometer.Program musí presne načítavať impulzy bez straty krokov aj pri rýchlej zmene smeru otáčania a realizovať ošetrenie voči mechanickým zákmitom kontaktov (debouncing).

https://docs.arduino.cc/static/cb2219c4f549dd9a7fe040362b668567/a6d36/Pinout-UNOrev3_latest.png
Literatúra:
Analýza a opis riešenia
Pre riešenie úlohy bol zvolený prístup využívajúci hardvérové prerušenia a stavový automat (FSM). Na detekciu smeru otáčania sa využíva stavová tabuľka (state table), ktorá vyhodnocuje prechody v Grayovom kóde. Každá zmena na pinoch vyvolá prerušenie, kde sa porovnáva predchádzajúci stav s aktuálnym. Použité komponenty:
- ATmega328P (Arduino Uno)
- Rotačný enkóder KY-040: Inkrementálny enkóder generujúci dva signály (CLK a DT).
- Datasheet KY-040
- Na potlačenie mechanických zákmitov boli použité dva externé keramické kondenzátory s kapacitou 47 nF pripojené medzi signálne piny (CLK, DT) a zem.

Schéma zapojenia: Enkodér je napájaný cez 5V a GND z Arduina. Signály CLK, DT a SW pripájam k digitálnym vstupom D2, D3 a D4. Na potlačenie šumu používam 47nF kondenzátory zapojené medzi CLK/DT a zemou.

Algoritmus a program
Program je rozdelený na obsluhu prerušení a hlavnú slučku (spracovanie výstupu).
- Obsluha prerušení (ISR):
Používame externé prerušenia INT0 (PD2) a INT1 (PD3). Obe funkcie volajú spoločnú funkciu handle_encoder(). static inline void handle_encoder(): Táto funkcia je optimalizovaná pre rýchlosť. Číta celý port PIND naraz, čím zabezpečuje synchronizáciu dát CLK a DT.
- Atómový prístup (Atómia dát):
Keďže int32_t je 32-bitová premenná na 8-bitovom procesore, jej čítanie v hlavnej slučke prebieha v kritickej sekcii medzi cli() a sei().
- Funkcia init_all():
Konfiguruje piny ako vstupné, zapína interné pull-up rezistory a inicializuje počiatočný stav last_state Výpis kódu je nižšie...
#include <avr/io.h>
int main(void)
{
unsigned int measuredValue;
while (1)
{
/* relax */
}
return(0);
}
#include <avr/io.h>
void adc_init(void); // A/D converter initialization
unsigned int adc_read(char a_pin);
Pridajte sem aj zbalený kompletný projekt, napríklad takto (použite jednoznačné pomenovanie, nemôžeme mať na serveri 10x zdrojaky.zip:
Zdrojový kód: zdrojaky.zip
Overenie
Na overenie funkčnosti digitálneho potenciometra použijeme posielanie dát cez sériový terminál pomocou knižnice UART.

Video:
Čo by som urobil inak
Zamyslite sa spätne nad problémom, ktorý ste riešili a napíšte, čo sa vám nepodarilo a nabudúce by ste spravili inak.
Kľúčové slová 'Category', ktoré sú na konci stránky nemeňte.