Operácie

Miniatúrny analógový joystick

Z 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.

Arduino Uno.

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.

joystick princíp.

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).

joystick zapojenie.

Ď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

RGB LED zapojenie.

Potom kompletná schéma zapojenia vyzerá nasledovne

RGB LED zapojenie.

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ť : Mojím cieľom bolo zobraziť čo najviac farieb.

Prvé rozloženie, ktoré som spravil nebolo úplne ideálne, pretože som modrú farbu staticky zadefinoval a nedosiahol som ideálny pomer (zobrazené na obrázku nižšie ako 1. varianta). Vzorce na výpočet farieb vyzerali nasledovne:

rLed = (joyX * 255) / total; 
gLed = (joyY * 255) / total;  
bLed = (total * 255) / (joyX + joyY);  

Ďalšie rozloženie, ktoré som vyskúšal bolo výrazne lepšie LED dióda menila farby, ktoré boli pekne sýte, ale nedosiahol som aj tak zobrazenie čo najviac rozličných farieb(Zobrazené na obrázku nižšie ako 2. varianta). Vzorce vyzerali nasledovne:

rLed = (joyX * 255)/joyY;  
gLed = (joyY * 255)/joyX ; 
bLed = (joyX * joyY) / 255; 

Tretie rozloženie je najlepšie, na LED dióde sa dá pomocou joysticku nastaviť široké spektrum farieb( môžeme vidieť na obrázku nižšie ako 3. varianta). Vzorce vyzerajú nasledovne:

rLed = joyX;  
gLed=joyY;   
bLed = 255- rLed-gLed;  

Najlepšie zobrazenie farieb predstavuje teda 3. varianta, ktorá dokáže zobraziť široké spektrum farieb.

RGB porovnanie variant.

<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...//
		//.......

	  //..........Prvá varianta...//
	//  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...//
	   
	   //........Druhá varianta..//
		//uint8_t rLed = (joyX * 255)/joyY;  //...Výpočet hodnoty pre červenú farbu...//
      // uint8_t gLed = (joyY * 255)/joyX ; //...Výpočet hodnoty pre zelenú farbu...//
      // uint8_t bLed = (joyX * joyY) / 255; //...Výpočet hodnoty pre modrú farbu...//
	  
	  //...Tretia varianta...//
		uint8_t rLed = joyX;  //...Výpočet hodnoty pre červenú farbu...//
		uint8_t gLed=joyY;   //...Výpočet hodnoty pre zelenú farbu...//
		uint8_t bLed = 255- rLed-gLed;  //...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.

Aplikácia.

Video:

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