Miniatúrny analógový joystick
Zo stránky SensorWiki
Záverečný projekt predmetu MIPS / LS2023 - Samuel Tomáš
Zadanie
Joystick s dvoma analógovými vstupmi a jedným digitálnym - ovládanie RGB LED-ky. Pomocou joysticku budem ovládať RGB LED-ku, analógové PIN-y teda x-ovú a y-ovú os joysticku využijem na na zmenu farby LED-ky a digitálny PIN aplikujem tak, že farby na LED-ke sa budú dať meniť iba pri stlačenom tlačidlo a po vypnutí tlačidla zostane na LED-ke svietiť posledná vysvietená farba.
![](/sensorwiki/images/thumb/7/79/ARDUINO-UNO-POPIS-KOMPONENTOV.png/400px-ARDUINO-UNO-POPIS-KOMPONENTOV.png)
Literatúra:
Analýza a opis riešenia
Ako funguje joystick:
Úloha analógového joysticku je previesť polohu "páky" na dvoch osiach (x a y) na elektrický signál, ktorý dokáže spracovať mikrokontrolér. To je dosiahnuté tým, že v joysticku sú použité dva analógové potenciometre. Každý z nich sníma jednu os, pomocou gymbalového mechanizmu, ktorý oddeľuje horizontálne a vertikálne pohyby. Tento joystick má aj chvíľkový tlačidlový prepínač, ktorý je navrhnutý tak aby fungoval vždy bez ohľadu na polohu páky.
![](/sensorwiki/images/8/8d/Princip_joystick.jpg)
Pri vypracovaní som postupoval nasledovne, ako prvé som zapojil joystick, ktorého schéma zapojenia je zobrazená na obrázku. joystick má 5 PIN-ov (nožičiek), prvý PIN GND (zem) som pripojil na GND (zem) Arduina, druhý PIN je napájacie napätie pre joystick 5V, ktoré som pripojil na PORT 5V v Arduine, ďalšie dva PIN-y sú analógové slúžia na ovládanie x-ovej a y-ovej osi joysticka tieto PIN-y som pripojil na analógové PORT-y Arduina A0 (PC0) a A1 (PC1), posledný PIN je digitálny slúži na ovládanie tlačidla na joysticku, tento som pripojil na digitálny PORT Arduina D2 (PD2).
![](/sensorwiki/images/thumb/6/69/Sch%C3%A9ma_joystick_S.T.jpg/400px-Sch%C3%A9ma_joystick_S.T.jpg.png)
Ďalej bolo potrebné zapojiť RGB LED diódu, schéma zapojenia je opäť zobrazená na obrázku nižšie. Dióda má 4 PIN-y (nožičky), prvý PIN je GND (zem), ktorú som pripojil na GND (zem) Arduina, Ďalšie PIN-y slúžia na ovládanie jednotlivých RGB zložiek LED diódy. Červenú zložku som pripojil na digitálny PORT PWM D9 (PB1), zelenú zložku som pripojil na digitálny PORT PWM D10 (PB2) a modrú zložku som pripojil na digitálny PORT PWM D10 (PB3) na Arduine. Všetky výstupy z Arduina pre LED-ku (PB1,PB2,PB3) prechádzajú cez 10K OHM-ové rezistory pred tým ako sú zapojené do diódy
![](/sensorwiki/images/0/08/RGB_LED_S.T.jpg)
Potom kompletná schéma zapojenia vyzerá nasledovne
![](/sensorwiki/images/thumb/7/7f/RGB_LED_Joystick_Sch%C3%A9ma_Zapojenia.png/400px-RGB_LED_Joystick_Sch%C3%A9ma_Zapojenia.png)
Algoritmus a program
Na začiatku definujem PIN-y pre rôzne časti RGB LED, smerovanie joysticku a tlačidla. Funkciou setup() nastavujem PIN-y mikrokontroléra. PIN-y pre časti RGB LED nastavím ako výstupné, PIN pre tlačidlo ako vstupný a zapnem PULL-UP rezistor pre tento PIN. Funkcia setRGB() slúži na nastavenie výstupu pre rôzne časti RGB LED. Využívam PWM generovanie signálu na riadenie jasu LED. Hodnotu farby som nastavil pomocou registra OCR1A pre červenú časť, OCR1B pre zelenú časť a OCR2A pre modrú časť LED. Funkcia analogRead() slúži na čítanie hodnôt z analógového PIN-u. Využívam AD prevodník ktorý prevádza analógové hodnoty na digitálne. Ďalej som nastavil časovače pre PWM generovanie signálu pre jednotlivé farby LED. TCCR1A a TCCR1B registre používam na časovač 1 (pre červenú a zelenú časť) a TCCR2A a TCCR2B registre používam na časovač 2 (pre modrú časť). V nekonečnej slučke while (1) sa cyklicky vykonáva: Oneskorenie pomocou _delay_ms(25) funkcie, potom sa čítajú hodnoty X a Y osi joysticku a stav tlačidla ak nie je tlačidlo stlačené LED dióda je po resete vypnutá, ak je tlačidlo stlačené LED dióda mení farbu podľa polohy joysticku, keďže máme iba dve osi a tri farby RGB tak nastavíme X os aby určovala červenú farbu a Y os určovala zelenú farbu. Modrá farba je vypočítaná na základe súčtu hodnôt z oboch osí. Po uvoľnení tlačidla zostane svietiť poslednou vysvietenou farbou.
Rozdelenie zložiek farieb aby LED menila plynule farbu do osí budem musieť nejako rozumne vypočítať :
Červená zložka farby chcem aby bola závislá na pohybe joystickom po X-ovej osi rLed = (joyX * 255)/joyY; gLed = (joyY * 255)/joyX ; bLed = (joyX * joyY) / 255;
Modrú farbu budem rozdeľovať medzi súčet hodnôt z y-ovej a x-ovej osi čo predstavuje v mojom prípade hodnotu "total", opäť vynásobím maximálnou hodnotou pre farbu "255" a podelím opäť súčtom hodnôt z x-ovej a y-ovej osi, potom vzorec je nasledovný: bLed = (total * 255) / (joyX + joyY)
<tabs>
//...Samuel Tomáš.....Projekt....MIPS...//
//...Ovládanie RGB LED pomocou joysticku...//
//...knižnice, ktoré využívam...//
#include <avr/io.h>
#include <util/delay.h>
//...Zadefinovanie PIN-ov...//
#define R_PIN 9 // Pin pre červenú časť LED
#define G_PIN 10 // Pin pre zelenú časť LED
#define B_PIN 11 // Pin pre modrú časť LED
#define JX_PIN 0 // Pin pre smer X joysticku (Analog)
#define JY_PIN 1 // Pin pre smer Y joysticku (Analog)
#define JSW_PIN 2 // Pin pre spínač joysticku (Digital)
//...Nastavenie vstupných a výstupných PIN-ov..//
void setup()
{
DDRB |= (1 << PB1) | (1 << PB2) | (1 << PB3); // Nastavenie pinov PB1, PB2, PB3 ako výstupné
DDRD &= ~(1 << PD2); // Nastavenie pinu PD2 ako vstupného
PORTD |= (1 << PD2); // Zapnutie pull-up rezistora pre pin PD2
}
//...Nastavenie výstupu pre rôzne časti RGB LED. Využívam generovanie PWM signálu na riadenie jasu LED...//
void setRGB(uint8_t rLed, uint8_t gLed, uint8_t bLed)
{
OCR1A = 255 - rLed; //...Nastavenie hodnoty pre pin R_PIN...//
OCR1B = 255 - gLed; // Nastavenie hodnoty pre pin G_PIN...//
OCR2A = 255 - bLed; // Nastavenie hodnoty pre pin B_PIN...//
}
//...Čítanie hodnôt z analógového pinu. Využívam AD prevodník, ktorý prevádza analógové hodnoty na digitálne...//
uint16_t analogRead(uint8_t pin)
{
ADMUX = (1 << REFS0) | (pin & 0x0F); //...Nastavenie referenčného napätia na AVCC a výber analógového pinu...//
ADCSRA |= (1 << ADSC) | (1 << ADEN); //...Spustenie konverzie a povolenie AD prevodníka...//
while (ADCSRA & (1 << ADSC)); //...Čakanie na dokončenie konverzie...//
return ADC; //...Vrátenie výsledku konverzie...//
}
int main()
{
setup();
//...Nastavenie časovačov pre PWM generovanie signálu...//
TCCR1A |= (1 << COM1A1) | (1 << COM1B1) | (1 << WGM10);
TCCR1B |= (1 << CS10); //...TCCR1A a TCCR1B registre sa používajú na časovač 1 (pre červenú a zelenú časť)...//
TCCR2A |= (1 << COM2A1) | (1 << WGM20);
TCCR2B |= (1 << CS20); //...CCR2A a TCCR2B registre sa používajú na časovač 2 (pre modrú časť)...//
while (1)
{
_delay_ms(25); //...Oneskorenie 25 ms...//
uint8_t joyX = analogRead(JX_PIN) >> 2; //...Delenie hodnoty X joysticku pre rozsah 0-255...//
uint8_t joyY = analogRead(JY_PIN) >> 2; //...Delenie hodnoty Y joysticku pre rozsah 0-255...//
//...Čítanie stavu (dig) tlačidla...//
uint8_t buttonState = PIND & (1 << PD2);
//...Výpočet pomeru farieb...//
uint16_t total = joyX + joyY; //...Celková suma hodnôt z joysticku...//
uint8_t rLed = (joyX * 255) / total; //...Výpočet hodnoty pre červenú farbu...//
uint8_t gLed = (joyY * 255) / total; //...Výpočet hodnoty pre zelenú farbu...//
uint8_t bLed = (total * 255) / (joyX + joyY); //...Výpočet hodnoty pre modrú farbu...//
if (buttonState == 0)
{
//...Tlačidlo je stlačené, LED je zapnutá...//
setRGB(rLed, gLed, bLed);
}
else
{
//...Tlačidlo nie je stlačené, LED zostane svietiť takou farbou akou sme tlačidlo vypli...//
}
}
return 0;
}
Zbalený projekt:
Zdrojový kód: JOYSTICK_RGB_LED_Samuel_Tomáš_.zip
Overenie
Popis môjho projektu je okomentovaný v priloženom videu.
![](/sensorwiki/images/thumb/7/78/RGB_LED_Joystick_REAL_zapojenie.jpg/400px-RGB_LED_Joystick_REAL_zapojenie.jpg)
Video:
Kľúčové slová 'Category', ktoré sú na konci stránky nemeňte.