Serwis Edukacyjny
w I-LO w Tarnowie
obrazek

Materiały dla uczniów liceum

  Wyjście       Spis treści       Wstecz       Dalej  

obrazek

Autor artykułu: mgr Jerzy Wałaszek
Konsultacje: Wojciech Grodowski, mgr inż. Janusz Wałaszek

©2024 mgr Jerzy Wałaszek
I LO w Tarnowie

obrazek

Warsztat

Kurs Digispark

DS003

SPIS TREŚCI
Podrozdziały

Charlieplexing

W poprzednich projektach DS001 i DS002 sterowaliśmy diodami LED podłączonymi do portów mikrokontrolera na płytce Digispark. Technika ta wymaga tylu portów, ile mamy diod LED, lecz pozwala sterować w prosty sposób niezależnie każdą z nich. Jeśli chcemy sterować większą liczbą diod LED niż mamy do dyspozycji portów, to musimy zastosować rozwiązanie o nazwie charlieplexing. Polega ono na odpowiednim podłączaniu diod LED do portów i przełączaniu trybu pracy portów. Porty mikrokontrolera ATtiny mogą pracować w 3 trybach (wybieranych za pomocą funkcji pinMode(port, tryb)):
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:

obrazek

INPUT_PULLUP tryb odczytu z podpięciem do +Vcc przez opornik podciągający:

obrazek

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:

obrazek

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:

obrazek

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:

obrazek

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:

obrazek

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:

obrazek

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 2 x 1,8V = 3,6V).

3 porty dają nam możliwość sterowania 6 diodami LED. Dodajmy kolejny port P3:

obrazek

 

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.


Na początek:  podrozdziału   strony 

Płytka DS003

Schemat ideowy płytki DS003

Dla charlieplexingu zaprojektujemy płytkę ćwiczeniową dla platformy Digispark. Na płytce znajdzie się 12 niebieskich diod LED, 4 oporniki oraz jeden przycisk. Schemat płytki jest następujący:

obrazek

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:

obrazek obrazek obrazek
DS003A DS003B DS003C

Wersja na płytce stykowej

obrazek 

obrazek

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.

DS003_A, wersja THT

obrazek
obrazek
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  

Pliki do pobrania

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

obrazek

DS003_A, wersja SMT

obrazek obrazek
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  

Pliki do pobrania

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

obrazek

DS003_B, wersja THT

obrazek obrazek
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  

Pliki do pobrania

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

obrazek

DS003_B, wersja SMT

obrazek obrazek
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  

Pliki do pobrania

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

DS003_C, wersja THT

obrazek obrazek
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  

Pliki do pobrania

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

obrazek

DS003_C, wersja SMT

obrazek
obrazek
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  

Pliki do pobrania

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

Na początek:  podrozdziału   strony 

Programowanie DS003

obrazek

Test 1

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;
}

Test 2

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:

Robal

// 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);
    }
}

Robal dwukierunkowy

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

obrazek

 

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.

Laser

// 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];
}

Licznik 12-bitowy

// 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;  
  }
}

Efekt nr 1

// 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);
    }
}

Efekt nr 2

// 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);
    }
}

Efekt nr 3

// 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;
}

Efekt nr 4

// 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;
}

Efekt nr 5

// 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--;
}

Na początek:  podrozdziału   strony 

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: i-lo@eduinf.waw.pl

Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.

Informacje dodatkowe.