Serwis Edukacyjny w I-LO w Tarnowie Materiały dla uczniów liceum |
Wyjście Spis treści Wstecz Dalej
Autor artykułu: mgr Jerzy
Wałaszek |
©2024 mgr Jerzy Wałaszek
|
INPUT | – | tryb odczytu, który pozwala odczytać
mikrokontrolerowi stan logiczny panujący na linii portu.
Samą linię portu możemy traktować jako wewnętrznie
niepodłączoną, ponieważ opór wejściowy jest bardzo duży:
|
INPUT_PULLUP | – | tryb odczytu z podpięciem do +Vcc przez
opornik podciągający:
Opornik R wymusza na wejściu portu stan wysoki 1, jeśli układ zewnętrzny nie ustawi tego portu w stan niski 0 (np. poprzez zwarcie do masy). Ten tryb eliminuje indukowanie się przypadkowych stanów na wejściu portu. Wykorzystuje się go głównie do odczytu stanu przycisków, które w momencie naciśnięcia zwierają wejście portu do masy. |
OUTPUT | – | tryb zapisu. W zależności od stanu
logicznego na wyjściu portu, możemy traktować to wyjście
jako połączone do +Vcc dla stanu 1 lub połączone z masą
dla stanu 0:
|
Dla naszych celów potrzebny będzie tryb INPUT (linia portu niepodłączona) i OUTPUT (linia portu połączona z +Vcc lub z masą).
Rozważmy następujący układ:
Dwie diody LED, D1 i D2 (niebieskie lub białe, z czerwonymi są problemy na Digisparku, szczególnie chińskim) są podłączone poprzez oporniki 220...270Ω do portów P0 i P1.
Jeśli jeden z tych portów pracuje w trybie INPUT, to żadna z diod nie świeci, ponieważ tryb INPUT oznacza przerwę w obwodzie i prąd nie popłynie.
Również prąd nie popłynie, jeśli oba porty będą w trybie OUTPUT i na ich wyjściu będą te same stany logiczne:
Jeśli oba porty będą pracowały w trybie OUTPUT i ustawione zostaną w nich różne stany wyjściowe, to zaświeci się tylko jedna z diod LED:
Podsumujmy tabelką:
Lp. | P0 | P1 | D1 | D2 |
1 | INPUT | X | ||
2 | X | INPUT | ||
3 | INPUT | INPUT | ||
4 | OUTPUT 0 | OUTPUT 0 | ||
5 | OUTPUT 1 | OUTPUT 1 | ||
6 | OUTPUT 0 | OUTPUT 1 | ||
7 | OUTPUT 1 | OUTPUT 0 |
Z analizy wynika, że nie ma możliwości jednoczesnego zapalenia obu diod. Jednak efekt ten uzyskamy przełączając odpowiednio szybko stan obu portów (dwa ostatnie wiersze tabelki, 6 i 7). Umówmy się, że z tabelki wykorzystamy tylko wiersze 3, 6 i 7.
Dla dwóch portów zysk tutaj jest żaden, lecz dołączmy następny port, P2 i zobaczmy, co nam to da:
Do trzech portów można podłączyć 6 diod LED. Tabelka wygląda następująco (pominęliśmy niewykorzystywane tryby pracy):
P0 | P1 | P2 | D1 | D2 | D3 | D4 | D5 | D6 |
INPUT | INPUT | INPUT | ||||||
OUTPUT 0 | OUTPUT 1 | INPUT | ||||||
OUTPUT 1 | OUTPUT 0 | INPUT | ||||||
INPUT | OUTPUT 0 | OUTPUT 1 | ||||||
INPUT | OUTPUT 1 | OUTPUT 0 | ||||||
OUTPUT 0 | INPUT | OUTPUT 1 | ||||||
OUTPUT 1 | INPUT | OUTPUT 0 |
Zwróć uwagę na jedną rzecz. Gdy do dwóch portów prześlemy
przeciwne stany logiczne, to zaświeca się tylko jedna z diod LED
podłączonych bezpośrednio do tych portów. Pozostałe nie zaświecą
się, ponieważ dioda świecąca wymusza na nich zbyt niskie
napięcie. Na przykład, jeśli dioda D1 świeci się, to panuje na
niej napięcie ok. 1,8V (LED czerwona).
Napięcie to rozkłada się na diody D4 i D5
(pozostałe są spolaryzowane zaporowo). Jednakże jest ono
zbyt niskie, aby te diody zaświeciły się
(potrzebne byłoby
3 porty dają nam możliwość sterowania 6 diodami LED. Dodajmy kolejny port P3:
P0 | P1 | P2 | P3 | D1 | D2 | D3 | D4 | D5 | D6 | D7 | D8 | D9 | D10 | D11 | D12 |
INPUT | INPUT | INPUT | INPUT | ||||||||||||
OUTPUT 0 | OUTPUT 1 | INPUT | INPUT | ||||||||||||
OUTPUT 1 | OUTPUT 0 | INPUT | INPUT | ||||||||||||
INPUT | OUTPUT 0 | OUTPUT 1 | INPUT | ||||||||||||
INPUT | OUTPUT 1 | OUTPUT 0 | INPUT | ||||||||||||
INPUT | INPUT | OUTPUT 0 | OUTPUT 1 | ||||||||||||
INPUT | INPUT | OUTPUT 1 | OUTPUT 0 | ||||||||||||
OUTPUT 0 | INPUT | OUTPUT 1 | INPUT | ||||||||||||
OUTPUT 1 | INPUT | OUTPUT 0 | INPUT | ||||||||||||
INPUT | OUTPUT 0 | INPUT | OUTPUT 1 | ||||||||||||
INPUT | OUTPUT 1 | INPUT | OUTPUT 0 | ||||||||||||
OUTPUT 0 | INPUT | INPUT | OUTPUT 1 | ||||||||||||
OUTPUT 1 | INPUT | INPUT | OUTPUT 0 |
Spróbujmy znaleźć zależność pomiędzy liczbą portów a liczbą diod LED:
Porty | LEDy |
2 | 2 |
3 | 6 = 2 × 3 |
4 | 12 = 3 × 4 |
5 | 20 = 4 × 5 |
n | (n-1) × n |
Charlieplexing pozwala zaoszczędzić na portach, jednakże ceną za to jest dosyć skomplikowany sposób sterowania diodami. Procedura sterująca zapala po kolei wybrane diody w pętli wykorzystując powyższą tabelę do sterowania trybami pracy portów. Jeśli zostanie to wykonane wystarczająco szybko (np. 30 razy na sekundę), to nasze oko odbierze obraz świecenia się wielu diod LED. Z uwagi na ten sposób pracy liczba diod nie może być dowolnie duża.
Diody są podpięte do portów P0, P1, P2 i P3 poprzez oporniki 220Ω. Przycisk jest podłączony bezpośrednio do portu P4 i do masy.
Fizycznie diody LED mogą być ułożone na płytce w różny sposób. My wybierzemy trzy warianty:
DS003A | DS003B | DS003C |
Płytkę DS003 proponuję wykonać tylko w wersji prototypowej na płytce stykowej. Digispark jest bardzo prostym układem, co niestety odbija się na jego działaniu. Do portów mikrokontrolera podpięte są diody oraz oporniki (np. do komunikacji poprzez USB). W efekcie powstają w naszej płytce DS003 różne upływy, które powodują lekkie świecenie niektórych diod LED w sytuacji, gdy powinny być zgaszone. Na diodach niebieskich efekt ten nie jest specjalnie rażący, jednak występuje i bez dodatkowych elementów nic z tym nie można zrobić. Dla chętnych zaprojektowałem przykładowe rozwiązania płytki DS003 w różnych konfiguracjach diod LED.
Elementy | Ilość | Uwagi |
Dioda LED | 12 | 3mm niebieska/biała |
Opornik 220Ω | 4 | 0,25W |
Przycisk TACT | 1 | |
Goldpiny męskie długie 1x3 | 1 | |
Goldpiny męskie 1x5 | 1 |
ds003_tht_a.sch | : | schemat ideowy w Eagle |
ds003_tht_a.brd | : | projekt płytki drukowanej w Eagle |
ds003_tht_aa.png | : | obrazek z widokiem elementów na płytce |
ds003_tht_ab.png | : | obrazek spodu płytki |
ds003.svg | : | plik Inkscape do wydruku na drukarce laserowej |
Elementy | Ilość | Uwagi |
Dioda LED | 12 | 0805 niebieska/biała |
Opornik 220Ω | 4 | 0805 |
Przycisk TACT | 1 | SMD |
Goldpiny męskie długie 1x3 | 1 | |
Goldpiny męskie 1x5 | 1 |
ds003_smd_a.sch | : | schemat ideowy w Eagle |
ds003_smd_a.brd | : | projekt płytki drukowanej w Eagle |
ds003_smd_aa.png | : | obrazek z widokiem elementów na płytce |
ds003_smd_at.png | : | obrazek góry płytki |
ds003.svg | : | plik Inkscape do wydruku na drukarce laserowej |
Elementy | Ilość | Uwagi |
Dioda LED | 12 | 3mm niebieska/biała |
Opornik 220Ω | 4 | 0,25W |
Przycisk TACT | 1 | |
Goldpiny męskie długie 1x3 | 1 | |
Goldpiny męskie 1x5 | 1 |
ds003_tht_b.sch | : | schemat ideowy w Eagle |
ds003_tht_b.brd | : | projekt płytki drukowanej w Eagle |
ds003_tht_ba.png | : | obrazek z widokiem elementów na płytce |
ds003_tht_bb.png | : | obrazek spodu płytki |
ds003.svg | : | plik Inkscape do wydruku na drukarce laserowej |
Elementy | Ilość | Uwagi |
Dioda LED | 12 | 0805 niebieska/biała |
Opornik 220Ω | 4 | 0805 |
Przycisk TACT | 1 | SMD |
Goldpiny męskie długie 1x3 | 1 | |
Goldpiny męskie 1x5 | 1 |
ds003_smd_b.sch | : | schemat ideowy w Eagle |
ds003_smd_b.brd | : | projekt płytki drukowanej w Eagle |
ds003_smd_ba.png | : | obrazek z widokiem elementów na płytce |
ds003_smd_bt.png | : | obrazek góry płytki |
ds003.svg | : | plik Inkscape do wydruku na drukarce laserowej |
Elementy | Ilość | Uwagi |
Dioda LED | 12 | 3mm niebieska/biała |
Opornik 220Ω | 4 | 0,25W |
Przycisk TACT | 1 | |
Goldpiny męskie długie 1x3 | 1 | |
Goldpiny męskie 1x5 | 1 |
ds003_tht_c.sch | : | schemat ideowy w Eagle |
ds003_tht_c.brd | : | projekt płytki drukowanej w Eagle |
ds003_tht_ca.png | : | obrazek z widokiem elementów na płytce |
ds003_tht_cb.png | : | obrazek spodu płytki |
ds003.svg | : | plik Inkscape do wydruku na drukarce laserowej |
Elementy | Ilość | Uwagi |
Dioda LED | 12 | 0805 niebieska/biała |
Opornik 220Ω | 4 | 0805 |
Przycisk TACT | 1 | SMD |
Goldpiny męskie długie 1x3 | 1 | |
Goldpiny męskie 1x5 | 1 |
ds003_smd_c.sch | : | schemat ideowy w Eagle |
ds003_smd_c.brd | : | projekt płytki drukowanej w Eagle |
ds003_smd_ca.png | : | obrazek z widokiem elementów na płytce |
ds003_smd_ct.png | : | obrazek góry płytki |
ds003.svg | : | plik Inkscape do wydruku na drukarce laserowej |
Pierwszy program ma na celu przetestowanie wszystkich diod. Przy okazji stworzymy funkcję, z której będą korzystały dalsze programy. Program zapala i gasi kolejne diody LED. Przeanalizuj go dokładnie.
// Charlieplexing // Test nr 1 // (C)2018 mgr Jerzy Wałaszek //--------------------------- // Konfigurujemy mikrokontroler //----------------------------- #define D0 0 // Porty diod LED #define D1 1 #define D2 2 #define D3 3 #define P 4 // Port przycisku void setup() { // Ustawiamy porty diod LED jako wejścia pinMode(D0,INPUT); pinMode(D1,INPUT); pinMode(D2,INPUT); pinMode(D3,INPUT); // P jako wejście z opornikiem podciągającym pinMode(P,INPUT_PULLUP); } // Zapala diodę x //--------------- void LED(char x) { // Gasimy wszystkie diody LED pinMode(D0,INPUT); pinMode(D1,INPUT); pinMode(D2,INPUT); pinMode(D3,INPUT); // Zapalamy odpowiednią diodę LED switch(x) { case 1: pinMode(D0,OUTPUT); pinMode(D1,OUTPUT); digitalWrite(D0,0); digitalWrite(D1,1); break; case 2: pinMode(D0,OUTPUT); pinMode(D1,OUTPUT); digitalWrite(D0,1); digitalWrite(D1,0); break; case 3: pinMode(D1,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D1,0); digitalWrite(D2,1); break; case 4: pinMode(D1,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D1,1); digitalWrite(D2,0); break; case 5: pinMode(D2,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D2,0); digitalWrite(D3,1); break; case 6: pinMode(D2,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D2,1); digitalWrite(D3,0); break; case 7: pinMode(D0,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D0,0); digitalWrite(D2,1); break; case 8: pinMode(D0,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D0,1); digitalWrite(D2,0); break; case 9: pinMode(D1,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D1,0); digitalWrite(D3,1); break; case 10:pinMode(D1,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D1,1); digitalWrite(D3,0); break; case 11:pinMode(D0,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D0,0); digitalWrite(D3,1); break; case 12:pinMode(D0,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D0,1); digitalWrite(D3,0); break; } } char licznik = 0; // Pętla główna //------------- void loop() { LED(licznik++); delay(500); if(licznik == 13) licznik = 0; } |
W charlieplexingu zapalenie więcej niż jednej diody LED uzyskuje się przez naprzemienne zaświecanie diod. Jeśli będzie to robione odpowiednio szybko, to oko zobaczy świecenie kilku diod LED naraz. Poniższy program wykorzystuje tę ideę:
// Charlieplexing // Test nr 2 // (C)2018 mgr Jerzy Wałaszek //--------------------------- // Konfigurujemy mikrokontroler //----------------------------- #define D0 0 // Porty diod LED #define D1 1 #define D2 2 #define D3 3 #define P 4 // Port przycisku void setup() { // Ustawiamy porty diod LED jako wejścia pinMode(D0,INPUT); pinMode(D1,INPUT); pinMode(D2,INPUT); pinMode(D3,INPUT); // P jako wejście z opornikiem podciągającym pinMode(P,INPUT_PULLUP); } // Zapala diodę x //--------------- void LED(char x) { // Gasimy wszystkie diody LED pinMode(D0,INPUT); pinMode(D1,INPUT); pinMode(D2,INPUT); pinMode(D3,INPUT); // Zapalamy odpowiednią diodę LED switch(x) { case 1: pinMode(D0,OUTPUT); pinMode(D1,OUTPUT); digitalWrite(D0,0); digitalWrite(D1,1); break; case 2: pinMode(D0,OUTPUT); pinMode(D1,OUTPUT); digitalWrite(D0,1); digitalWrite(D1,0); break; case 3: pinMode(D1,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D1,0); digitalWrite(D2,1); break; case 4: pinMode(D1,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D1,1); digitalWrite(D2,0); break; case 5: pinMode(D2,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D2,0); digitalWrite(D3,1); break; case 6: pinMode(D2,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D2,1); digitalWrite(D3,0); break; case 7: pinMode(D0,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D0,0); digitalWrite(D2,1); break; case 8: pinMode(D0,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D0,1); digitalWrite(D2,0); break; case 9: pinMode(D1,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D1,0); digitalWrite(D3,1); break; case 10:pinMode(D1,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D1,1); digitalWrite(D3,0); break; case 11:pinMode(D0,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D0,0); digitalWrite(D3,1); break; case 12:pinMode(D0,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D0,1); digitalWrite(D3,0); break; } } unsigned char licznik = 0; // Pętla główna //------------- void loop() { unsigned char a,b,i; a = licznik++; if(licznik == 13) licznik = 1; b = a + 1; if(b == 13) b = 1; for(i = 0; i < 127; i++) { LED(a); delay(1); LED(b); delay(1); } } |
Prosta modyfikacja tego programu tworzy robala:
// Charlieplexing // Robal // (C)2018 mgr Jerzy Wałaszek //--------------------------- // Konfigurujemy mikrokontroler //----------------------------- #define D0 0 // Porty diod LED #define D1 1 #define D2 2 #define D3 3 #define P 4 // Port przycisku void setup() { // Ustawiamy porty diod LED jako wejścia pinMode(D0,INPUT); pinMode(D1,INPUT); pinMode(D2,INPUT); pinMode(D3,INPUT); // P jako wejście z opornikiem podciągającym pinMode(P,INPUT_PULLUP); } // Zapala diodę x //--------------- void LED(char x) { // Gasimy wszystkie diody LED pinMode(D0,INPUT); pinMode(D1,INPUT); pinMode(D2,INPUT); pinMode(D3,INPUT); // Zapalamy odpowiednią diodę LED switch(x) { case 1: pinMode(D0,OUTPUT); pinMode(D1,OUTPUT); digitalWrite(D0,0); digitalWrite(D1,1); break; case 2: pinMode(D0,OUTPUT); pinMode(D1,OUTPUT); digitalWrite(D0,1); digitalWrite(D1,0); break; case 3: pinMode(D1,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D1,0); digitalWrite(D2,1); break; case 4: pinMode(D1,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D1,1); digitalWrite(D2,0); break; case 5: pinMode(D2,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D2,0); digitalWrite(D3,1); break; case 6: pinMode(D2,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D2,1); digitalWrite(D3,0); break; case 7: pinMode(D0,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D0,0); digitalWrite(D2,1); break; case 8: pinMode(D0,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D0,1); digitalWrite(D2,0); break; case 9: pinMode(D1,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D1,0); digitalWrite(D3,1); break; case 10:pinMode(D1,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D1,1); digitalWrite(D3,0); break; case 11:pinMode(D0,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D0,0); digitalWrite(D3,1); break; case 12:pinMode(D0,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D0,1); digitalWrite(D3,0); break; } } unsigned char licznik = 1; // Pętla główna //------------- void loop() { unsigned char r[6],i,j; r[0] = licznik++; if(licznik == 13) licznik = 1; for(i = 1; i < 6; i++) { r[i] = r[i - 1] + 1; if(r[i] == 13) r[i] = 1; } for(i = 0; i < 16; i++) for(j = 0; j < 6; j++) { LED(r[j]); delay(1); } } |
// Charlieplexing // Robal dwukierunkowy // (C)2018 mgr Jerzy Wałaszek //--------------------------- // Konfigurujemy mikrokontroler //----------------------------- #define D0 0 // Porty diod LED #define D1 1 #define D2 2 #define D3 3 #define P 4 // Port przycisku void setup() { // Ustawiamy porty diod LED jako wejścia pinMode(D0,INPUT); pinMode(D1,INPUT); pinMode(D2,INPUT); pinMode(D3,INPUT); // P jako wejście z opornikiem podciągającym pinMode(P,INPUT_PULLUP); } // Zapala diodę x //--------------- void LED(char x) { // Gasimy wszystkie diody LED pinMode(D0,INPUT); pinMode(D1,INPUT); pinMode(D2,INPUT); pinMode(D3,INPUT); // Zapalamy odpowiednią diodę LED switch(x) { case 1: pinMode(D0,OUTPUT); pinMode(D1,OUTPUT); digitalWrite(D0,0); digitalWrite(D1,1); break; case 2: pinMode(D0,OUTPUT); pinMode(D1,OUTPUT); digitalWrite(D0,1); digitalWrite(D1,0); break; case 3: pinMode(D1,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D1,0); digitalWrite(D2,1); break; case 4: pinMode(D1,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D1,1); digitalWrite(D2,0); break; case 5: pinMode(D2,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D2,0); digitalWrite(D3,1); break; case 6: pinMode(D2,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D2,1); digitalWrite(D3,0); break; case 7: pinMode(D0,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D0,0); digitalWrite(D2,1); break; case 8: pinMode(D0,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D0,1); digitalWrite(D2,0); break; case 9: pinMode(D1,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D1,0); digitalWrite(D3,1); break; case 10:pinMode(D1,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D1,1); digitalWrite(D3,0); break; case 11:pinMode(D0,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D0,0); digitalWrite(D3,1); break; case 12:pinMode(D0,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D0,1); digitalWrite(D3,0); break; } } unsigned char licznik = 1; int dir = 1; // Kierunek robala char c = 1; // Stan przycisku // Pętla główna //------------- void loop() { unsigned char r[6],i,j; r[0] = licznik; licznik += dir; if(licznik == 13) licznik = 1; if(licznik == 0) licznik = 12; for(i = 1; i < 6; i++) { r[i] = r[i - 1] + 1; if(r[i] == 13) r[i] = 1; } for(i = 0; i < 16; i++) for(j = 0; j < 6; j++) { LED(r[j]); delay(1); } if(analogRead(2) > 100) c = 1; // Przycisk zwolniony? if(c && (analogRead(2) < 100)) // Przycisk wciśnięty? { dir = - dir; // Zmiana kierunku robala c = 0; // Blokada wciśnięcia } } |
Przy odczycie przycisku z portu P4 napotykamy w Digisparku na problem. Do linii P4 podpięta jest dioda Zenera potrzebna do transmisji poprzez USB. Efekt tego jest taki, iż napięcie na wejściu P4 jest niższe od poziomu logicznego 1 i mikrokontroler interpretuje to jako stan 0 bez względu na to, czy przycisk W jest wciśnięty, czy nie. Zatem odczyt stanu portu funkcją digitalRead(4) nie sprawdzi się na porcie P4. Cóż zatem zrobić? Na szczęście mikrokontroler ATtiny 85 posiada możliwość pomiaru napięcia na wejściu portu. Jest to tzw. wejście analogowe (ang. analog input). Wejścia analogowe posiadają inną numerację od wejść cyfrowych:
Na powyższym rysunku wejścia analogowe oznaczone są jako ADCn (ang. Analog/Digital Converter = przetwornik analogowo/cyfrowy). Do portu P4 podłączone jest wejście analogowe ADC2. Wejścia analogowe dokładniej omówimy w dalszej części kursu. Mikrokontroler posiada wbudowany 10-bitowy przetwornik analogowo/cyfrowy. Gdy programujesz w Arduino, użycie wejścia analogowego jest banalnie proste. Stosujesz funkcję analogRead(nr wejścia analogowego). Funkcja ta zwraca wartości od 0 do 1023, które są proporcjonalne do napięcia na wejściu portu. Nas interesuje tylko napięcie niskie, gdy przycisk zwiera wejście portu do masy. Dlatego stan portu sprawdzamy za pomocą instrukcji:
if(analogRead(2) < 100) ... // przycisk wciśnięty if(analogRead(2) > 100) ... // przycisk zwolniony |
Aby wyłapać naciśnięcie przycisku, stosujemy dodatkową zmienną c, która zostaje ustawiona na 0 przy pierwszym wciśnięciu przycisku. Dalsze naciskanie przycisku nie wpływa na działanie programu. Gdy przycisk zostaje zwolniony, zmienna c wraca do stanu 1.
// Charlieplexing // Laser // (C)2018 mgr Jerzy Wałaszek //--------------------------- // Konfigurujemy mikrokontroler //----------------------------- #define D0 0 // Porty diod LED #define D1 1 #define D2 2 #define D3 3 #define P 4 // Port przycisku char r[12]; void setup() { // Ustawiamy porty diod LED jako wejścia pinMode(D0,INPUT); pinMode(D1,INPUT); pinMode(D2,INPUT); pinMode(D3,INPUT); // P jako wejście z opornikiem podciągającym pinMode(P,INPUT_PULLUP); for(char i = 0; i < 12; i++) r[i] = 0; } // Zapala diodę x //--------------- void LED(char x) { // Gasimy wszystkie diody LED pinMode(D0,INPUT); pinMode(D1,INPUT); pinMode(D2,INPUT); pinMode(D3,INPUT); // Zapalamy odpowiednią diodę LED switch(x) { case 1: pinMode(D0,OUTPUT); pinMode(D1,OUTPUT); digitalWrite(D0,0); digitalWrite(D1,1); break; case 2: pinMode(D0,OUTPUT); pinMode(D1,OUTPUT); digitalWrite(D0,1); digitalWrite(D1,0); break; case 3: pinMode(D1,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D1,0); digitalWrite(D2,1); break; case 4: pinMode(D1,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D1,1); digitalWrite(D2,0); break; case 5: pinMode(D2,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D2,0); digitalWrite(D3,1); break; case 6: pinMode(D2,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D2,1); digitalWrite(D3,0); break; case 7: pinMode(D0,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D0,0); digitalWrite(D2,1); break; case 8: pinMode(D0,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D0,1); digitalWrite(D2,0); break; case 9: pinMode(D1,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D1,0); digitalWrite(D3,1); break; case 10:pinMode(D1,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D1,1); digitalWrite(D3,0); break; case 11:pinMode(D0,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D0,0); digitalWrite(D3,1); break; case 12:pinMode(D0,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D0,1); digitalWrite(D3,0); break; } } // Pętla główna //------------- void loop() { unsigned char i,j; if(analogRead(2) < 100) r[0] = 1; else r[0] = 0; for(i = 0; i < 4; i++) for(j = 0; j < 12; j++) { if(r[j]) LED(j+1); else LED(0); delay(1); } for(i = 11; i > 0; i--) r[i] = r[i-1]; } |
// Charlieplexing // Licznik 12-bitowy // (C)2018 mgr Jerzy Wałaszek //--------------------------- // Konfigurujemy mikrokontroler //----------------------------- #define D0 0 // Porty diod LED #define D1 1 #define D2 2 #define D3 3 #define P 4 // Port przycisku char r[12]; void setup() { // Ustawiamy porty diod LED jako wejścia pinMode(D0,INPUT); pinMode(D1,INPUT); pinMode(D2,INPUT); pinMode(D3,INPUT); // P jako wejście z opornikiem podciągającym pinMode(P,INPUT_PULLUP); for(char i = 0; i < 12; i++) r[i] = 0; } // Zapala diodę x //--------------- void LED(char x) { // Gasimy wszystkie diody LED pinMode(D0,INPUT); pinMode(D1,INPUT); pinMode(D2,INPUT); pinMode(D3,INPUT); // Zapalamy odpowiednią diodę LED switch(x) { case 1: pinMode(D0,OUTPUT); pinMode(D1,OUTPUT); digitalWrite(D0,0); digitalWrite(D1,1); break; case 2: pinMode(D0,OUTPUT); pinMode(D1,OUTPUT); digitalWrite(D0,1); digitalWrite(D1,0); break; case 3: pinMode(D1,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D1,0); digitalWrite(D2,1); break; case 4: pinMode(D1,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D1,1); digitalWrite(D2,0); break; case 5: pinMode(D2,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D2,0); digitalWrite(D3,1); break; case 6: pinMode(D2,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D2,1); digitalWrite(D3,0); break; case 7: pinMode(D0,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D0,0); digitalWrite(D2,1); break; case 8: pinMode(D0,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D0,1); digitalWrite(D2,0); break; case 9: pinMode(D1,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D1,0); digitalWrite(D3,1); break; case 10:pinMode(D1,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D1,1); digitalWrite(D3,0); break; case 11:pinMode(D0,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D0,0); digitalWrite(D3,1); break; case 12:pinMode(D0,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D0,1); digitalWrite(D3,0); break; } } // Pętla główna //------------- void loop() { unsigned char i; for(i = 0; i < 12; i++) { if(r[i]) LED(i+1); else LED(0); delay(1); } for(i = 0; i < 12; i++) { r[i] ^= 1; if(r[i]) break; } } |
// Charlieplexing // Efekt 1 // (C)2018 mgr Jerzy Wałaszek //--------------------------- // Konfigurujemy mikrokontroler //----------------------------- #define D0 0 // Porty diod LED #define D1 1 #define D2 2 #define D3 3 #define P 4 // Port przycisku char r[12]; void setup() { // Ustawiamy porty diod LED jako wejścia pinMode(D0,INPUT); pinMode(D1,INPUT); pinMode(D2,INPUT); pinMode(D3,INPUT); // P jako wejście z opornikiem podciągającym pinMode(P,INPUT_PULLUP); for(char i = 0; i < 12; i++) r[i] = 0; } // Zapala diodę x //--------------- void LED(char x) { // Gasimy wszystkie diody LED pinMode(D0,INPUT); pinMode(D1,INPUT); pinMode(D2,INPUT); pinMode(D3,INPUT); // Zapalamy odpowiednią diodę LED switch(x) { case 1: pinMode(D0,OUTPUT); pinMode(D1,OUTPUT); digitalWrite(D0,0); digitalWrite(D1,1); break; case 2: pinMode(D0,OUTPUT); pinMode(D1,OUTPUT); digitalWrite(D0,1); digitalWrite(D1,0); break; case 3: pinMode(D1,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D1,0); digitalWrite(D2,1); break; case 4: pinMode(D1,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D1,1); digitalWrite(D2,0); break; case 5: pinMode(D2,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D2,0); digitalWrite(D3,1); break; case 6: pinMode(D2,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D2,1); digitalWrite(D3,0); break; case 7: pinMode(D0,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D0,0); digitalWrite(D2,1); break; case 8: pinMode(D0,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D0,1); digitalWrite(D2,0); break; case 9: pinMode(D1,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D1,0); digitalWrite(D3,1); break; case 10:pinMode(D1,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D1,1); digitalWrite(D3,0); break; case 11:pinMode(D0,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D0,0); digitalWrite(D3,1); break; case 12:pinMode(D0,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D0,1); digitalWrite(D3,0); break; } } char c = 12; char d = 0; // Pętla główna //------------- void loop() { int i,j; if(c == 0) { c = 12; d = 0; for(i = 0; i < 12; i++) r[i] = 0; } r[d] = 1; if(d < c) { if(d > 0) r[d-1] = 0; d++; } else { c--; d = 0; } for(j = 0; j < 8; j++) for(i = 0; i < 12; i++) { if(r[i]) LED(i+1); else LED(0); delay(1); } } |
// Charlieplexing // Efekt 2 // (C)2018 mgr Jerzy Wałaszek //--------------------------- // Konfigurujemy mikrokontroler //----------------------------- #define D0 0 // Porty diod LED #define D1 1 #define D2 2 #define D3 3 #define P 4 // Port przycisku char r[12]; void setup() { // Ustawiamy porty diod LED jako wejścia pinMode(D0,INPUT); pinMode(D1,INPUT); pinMode(D2,INPUT); pinMode(D3,INPUT); // P jako wejście z opornikiem podciągającym pinMode(P,INPUT_PULLUP); for(char i = 0; i < 12; i++) r[i] = 0; } // Zapala diodę x //--------------- void LED(char x) { // Gasimy wszystkie diody LED pinMode(D0,INPUT); pinMode(D1,INPUT); pinMode(D2,INPUT); pinMode(D3,INPUT); // Zapalamy odpowiednią diodę LED switch(x) { case 1: pinMode(D0,OUTPUT); pinMode(D1,OUTPUT); digitalWrite(D0,0); digitalWrite(D1,1); break; case 2: pinMode(D0,OUTPUT); pinMode(D1,OUTPUT); digitalWrite(D0,1); digitalWrite(D1,0); break; case 3: pinMode(D1,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D1,0); digitalWrite(D2,1); break; case 4: pinMode(D1,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D1,1); digitalWrite(D2,0); break; case 5: pinMode(D2,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D2,0); digitalWrite(D3,1); break; case 6: pinMode(D2,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D2,1); digitalWrite(D3,0); break; case 7: pinMode(D0,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D0,0); digitalWrite(D2,1); break; case 8: pinMode(D0,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D0,1); digitalWrite(D2,0); break; case 9: pinMode(D1,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D1,0); digitalWrite(D3,1); break; case 10:pinMode(D1,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D1,1); digitalWrite(D3,0); break; case 11:pinMode(D0,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D0,0); digitalWrite(D3,1); break; case 12:pinMode(D0,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D0,1); digitalWrite(D3,0); break; } } char c = 0; char d = 1; // Pętla główna //------------- void loop() { int i,j; if(c == 12) { c = 0; d ^= 1; } r[c++] = d; for(j = 0; j < 4; j++) for(i = 0; i < 12; i++) { if(r[i]) LED(i+1); else LED(0); delay(1); } } |
// Charlieplexing // Efekt 3 // (C)2018 mgr Jerzy Wałaszek //--------------------------- // Konfigurujemy mikrokontroler //----------------------------- #define D0 0 // Porty diod LED #define D1 1 #define D2 2 #define D3 3 #define P 4 // Port przycisku void setup() { // Ustawiamy porty diod LED jako wejścia pinMode(D0,INPUT); pinMode(D1,INPUT); pinMode(D2,INPUT); pinMode(D3,INPUT); // P jako wejście z opornikiem podciągającym pinMode(P,INPUT_PULLUP); } // Zapala diodę x //--------------- void LED(char x) { // Gasimy wszystkie diody LED pinMode(D0,INPUT); pinMode(D1,INPUT); pinMode(D2,INPUT); pinMode(D3,INPUT); // Zapalamy odpowiednią diodę LED switch(x) { case 1: pinMode(D0,OUTPUT); pinMode(D1,OUTPUT); digitalWrite(D0,0); digitalWrite(D1,1); break; case 2: pinMode(D0,OUTPUT); pinMode(D1,OUTPUT); digitalWrite(D0,1); digitalWrite(D1,0); break; case 3: pinMode(D1,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D1,0); digitalWrite(D2,1); break; case 4: pinMode(D1,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D1,1); digitalWrite(D2,0); break; case 5: pinMode(D2,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D2,0); digitalWrite(D3,1); break; case 6: pinMode(D2,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D2,1); digitalWrite(D3,0); break; case 7: pinMode(D0,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D0,0); digitalWrite(D2,1); break; case 8: pinMode(D0,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D0,1); digitalWrite(D2,0); break; case 9: pinMode(D1,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D1,0); digitalWrite(D3,1); break; case 10:pinMode(D1,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D1,1); digitalWrite(D3,0); break; case 11:pinMode(D0,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D0,0); digitalWrite(D3,1); break; case 12:pinMode(D0,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D0,1); digitalWrite(D3,0); break; } } int a = 0; int b = 11; int da = 1; int db = -1; // Pętla główna //------------- void loop() { char i,j; for(j = 0; j < 5; j++) for(i = 0; i < 12; i++) { if((i == a) || (i == b) || ((a > b) && (i > b) && (i < a))) LED(i+1); else LED(0); delay(1); } a += da; b += db; if((a == 0) || (a == 11)) da = - da; if((b == 0) || (b == 11)) db = - db; } |
// Charlieplexing // Efekt 4 // (C)2018 mgr Jerzy Wałaszek //--------------------------- // Konfigurujemy mikrokontroler //----------------------------- #define D0 0 // Porty diod LED #define D1 1 #define D2 2 #define D3 3 #define P 4 // Port przycisku char r[12]; void setup() { // Ustawiamy porty diod LED jako wejścia pinMode(D0,INPUT); pinMode(D1,INPUT); pinMode(D2,INPUT); pinMode(D3,INPUT); // P jako wejście z opornikiem podciągającym pinMode(P,INPUT_PULLUP); for(char i = 0; i < 12; i++) r[i] = 0; } // Zapala diodę x //--------------- void LED(char x) { // Gasimy wszystkie diody LED pinMode(D0,INPUT); pinMode(D1,INPUT); pinMode(D2,INPUT); pinMode(D3,INPUT); // Zapalamy odpowiednią diodę LED switch(x) { case 1: pinMode(D0,OUTPUT); pinMode(D1,OUTPUT); digitalWrite(D0,0); digitalWrite(D1,1); break; case 2: pinMode(D0,OUTPUT); pinMode(D1,OUTPUT); digitalWrite(D0,1); digitalWrite(D1,0); break; case 3: pinMode(D1,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D1,0); digitalWrite(D2,1); break; case 4: pinMode(D1,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D1,1); digitalWrite(D2,0); break; case 5: pinMode(D2,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D2,0); digitalWrite(D3,1); break; case 6: pinMode(D2,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D2,1); digitalWrite(D3,0); break; case 7: pinMode(D0,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D0,0); digitalWrite(D2,1); break; case 8: pinMode(D0,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D0,1); digitalWrite(D2,0); break; case 9: pinMode(D1,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D1,0); digitalWrite(D3,1); break; case 10:pinMode(D1,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D1,1); digitalWrite(D3,0); break; case 11:pinMode(D0,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D0,0); digitalWrite(D3,1); break; case 12:pinMode(D0,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D0,1); digitalWrite(D3,0); break; } } // Pętla główna //------------- void loop() { char i,j; for(j = 0; j < 5; j++) for(i = 0; i < 12; i++) { if(r[i]) LED(i+1); else LED(0); delay(1); } r[random(12)] ^= 1; } |
// Charlieplexing // Efekt 5 // (C)2018 mgr Jerzy Wałaszek //--------------------------- // Konfigurujemy mikrokontroler //----------------------------- #define D0 0 // Porty diod LED #define D1 1 #define D2 2 #define D3 3 #define P 4 // Port przycisku void setup() { // Ustawiamy porty diod LED jako wejścia pinMode(D0,INPUT); pinMode(D1,INPUT); pinMode(D2,INPUT); pinMode(D3,INPUT); // P jako wejście z opornikiem podciągającym pinMode(P,INPUT_PULLUP); } // Zapala diodę x //--------------- void LED(char x) { // Gasimy wszystkie diody LED pinMode(D0,INPUT); pinMode(D1,INPUT); pinMode(D2,INPUT); pinMode(D3,INPUT); // Zapalamy odpowiednią diodę LED switch(x) { case 1: pinMode(D0,OUTPUT); pinMode(D1,OUTPUT); digitalWrite(D0,0); digitalWrite(D1,1); break; case 2: pinMode(D0,OUTPUT); pinMode(D1,OUTPUT); digitalWrite(D0,1); digitalWrite(D1,0); break; case 3: pinMode(D1,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D1,0); digitalWrite(D2,1); break; case 4: pinMode(D1,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D1,1); digitalWrite(D2,0); break; case 5: pinMode(D2,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D2,0); digitalWrite(D3,1); break; case 6: pinMode(D2,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D2,1); digitalWrite(D3,0); break; case 7: pinMode(D0,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D0,0); digitalWrite(D2,1); break; case 8: pinMode(D0,OUTPUT); pinMode(D2,OUTPUT); digitalWrite(D0,1); digitalWrite(D2,0); break; case 9: pinMode(D1,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D1,0); digitalWrite(D3,1); break; case 10:pinMode(D1,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D1,1); digitalWrite(D3,0); break; case 11:pinMode(D0,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D0,0); digitalWrite(D3,1); break; case 12:pinMode(D0,OUTPUT); pinMode(D3,OUTPUT); digitalWrite(D0,1); digitalWrite(D3,0); break; } } char c = 0,r,l; // Pętla główna //------------- void loop() { if(!c) { c = 3 + random(5); r = 7; l = 6; } c--; for(int i = 0; i < 4; i++) for(int j = 0; j < 12; j++) { if((j >= l) && (j <= r)) LED(j); else LED(0); delay(1); } r++; l--; } |
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2024 mgr Jerzy Wałaszek |
Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone
pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email:
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.