Blik!: Rozdiel medzi revíziami
Zo stránky SensorWiki
(17 medziľahlých úprav od rovnakého používateľa nie je zobrazených.) | |||
Riadok 1: | Riadok 1: | ||
<FONT Size="+2">Programovateľný astabilný multivibrátor </FONT> | <FONT Size="+2">Programovateľný astabilný multivibrátor </FONT> | ||
Typický elektronický obvod, ktorý si postaví každý začiatočník je nejaké jednoduché blikátko, obvykle s dvoma tranzistormi, alebo s populárnym časovačom NE555. V roku 2023 však máme predsa len viac možností. Jednou z nich je namiesto obvodu 555 použiť rovnako veľký mikroprocesor ATtiny45, ktorý však môže okrem samotného blikania realizovať aj náročnejšie funkcie. Keďže procesor má možnosť budiť viac ako jednu jedinú LED diódu, využili sme to a v zapojení je použitá trojfarebná RGB dióda OSTAMA51A5A. Pripojená je na tie tri vývody mikroprocesora, ktoré majú okrem bežného digitálneho výstupu aj alternatívnu funkciu s výstupom PWM signálu. Týmto spôsobom môžeme ovládať všetky tri farby spojito (nielen zapni/vypni, ale aj rôzne stupne intenzity a dosiahnuť tak mnoho farebných kombinácií. | |||
Typický elektronický obvod, ktorý si postaví každý začiatočník je nejaké jednoduché blikátko, obvykle [https://www.electronics-tutorials.ws/waveforms/astable.html s dvoma tranzistormi], alebo [https://www.electronics-tutorials.ws/waveforms/555_oscillator.html s populárnym časovačom '''NE555''']. V roku 2023 však máme predsa len viac možností. Jednou z nich je namiesto obvodu 555 použiť rovnako veľký mikroprocesor ATtiny45, ktorý však môže okrem samotného blikania realizovať aj náročnejšie funkcie. Keďže procesor má možnosť budiť viac ako jednu jedinú LED diódu, využili sme to a v zapojení je použitá trojfarebná RGB dióda OSTAMA51A5A. Pripojená je na tie tri vývody mikroprocesora, ktoré majú okrem bežného digitálneho výstupu aj alternatívnu funkciu s výstupom PWM signálu. Týmto spôsobom môžeme ovládať všetky tri farby spojito (nielen zapni/vypni, ale aj rôzne stupne intenzity a dosiahnuť tak mnoho farebných kombinácií. | |||
[[Obrázok:blikFotka1.jpg|450px|thumb|center|''Obvody zrealizované študentmi na predmete [[Digitálne technológie výroby|DTV]] v roku 2023.'']] | [[Obrázok:blikFotka1.jpg|450px|thumb|center|''Obvody zrealizované študentmi na predmete [[Digitálne technológie výroby|DTV]] v roku 2023.'']] | ||
Riadok 481: | Riadok 482: | ||
Teraz už vieme spraviť program, ktorý predvedie všetky možné farby na RGB dióde. Tento demo program si môžete aj priamo stiahnuť ako .hex súbor. | Teraz už vieme spraviť program, ktorý predvedie všetky možné farby na RGB dióde. Tento demo program si môžete aj priamo stiahnuť ako .hex súbor. | ||
Prechod medzi všetkými farbami rozhodne nie je jednoduchý, pohybujeme sa totiž v 3-rozmernom farebnom priestore. | Prechod medzi všetkými farbami rozhodne nie je jednoduchý, pohybujeme sa totiž v 3-rozmernom farebnom priestore. Na to aby sme vyskúšali naozaj všetky farby sa nám RGB priestor celkom nehodí | ||
a ako vhodnejší sa ukazuje priestor HSV, kde stačí meniť jeden parameter, Hue určujúci farebnosť. Nie je to síce celkom dokonalé, ale lepšie ako trojitý vnorený cyklus. Podrobnejší opis tohto | |||
problému nájdete napr. [https://makeabilitylab.github.io/physcomp/arduino/rgb-led-fade.html#crossfading-in-the-hsl-color-space v tomto článku]. | |||
Konverzné rutiny napísal [https://gist.github.com/postspectacular/2a4a8db092011c6743a7 Karsten Schmidt]. Vypočítané hodnoty RGB sa potom posielajú na výstup invertované (teda 255-hodnota), | |||
pretože naše LED diódy sú v zapojení so spoločnou anódou a teda 0 je plný svit, zatiaľ čo 1 je zhasnutá dióda. | |||
<tabs> | <tabs> | ||
<tab name="Arduino"><source lang="c++"> | <tab name="Arduino"><source lang="c++"> | ||
/* | |||
* tento program vychadza z HSV2RGB odtialto: | |||
* https://gist.github.com/postspectacular/2a4a8db092011c6743a7 | |||
* | |||
*/ | |||
const int RED_PIN = 0; | |||
const int GREEN_PIN = 1; | |||
const int BLUE_PIN = 4; | |||
const int DELAY_MS = 20; // delay in ms between changing colors | |||
float col[3]; | |||
float hue = 0.0; | |||
void setup() | void setup() | ||
{ | { | ||
pinMode( | // Set the RGB pins to output | ||
pinMode( | pinMode(RED_PIN, OUTPUT); | ||
pinMode( | pinMode(GREEN_PIN, OUTPUT); | ||
pinMode(BLUE_PIN, OUTPUT); | |||
} | |||
void loop() { | |||
setColor(hsv2rgb(hue, 1.0, 1.0, col)); | |||
delay(DELAY_MS); | |||
hue += 0.01; | |||
if (hue >= 1.0) hue = 0.0; | |||
} | |||
void setColor(float *rgb) { | |||
analogWrite(RED_PIN, (int)((1.0 - rgb[0]) * 255)); | |||
analogWrite(GREEN_PIN, (int)((1.0 - rgb[1]) * 255)); | |||
analogWrite(BLUE_PIN, (int)((1.0 - rgb[2]) * 255)); | |||
} | } | ||
// HSV->RGB conversion based on GLSL version | |||
{ | // expects hsv channels defined in 0.0 .. 1.0 interval | ||
float fract(float x) { return x - int(x); } | |||
float mix(float a, float b, float t) { return a + (b - a) * t; } | |||
float step(float e, float x) { return x < e ? 0.0 : 1.0; } | |||
float* hsv2rgb(float h, float s, float b, float* rgb) { | |||
rgb[0] = b * mix(1.0, constrain(abs(fract(h + 1.0) * 6.0 - 3.0) - 1.0, 0.0, 1.0), s); | |||
rgb[1] = b * mix(1.0, constrain(abs(fract(h + 0.6666666) * 6.0 - 3.0) - 1.0, 0.0, 1.0), s); | |||
rgb[2] = b * mix(1.0, constrain(abs(fract(h + 0.3333333) * 6.0 - 3.0) - 1.0, 0.0, 1.0), s); | |||
return rgb; | |||
} | |||
</source></tab> | </source></tab> | ||
Riadok 544: | Riadok 569: | ||
'''Postup''' | '''Postup''' | ||
# Zoberieme bežné Arduino UNO alebo Nano a pod. V programe Arduino otvoríme File -> Examples -> ArduinoISP -> ArduinoISP a nahráme tento program do mikroprocesora Arduino UNO. Tým sme ho zmenili na programátor. | # Zoberieme bežné Arduino UNO alebo Nano a pod. V programe Arduino otvoríme File -> Examples -> ArduinoISP -> ArduinoISP a nahráme tento program do mikroprocesora Arduino UNO. Tým sme ho zmenili na programátor.<BR>[[Súbor:ArduinoISPprogrammer02.png|400px|center]] | ||
# K takto vytvorenému programátoru pripojíme procesor ATtiny45, ktorý chceme naprogramovať (pozri obr. nižšie)<BR>[[Súbor:ArduinoISPprogrammer.png|center]] | # K takto vytvorenému programátoru pripojíme procesor ATtiny45, ktorý chceme naprogramovať (pozri obr. nižšie)<BR>[[Súbor:ArduinoISPprogrammer.png|400px|center]] | ||
# Ak sme tak už neurobili predtým, doinštalujeme knižnicu a podporu pre procesory radu ATtiny. V menu potom vyberieme typ procesora ATtiny45 bez bootloadera. | # Ak sme tak už neurobili predtým, '''[https://github.com/SpenceKonde/ATTinyCore doinštalujeme knižnicu a podporu pre procesory radu ATtiny]'''. V menu potom vyberieme typ procesora ATtiny45 bez bootloadera. | ||
<BR>[[Súbor:ArduinoISPprogrammer03.png|400px|center]] | |||
# Napíšeme (alebo prenesieme z TinkerCADu) program pre Blik! | # Napíšeme (alebo prenesieme z TinkerCADu) program pre Blik! | ||
# Bežným spôsobom ho skompilujeme a naprogramujeme | # Bežným spôsobom ho skompilujeme a naprogramujeme | ||
<BR>[[Súbor:ArduinoISPprogrammer05.png|400px|center]] | |||
# Naprogramovaný procesor vyberieme z programátora a vložíme do doštičky Blik! | # Naprogramovaný procesor vyberieme z programátora a vložíme do doštičky Blik! | ||
# Ak chceme program zmeniť za iný, pokračujeme bodom 4. | # Ak chceme program zmeniť za iný, pokračujeme bodom 4. | ||
Riadok 565: | Riadok 592: | ||
Úpravou programu podľa vzoru uvedeného pri stavovom automate (Program 3) dostaneme semafor, ktorý zmení stav vždy po stlačení tlačidla. | Úpravou programu podľa vzoru uvedeného pri stavovom automate (Program 3) dostaneme semafor, ktorý zmení stav vždy po stlačení tlačidla. | ||
=== | === Program 6: Semafor === | ||
{| class="wikitable" | |||
|+ style="margin: auto; caption-side:bottom;"|'''Program''' | |||
|- style="vertical-align:top; text-align:left;" | |||
! [[Súbor:Blik_Program06.png|250px]] | |||
! <tabs> | |||
<tab name="Arduino"><source lang="c++"> | |||
void setup() | |||
{ | |||
pinMode(0, OUTPUT); | |||
pinMode(1, OUTPUT); | |||
pinMode(4, OUTPUT); | |||
} | |||
void loop() | |||
{ | |||
// Červená | |||
digitalWrite(0, LOW); | |||
digitalWrite(1, HIGH); | |||
digitalWrite(4, HIGH); | |||
delay(4000); // Wait for 4000 millisecond(s) | |||
// Červená+Žltá | |||
digitalWrite(0, LOW); | |||
digitalWrite(1, HIGH); | |||
digitalWrite(4, LOW); | |||
delay(1000); // Wait for 1000 millisecond(s) | |||
// Zelená | |||
digitalWrite(0, HIGH); | |||
digitalWrite(1, LOW); | |||
digitalWrite(4, HIGH); | |||
delay(4000); // Wait for 4000 millisecond(s) | |||
// Žltá | |||
digitalWrite(0, HIGH); | |||
digitalWrite(1, HIGH); | |||
digitalWrite(4, LOW); | |||
delay(1000); // Wait for 1000 millisecond(s) | |||
} | |||
</source></tab> | |||
</tabs> | |||
|} | |||
=== Infračervený ovládač === | |||
[[Obrázok:blik03.jpg|250px|left]] | |||
Namiesto trojfarebnej RGB diódy osadíme infračervenú diódu (napr. [https://www.vishay.com/docs/81009/tsal6100.pdf Vihay TSAL6100]) a po stlačení tlačidla odvysielame nejaký špeciálny kód, napr. na vypnutie zariadenia. Získame tak jednoduchý diaľkový ovládač. Aby sme vedeli skontrolovať | |||
funkciu zariadenia, pridáme na dosku aj jednu bežnú červenú LED diódu na pozíciu D2. Aby ovládač fungoval spoľahlivo aj na väčšiu vzdialenosť, zameníme rezistor R3 za iný s menšou hodnotou, napr. 27 až 47 Ohm. Pozor však, hoci IR LED zvládne často až prúd 100mA, procesor vie dať na výstup max. 20mA. | |||
Tu sme program zatiaľ nerozchodili, ale v princípe máme dve možnosti, pričom obe spomínajú možnosť inverznej funkcie aj pre indikačnú aj pre vysielaciu LED diodu. | |||
* IRMP - https://github.com/IRMP-org/IRMP | |||
* IRremote - https://github.com/Arduino-IRremote/Arduino-IRremote (based on Ken Sheriff http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html) | |||
Riadok 593: | Riadok 670: | ||
Ak by si zariadenie chcel niekto postaviť, na GitHube sú k dispozícii všetky zdrojáky pre KiCAD ako aj vygenerované Gerber súbory. | Ak by si zariadenie chcel niekto postaviť, na GitHube sú k dispozícii všetky zdrojáky pre KiCAD ako aj vygenerované Gerber súbory. | ||
<html><center> | |||
<IMG Src="http://homemadehardware.com/img/attiny85_pinout.jpeg" width=800> | |||
<BR><I>Pomôcka pre programátora - označenie vývodov a ich funkcie.</I></center></html> |
Aktuálna revízia z 19:01, 9. máj 2023
Programovateľný astabilný multivibrátor
Typický elektronický obvod, ktorý si postaví každý začiatočník je nejaké jednoduché blikátko, obvykle s dvoma tranzistormi, alebo s populárnym časovačom NE555. V roku 2023 však máme predsa len viac možností. Jednou z nich je namiesto obvodu 555 použiť rovnako veľký mikroprocesor ATtiny45, ktorý však môže okrem samotného blikania realizovať aj náročnejšie funkcie. Keďže procesor má možnosť budiť viac ako jednu jedinú LED diódu, využili sme to a v zapojení je použitá trojfarebná RGB dióda OSTAMA51A5A. Pripojená je na tie tri vývody mikroprocesora, ktoré majú okrem bežného digitálneho výstupu aj alternatívnu funkciu s výstupom PWM signálu. Týmto spôsobom môžeme ovládať všetky tri farby spojito (nielen zapni/vypni, ale aj rôzne stupne intenzity a dosiahnuť tak mnoho farebných kombinácií.
Opis a schéma zapojenia
Srdcom celého zariadenia je 8-bitový mikroprocesor ATtiny45V v DIL-8 puzdre. Okrem dvoch napájacích vývodov máme k dispozícii celkom 6 vstupov/výstupov ak použijeme menej presný interný oscilátor. Pre naše účely je celkom dostačujúci. Napájanie je zabezpečené lítiovou batériou Bt1 typu CR2032 s priemerom 20 mm a kapacitou 220mAh. Na plošný spoj umiestnime vhodný držiak, ktorý je umiestnený zo spodnej časti. Vypínač sme do zapojenia nezaradili zámerne, jednak aby sme znížili náklady, ale aj preto, lebo batéria sa dá jednoducho vybrať, alebo aspoň odizolovať malým kúskom plastu priamo v držiaku.
Jediným vstupom je tlačidlo SW1, ktoré spína vstup voči zemi. Aby zapojenie správne fungovalo, musí mať príslušný vstup PB3 mikroprocesora zapnutý interný pull-up rezistor, inak zapojenie nebude fungovať.
Na výstupoch PB0, 1 a 4 sú zapojené tri LED diódy (resp. jedna RGB dióda v ktorej sú všetky tri integrované). Všetky tri diódy majú zapojený aj predradný rezistor R1-3, ktorý obmedzuje maximálny prúd cez diódu. Pri oživovaní sa ukázalo, že intenzita jednotlivých farebných zložiek je ľudským okom vnímaná rozlične, preto sú odpory R1 a R3 menšie (680R) ako R1 (1k) - je to preto, aby subjektívne vnímaná intenzita bola vyrovnaná u všetkých troch diód. Keďže použitá RGB dióda má spoločnú anódu, programátor ju musí ovládať s inverznou logikou, teda zápis log. 0 na výstup LED diódu rozsvieti a log. 1 ju zhasne.
Plošný spoj
Plošný spoj je obojstranný, rozmerov AxB mm navrhnutý v programe KiCAD7. Na obrázku je rozmiestnenie súčiastok a obrazec plošného spoja, ktorý bol napokon vyrobený vo firme JLC PCB (China). Pri návrhu sme zohľadnili najmä to, že výrobok je určený pre začiatočníkov a tak sú všetky súčiastky v prevedení s vývodmi, namiesto miniatúrnych SMD prvkov. Okrem jednoduchšieho spájkovania sa tak zjednoduší aj prípadné meranie alebo výmena prvkov. Snažili sme sa dosiahnuť čo najmenšie rozmery plošného spoja, aby cena ostala primeraná. Plošný spoj je pripravený aj na osadenie alternatívnych prevedení, ktoré sú opísané nižšie.
Osadzovanie súčiastkami začneme päticou na procesor DIL8, ktorá je najnižšia. Dáme pritom pozor na orientáciu výrezom nahor. Potom osadíme tlačidlo a rezistory R1-R3, tu na orientácii súčiastok nezáleží. Napokon osadíme trojfarebnú LED diódu D1 (najkratší vývod 1 je na plošnom spoji označený štvorčekom) a pozície D2, D3 ostanú prázdne. Ako posledný spájkujeme z opačnej strany držiak na gombíkovú batériu. Ak by sme ho osadili skôr, nedostali by sme sa k vývodom ostatných súčiastok. Osadený plošný spoj je na obrázku X.
Zoznam súčiastok
Amount | Product / Datasheet | Reference | Value | Názov | Footprint |
---|---|---|---|---|---|
1 | GOLD-8P | Conn1 | DIL8 | Pätica na integrovaný obvod DIL8 | nie je |
1 | 1-1825910-0 | SW1 | Mikrospinac TACT | Mikrospínač do plošného spoja | Button_Switch_THT:SW_PUSH_6mm_H4.3mm |
1 | CF1/4W-180R | R1 | 180R | Rezistor 1/8W | Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P12.70mm_Horizontal |
1 | CF1/4W-180R | R2 | 180R | Rezistor 1/8W | Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P12.70mm_Horizontal |
1 | CF1/4W-180R | R3 | 180R | Rezistor 1/8W | Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P12.70mm_Horizontal |
1 | OSTAMA51A5A | D1 | OSTAMA51A5A | LED 5mm trojfarebná, RGB | LED_THT:LED_D5.0mm-4_RGB_Staggered_Pins |
1 | L-7113F3BT | D2 | L-7113F3BT | LED 5mm infračervená | LED_THT:LED_D5.0mm |
1 | L-53LID | D3 | L53-LID | LED 5mm červená, nízkopríkonová | LED_THT:LED_D5.0mm |
1 | ATTINY45-20PU | IC1 | ATtiny45-20P | Mikroprocesor Attiny45 DIL8 | Package_DIP:DIP-8_W7.62mm |
1 | KEYS1066 | BT1 | [Keystone1016] | Držiak gombíkovej batérie | Battery:BatteryHolder_Keystone_103_1x20mm |
1 | BAT-CR2032/A | Batt1 | CR2023 | Gombíková batéria 3V typ CR2032 | nie je |
1 | GOLD-8P | Conn1 | DIL8 | Pätica na integrovaný obvod DIL8 | nie je |
Pri osádzaní vám môže pomôcť tento interaktívny diagram, v ktorom sa okrem ľahkej orientácie na doske môžete aj začiarkovať, ktoré súčiastky už máte pripravené a ktoré sú už aj osadené.
Software
Pre programátora je potrebné vedieť, kam je ktorý komponent pripojený, pozri nasledujúcu tabuľku.
Component | Pin | Arduino |
---|---|---|
Red | 5 | PB0 |
Green | 6 | PB1 |
-- | 7 | PB2 |
SW1 | 2 | PB3 |
Blue | 3 | PB4 |
-- | 1 | PB5 |
Program 1: blikanie LED
Najjednoduchší program je naozaj obyčajné blikanie jednou z trojice LED diód. Ak chceme využiť niektorú inú, stačí zmeniť číslo podľa tabuľky vyššie.
/* pin0 - Red LED / 1 - Green / 4 - Blue */
void setup()
{
pinMode(0, OUTPUT);
}
void loop()
{
digitalWrite(0, LOW); // LED On (common Anode)
delay(200); // Wait for 200 ms
digitalWrite(0, HIGH); // LED Off
delay(200); // Wait for 200 ms
}
##define F_CPU 8000000UL // toto je lepsie vlozit do parametrov pre kompilator
#include <avr/io.h>
#include <util/delay.h>
#define LED1 PB0 // pripojena dioda
int main(void)
{
DDRB |= (1 << LED1); // set pin as OUTPUT
while(1)
{
PORTB |= (1<<LED1); // zhasni LED, t.j. clear PB0 na log. 0
_delay_ms(200);
PORTB &= ~(1<<LED1); // ... tak rozsviet LED, t.j. set PB0 na log. 1
_delay_ms(2000);
}
}
/*
* LED Blink s periodou 100:1000 ms
* delay vygenerovane tu http://darcy.rsgc.on.ca/ACES/TEI4M/AVRdelay.html
* pre frekvenciu 8 MHz (ATtiny45, internal osc.)
*
* LED je pripojena na pin5 (PORTB.0)
*/
START: SBI DDRB,0 ; DDRB.0 = 1 (t.j. Output)
LOOP:
CBI PORTB,0 ; PORTB.0 = 0 (t.j. Low, rozsviet LED so spol. Anodou)
; CALL DELAY ; UNSUPPORTED INSTRUCTION ON ATtiny!!!! - treba nahradit RCALL + RET
ldi r18, 5 ; 100ms SVIETI
ldi r19, 15
ldi r20, 242
L1: dec r20
brne L1
dec r19
brne L1
dec r18
brne L1
nop
SBI PORTB,0 ; PORTB.0 = 1 (t.j. High, zhasni LED v obratenej logike)
ldi r18, 41 ; jedna seunda nesvieti (vypocet pre 8MHz!!!)
ldi r19, 150
ldi r20, 128
L2: dec r20
brne L2
dec r19
brne L2
dec r18
brne L2
nop
RJMP LOOP ; Skok na zaciatok (JMP nepodporovane)
Program 2: LED a tlačítko
Asi druhý najjednoduchší program je ovládanie LED diódy tlačítkom. Podľa toho, ktorú si vyberieme, zmeníme číslo výstupu podľa tabuľky vyššie.
#define SW1 1
#define LED1 2
void setup()
{
pinMode(SW1,INPUT_PULLUP);
pinMode(LED1,OUTPUT);
}
void loop()
{
if (digitalRead(SW1) == 0)
digitalWrite(LED1, HIGH);
else
digitalWrite(LED1, LOW);
}
#define F_CPU 8000000UL // toto je lepsie vlozit do parametrov pre kompilator
#define set_bit(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
#define clear_bit(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))
#include <avr/io.h>
#include <util/delay.h>
#define LED1 PB2 // pripojena dioda
#define SW1 PB1 // pripojene tlacitko
int main(void)
{
DDRB |= (1 << LED1); // set LED1 pin as OUTPUT
DDRB &= ~(1<<SW1); // set SW1 pin as INPUT (not necessary, default)
PORTB |= (1<<SW1); // SW1 pull-up ON
while(1)
{
if ( bit_is_clear(PINB, SW1) ) // ak je stlacene tlacitko SW1
set_bit(PORTB,LED1); // LED1 = log.1
else // inak
clear_bit(PORTB,LED1); // LED1 = log.0
}
return 0;
}
/*
* Program01.asm
*
* Ovladanie LED diody tlacitkom
* Created: 16. 2. 2023 18:18:35
*/
START: SBI DDRB,2 ; DDRB.2 = 1 (t.j. Output) - LED
CBI DDRB,1 ; DDRB.1 = 0 (t.j. Input) - SW1
SBI PORTB,1 ; PORTB.1 = 1 set SW1 Pull Up ON
LOOP: SBI PORTB,2 ; PORTB.2 = 1 (t.j. High, rozsviet LED)
ON: SBIS PINB,1 ; IF input on pin = 1 (button NOT pressed), skip next instruction
RJMP ON ; otherwise just loop here
CBI PORTB,2 ; PORTB.2 = 0 (t.j. Low, zhasni LED)
OFF: SBIC PINB,1 ; if input on pin = 0 (button IS pressed), skip next instruction
RJMP OFF ; otherwise just loop here
RJMP LOOP ; Skok na LED On
Program 3: Stavový automat ovládaný tlačidlom
V tomto programe budeme prepínať tlačidlom jednotlivé stavy, v ktorých bude vždy svietiť jedna farba. Jednoducho sa dá program rozšíriť o viac stavov a teda aj viac farieb. V programe kladieme dôraz na správne a jednoznačné vyhodnotenie stavu tlačidla, takže prechody nastávajú naozaj až pri stlačení a pri podržaní program nepokračuje dalej.
Stavový diagram so 4 stavmi medzi ktorými prechádzame po stlačení tlačidla.
#define RedLED 0
#define GreenLED 1
#define BlueLED 4
#define SW1 3
#define LED_OFF HIGH // common Anode mode
#define LED_ON LOW
int StateCounter = 0;
int lastState = 0;
int buttonState = 0;
void setup()
{
pinMode(RedLED, OUTPUT);
pinMode(GreenLED, OUTPUT);
pinMode(BlueLED, OUTPUT);
pinMode(SW1, INPUT_PULLUP); // pozn.: Tento riadok TinkerCAD nevie
}
void loop()
{
buttonState = digitalRead(SW1); // nacitame stav tlacitka
// ak sme stlacili tlacitko a je to zmena oproti minulemu
if ( ( buttonState == 0) && ( buttonState != lastState) )
{
StateCounter += 1; // presun sa do nasledujuceho stavu
if (StateCounter >= 4)
{
StateCounter = 0; // a po poslednom zacni od znova
}
}
switch (StateCounter)
{
case 1: // Red LED On
digitalWrite(RedLED, LED_ON);
digitalWrite(GreenLED, LED_OFF);
digitalWrite(BlueLED, LED_OFF);
break;
case 2: // Green LED On
digitalWrite(GreenLED, LED_ON);
digitalWrite(RedLED, LED_OFF);
digitalWrite(BlueLED, LED_OFF);
break;
case 3: // Blue LED On
digitalWrite(BlueLED, LED_ON);
digitalWrite(RedLED, LED_OFF);
digitalWrite(GreenLED, LED_OFF);
break;
default: // vsetky LED zhasnute
digitalWrite(RedLED, LED_OFF);
digitalWrite(GreenLED, LED_OFF);
digitalWrite(BlueLED, LED_OFF);
}
delay(50); // Wait for 50 millisecond(s)
lastState = buttonState; // a zapamataj si predosly stav tlacitka
}
Program 4: stmievanie LED
Doteraz sme LED diódy ovládali iba dvojstavovo - zapni alebo vypni, kedy dióda buď ostala vypnutá, alebo svietila max. jasom. Príkaz analogWrite nám však umožní nastaviť na výstupe jednu z 255 úrovní od 0 po maximum. Potom môžeme v jednoduchej slučke postupne jas zvyšovať alebo znižovať. Nezabudnite, že diódu máme zapojenú s obrátenou logikou, takže max. hodnota 255 znamená vypnutú LED a hodnota 0 naopak maximálny svit.
// pin0 - Red LED / 1 - Green / 4 - Blue
#define LEDpin 0
int i = 0;
void setup()
{
pinMode(LEDpin, OUTPUT);
}
void loop()
{
for (i = 255; i >= 0; i--) // zvysujeme jas
{
analogWrite(LEDpin, i);
delay(10); // Wait 10 ms
}
for (i = 0; i <= 255; i++) // znizujeme jas
{
analogWrite(LEDpin, i);
delay(10); // Wait 10 ms
}
}
Ak sa vám bude zdať nárast a pokles jasu nerovnomerný, máte pravdu. Je to preto, lebo ľudské oko nemá rovnakú citlivosť na rovnomernú zmenu jasu. Ak to chcete napraviť, môžete použiť komplikovanejší program, napríklad podľa návodu Róberta Ulbrichta na Arduino Slovakia.
Program 5: RGB demo
Teraz už vieme spraviť program, ktorý predvedie všetky možné farby na RGB dióde. Tento demo program si môžete aj priamo stiahnuť ako .hex súbor.
Prechod medzi všetkými farbami rozhodne nie je jednoduchý, pohybujeme sa totiž v 3-rozmernom farebnom priestore. Na to aby sme vyskúšali naozaj všetky farby sa nám RGB priestor celkom nehodí a ako vhodnejší sa ukazuje priestor HSV, kde stačí meniť jeden parameter, Hue určujúci farebnosť. Nie je to síce celkom dokonalé, ale lepšie ako trojitý vnorený cyklus. Podrobnejší opis tohto problému nájdete napr. v tomto článku.
Konverzné rutiny napísal Karsten Schmidt. Vypočítané hodnoty RGB sa potom posielajú na výstup invertované (teda 255-hodnota), pretože naše LED diódy sú v zapojení so spoločnou anódou a teda 0 je plný svit, zatiaľ čo 1 je zhasnutá dióda.
/*
* tento program vychadza z HSV2RGB odtialto:
* https://gist.github.com/postspectacular/2a4a8db092011c6743a7
*
*/
const int RED_PIN = 0;
const int GREEN_PIN = 1;
const int BLUE_PIN = 4;
const int DELAY_MS = 20; // delay in ms between changing colors
float col[3];
float hue = 0.0;
void setup()
{
// Set the RGB pins to output
pinMode(RED_PIN, OUTPUT);
pinMode(GREEN_PIN, OUTPUT);
pinMode(BLUE_PIN, OUTPUT);
}
void loop() {
setColor(hsv2rgb(hue, 1.0, 1.0, col));
delay(DELAY_MS);
hue += 0.01;
if (hue >= 1.0) hue = 0.0;
}
void setColor(float *rgb) {
analogWrite(RED_PIN, (int)((1.0 - rgb[0]) * 255));
analogWrite(GREEN_PIN, (int)((1.0 - rgb[1]) * 255));
analogWrite(BLUE_PIN, (int)((1.0 - rgb[2]) * 255));
}
// HSV->RGB conversion based on GLSL version
// expects hsv channels defined in 0.0 .. 1.0 interval
float fract(float x) { return x - int(x); }
float mix(float a, float b, float t) { return a + (b - a) * t; }
float step(float e, float x) { return x < e ? 0.0 : 1.0; }
float* hsv2rgb(float h, float s, float b, float* rgb) {
rgb[0] = b * mix(1.0, constrain(abs(fract(h + 1.0) * 6.0 - 3.0) - 1.0, 0.0, 1.0), s);
rgb[1] = b * mix(1.0, constrain(abs(fract(h + 0.6666666) * 6.0 - 3.0) - 1.0, 0.0, 1.0), s);
rgb[2] = b * mix(1.0, constrain(abs(fract(h + 0.3333333) * 6.0 - 3.0) - 1.0, 0.0, 1.0), s);
return rgb;
}
Programovanie
Najjednoduchšie si programy vyskúšate v prostredí TinkerCAD
Ak ste navrhli program v simulátore prostredia TinkerCAD, musíte vygenerovať C-kód a ten v prostredí Arduino IDE skompilovať (preložiť) do strojového kódu, ktorý je uložený v tzv. formáte IntelHEX (.hex).
Prenos z TinkerCADu si ušetríte, ak budete písať program priamo v jazyku C s Arduino nadstavbou v Arduino IDE. Aj tam treba zdrojový kód preložiť do IntelHEX formátu.
Okrem toho môžete program napísať v prostredí AVR Studio / AtmelStudio v jazyku C a skompilovať prekladačom avr-gcc, alebo ho napísať priamo v assembleri tohoto procesora.
Napokon potrebujeme preložený .hex súbor nahrať do pamäte mikroprocesora. To sa dá spraviť buď profesionálnym programátorom (napr. Elnec BeeProg2), alebo použijeme ako programátor dosku Arduino so špeciálnym softvérom.
Na otestovanie môžeme použiť už preložený súbor demo.hex
Postup
- Zoberieme bežné Arduino UNO alebo Nano a pod. V programe Arduino otvoríme File -> Examples -> ArduinoISP -> ArduinoISP a nahráme tento program do mikroprocesora Arduino UNO. Tým sme ho zmenili na programátor.
- K takto vytvorenému programátoru pripojíme procesor ATtiny45, ktorý chceme naprogramovať (pozri obr. nižšie)
- Ak sme tak už neurobili predtým, doinštalujeme knižnicu a podporu pre procesory radu ATtiny. V menu potom vyberieme typ procesora ATtiny45 bez bootloadera.
- Napíšeme (alebo prenesieme z TinkerCADu) program pre Blik!
- Bežným spôsobom ho skompilujeme a naprogramujeme
- Naprogramovaný procesor vyberieme z programátora a vložíme do doštičky Blik!
- Ak chceme program zmeniť za iný, pokračujeme bodom 4.
Varianty
Semafor
Namiesto trojfarebnej RGB diódy osadíme tri samostatné diódy - červenú, žltú a zelenú. Dostaneme tak jednoduchý semafor.
Program uvedený nižšie postupne prechádza všetkými stavmi semafora dookola. Časovanie je nastavené na pevno a tlačítko v tomto prípade nemá žiadnu funkciu, mohlo by slúžiť ako vypínač prepínajúci procesor do sleep modu.
Úpravou programu podľa vzoru uvedeného pri stavovom automate (Program 3) dostaneme semafor, ktorý zmení stav vždy po stlačení tlačidla.
Program 6: Semafor
Infračervený ovládač
Namiesto trojfarebnej RGB diódy osadíme infračervenú diódu (napr. Vihay TSAL6100) a po stlačení tlačidla odvysielame nejaký špeciálny kód, napr. na vypnutie zariadenia. Získame tak jednoduchý diaľkový ovládač. Aby sme vedeli skontrolovať
funkciu zariadenia, pridáme na dosku aj jednu bežnú červenú LED diódu na pozíciu D2. Aby ovládač fungoval spoľahlivo aj na väčšiu vzdialenosť, zameníme rezistor R3 za iný s menšou hodnotou, napr. 27 až 47 Ohm. Pozor však, hoci IR LED zvládne často až prúd 100mA, procesor vie dať na výstup max. 20mA.
Tu sme program zatiaľ nerozchodili, ale v princípe máme dve možnosti, pričom obe spomínajú možnosť inverznej funkcie aj pre indikačnú aj pre vysielaciu LED diodu.
- IRMP - https://github.com/IRMP-org/IRMP
- IRremote - https://github.com/Arduino-IRremote/Arduino-IRremote (based on Ken Sheriff http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html)
Podklady
Ak by si zariadenie chcel niekto postaviť, na GitHube sú k dispozícii všetky zdrojáky pre KiCAD ako aj vygenerované Gerber súbory.
Pomôcka pre programátora - označenie vývodov a ich funkcie.