Sterowanie wyświetlaczem 7 segmentowym

Podłączanie i sterowanie wyświetlaczem 7 segmentowym przez Arduino

W poprzednim artykule omówiliśmy sobie czym jest i jak teoretycznie sterować wyświetlaczem 7 segmentowym.

Teraz przyszedł czas, aby teorię zamienić w praktykę. Na początek postaramy się podłączyć nasz wyświetlacz bezpośrednio do Arduino i zmusić je, aby wyświetlało od 0-9.

Użyty w projekcie wyświetlacz

Powyższe zdjęcie prezentuje wyświetlacz, który został użyty w poniższych przykładach. Jest to siedmiosegmentowy wyświetlacz led koloru zielonego mogący wyświetlić tylko jedną cyfrę na raz. Dodatkowo w prawym dolnym rogu jest dioda, która może być użyta jako kropka.

Do tego projektu wykorzystamy elementy znajdujące się w Starter Kit.

Spis elementów użytych w projekcie:

Podłączenie

Pierwszym krokiem będzie umieszczenie wyświetlacza na płytce stykowej i dołączenie do odpowiednich pinów rezystory ograniczające.

Podłączenie rezystorów ograniczających

Wyświetlacz posiada wspólną anodę, co oznacza wspólny “plus”, a diody sterowane są masą (na rynku dostępne są również wyświetlacze ze wspólną katodą). Poszczególne segmenty będziemy podłączali do pinów Arduino. Jedynym segmentem, który będzie “wisiał” w powietrzu będzie kropka, której na razie nie będziemy podłączać.

Po umieszczeniu wyświetlacza i podłączeniu rezystorów możemy przejść do kolejnego kroku jakim będzie podłączenie odpowiednich pinów Arduino do segmentów naszego wyświetlacza. Poniższe przypisanie pinów jest przykładowe dla zastosowanej biblioteki i każdy może sobie je dowolnie zmienić.

Podłączenie do Arduino

Zacznijmy najpierw od podłączenia wspólnej anody, którą łączymy z pinem 12 Arduino. Następnie możemy podłączyć segmenty wyświetlacza zgodnie z poniższą tabelką:

Podłączenie odpowiednich pinów Arduino do segmentów wyświetlacza

Jeśli wcześniej chcielibyście sprawdzić jak działa wasz wyświetlacz możecie wybrany przez was segment zapalić podłączając go do zasilania Arduino przez umieszczony na płytce stykowej rezystor.

Gotowy do testowania układ

Zakładając, że wszystko zrobiliśmy poprawnie powinniśmy otrzymać układ podobny do zdjęcia powyżej.

Wgrywanie kodu

Teraz czas na ożywienie naszego wyświetlacza. Skorzystamy z gotowej biblioteki, która ma wiele zalet. Po pierwsze ma już zadeklarowane jakie segmenty potrzebne są do wyświetlenia danego znaku/cyfry. Po drugie można w niej zadeklarować ile cyfr może nasz wyświetlacz obsłużyć. Bibliotekę wraz instrukcją w j. ang możecie ściągnąć tutaj.

W pierwszej kolejności postaramy się wyświetlić jakąś cyfrę na naszym wyświetlaczu. Kopiujemy poniższy kod i go wgrywamy.

#include <SevenSeg.h>

SevenSeg disp(11,7,3,5,6,10,2);
const int numOfDigits=1;
int digitPins[numOfDigits]={12};


void setup(){

disp.setDigitPins(numOfDigits,digitPins);


}

void loop(){

  disp.write(1);

}

Jeśli wszystko jest dobrze podłączone nasz wyświetlacz po wgraniu programu powinien wyświetlić cyfrę 1.

Układ wyświetlający 1

Modyfikacja kodu na własne potrzeby

Wróćmy teraz do kodu, żeby zrozumieć co tam zaszło.

#include <SevenSeg.h>

Składnia #include informuje program o zawarciu biblioteki SevenSeg, jeśli w projekcie będziecie chcieli zawrzeć dodatkowo inne biblioteki np. do obsługi zegara RTC, to właśnie tak będą one oznaczone w programie #include <nazwa_biblioteki.h>.

SevenSeg disp(11,7,3,5,6,10,2);

W tej linijce deklarujemy do których pinów podłączone są poszczególne segmenty wyświetlacza. W tym przypadku segment A podłączony jest do pinu 11, segment B do pinu 7 itd.

const int numOfDigits=1;

numOfDigits jest zmienną stałą, która deklaruje liczbę cyfr na wyświetlaczu. W naszym przypadku używamy jednej cyfry, dlatego wpisujemy 1

int digitPins[numOfDigits]={12};

Zmienna digitPins jest tablicą posiadającą piny do których podłączone są wspólne anody. Standardowo biblioteka wspiera wyświetlacze ze wspólną anodą, jednak istnieje możliwość użycia wyświetlacza ze wspólną katodą (w funkcji setup należy dodać linijkę disp.setCommonCathode() ).

disp.setDigitPins(numOfDigits,digitPins);

setDigitPins jest instrukcją, która informuje program o tym, które piny mają być ustawione jako piny sterujące cyframi i ile tych cyfr jest. W naszym przypadku wyświetlacz może wyświetlać tylko 1 cyfrę, a wspólna anoda jest podłączona do pinu 12.

disp.write(1);

Funkcja, która ma za zadanie wyświetlić wpisaną w nawiasie cyfrę.

Jeśli chcielibyście wyświetlić jakiś znak, to istnieje taka możliwość poprzez zastosowanie komendy disp.write(“F”); W tym przypadku na wyświetlaczu powinna się pojawić litera F. Pamiętajcie, że nie każdą literę da się wyświetlić (teoretycznie każda będzie wyświetlona, ale raczej nie wiele wspólnego będzie mieć z rzeczywistą literą, spowodowane jest liczbą segmentów, które mogą służyć do wyświetlania znaków)

Teraz pytanie, co jeśli chcemy zmieniać nasze cyfry na wyświetlaczu, w końcu chodzi o to, aby cyfry można było zmieniać. Tutaj warto się zagłębić w dokumentacje, ponieważ musimy użyć przerwania. Dzięki temu zmiana wyświetlanych cyfr będzie płynna bez zawieszania się czy migania. Jeśli nie użyjemy przerwania, a będziemy chcieli wyświetlić liczby od 0-9, to nasz wyświetlacz będzie na tyle szybko zmieniał liczby, że nasze oczy będą widzieć prawie cały czas 0. Kiedy jednak dodamy przerwanie (dla początkujących ważne jest to, że praktycznie nie trzeba niczego zmieniać, konfigurować, wystarczy dodać kilka linijek i wszystko będzie działać jak należy. Dla zaawansowanych użytkowników istnieje możliwość zmiany ustawień timera, czasu odświeżania) nasz wyświetlacz będzie się odświeżał bez migania.

W tym celu do funkcji setup dodajemy:

disp.setTimer(2);
disp.startTimer();

Na samym końcu naszego całego kodu dodajemy dwie linijki, które zajmą się wszystkim.

ISR(TIMER2_COMPA_vect){
  disp.interruptAction();
}

Cały kod, którego zadaniem jest wyświetlenie cyfr od 0-9:

#include <SevenSeg.h>

SevenSeg disp(11,7,3,5,6,10,2); //podłączenie segmentów A-F do pinów Arduino
const int numOfDigits=1; //liczba cyfr, które nasz wyświetlacz może wyświetlić
int digitPins[numOfDigits]={12}; //deklaracja pinów sterujących wyświetlaczem, jeśli 
                                                   // wyświetlacz może wyświetlić więcej niż jedną cyfrę
                                                //wpisujemy numer pinu Arduino, który będzie sterować


void setup(){

disp.setDigitPins(numOfDigits,digitPins);
disp.setTimer(2); //ustawienie Timera2
disp.startTimer(); //uruchomienie timera

}

void loop(){
   for (int i=0;i<=9;i++){ //od 0-9 zwiększaj zmienną i o 1

     disp.write(i); //wyświetl zmienną i
     delay(1000); //poczekaj 1000ms
   }

}

ISR(TIMER2_COMPA_vect){
  disp.interruptAction();
}

Jak to wygląda możecie zobaczyć na poniższym filmiku:

Działanie układu

Sterowanie wyświetlaczem przy użyciu rejestru 74HC595

A co byście powiedzieli, jeśli napiszę, że do wysterowania wyświetlacza 7 segmentowego wystarczą tylko 3 kable? Oczywiście oprócz zasilania, ale tak, taka możliwość istnieje jeśli pomiędzy wyświetlacz, a Arduino podepniemy rejestr przesuwny. Do tego celu użyjemy rejestru 74HC595, który możecie znaleźć w Starter-kit.

Podłączenie rejestru przesuwnego

Z poprzedniego testu mamy już wyświetlacz z połączonymi rezystorami ograniczającymi wpięty w płytkę stykową. Wpinamy układ 74HC595 i zworkami łączymy piny zasilania z odpowiednimi liniami zasilającymi na płytce stykowej (górne oraz dolnej linie nie są połączone ze sobą, jeśli chcecie mieć zasilanie musicie je ze sobą zewrzeć. tak jak na powyższym obrazku). W dalszych zdjęciach te połączenia pominęliśmy, żeby schemat był przejrzysty.

Podłączenie Arduino do rejestru przesuwnego

Kolejnym krokiem jest podłączenie pinów sterujących do pinów Arduino.

Pin data (14) do pinu 8 Arduino
Pin latch (12) do pinu 7 Arduino
Pin clock (11) do pinu 6 Arduino

Piny rejestru przesuwnego

Mając podpięte piny sterujące możemy przejść do połączenia segmentów wyświetlacza z układem 74HC595. Pin Q z literką łączymy z segmentem z odpowiednią literką. I tak:

Połączenie pinów rejestru z pinami Arduino

Wszystko podłączone

Jeśli skończyliśmy podłączanie wszystkiego (zakładamy, że sprawdziliście połączenia dobrze tzn. nie pomyliliście się przy łączeniu pinów wyświetlacza z pinami rejestru przesuwnego, jeśli taka pomyłka nastąpiła możecie się spotkać z sytuacją kiedy wasze segmenty nie będą się zapalały w odpowiedniej kolejności) powinniśmy zobaczyć coś podobnego do układu na zdjęciu poniżej.

Gotowy do testów układ

Kod

Kolejnym i ostatnim krokiem będzie wgranie poniższego programu, którego zadaniem jest odliczanie od 0-9.

Kod do obsługi wyświetlacza

int dataPin = 8;
int latchPin = 7;
int clockPin = 6;

byte dec_digits[] = {0b11000000,0b11111001,0b10100100,0b10110000,0b10011001,0b10010010,0b10000011,0b11111000,0b10000000,0b10011000 };

void setup() {
  //ustawienie pinów jako wyjść (output) w celu sterowania rejestrem przesuwnym
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}

void loop() {
  for (int numberToDisplay = 0; numberToDisplay < 10; numberToDisplay++) {
    // take the latchPin low so
    // the LEDs don't change while you're sending in bits:
    digitalWrite(latchPin, LOW);
    // shift out the bits:
    shiftOut(dataPin, clockPin, MSBFIRST, dec_digits[numberToDisplay]);
    //take the latch pin high so the LEDs will light up:
    digitalWrite(latchPin, HIGH);
    // pause before next value:
    delay(300);
  }
}

Układ odliczający od 0-9

Jeśli gdzieś w połączeniach został popełniony błąd możecie się spodziewać podobnego widoku jak w poniższym filmiku. Trzeba wtedy prześledzić połączenia wyświetlacza z rejestrem, a także sprawdzić, czy któryś z kabli nie jest przerwany (takie sytuacje się zdarzają, że wszystko jest dobrze podłączone, a okazuje się że kabel do płytki stykowej jest gdzieś przerwany i nie kontaktuje).

Używając wyświetlaczy 7 segmentowych sporo osób ma problem, który pin idzie do którego segmentu LED. Dlatego w pierwszej kolejności dobrze jest stworzyć tablicę przechowującą nasze cyfry w postaci zapalonych lub zgaszonych poszczególnych segmentów. W tym przypadku 0 odpowiada zapalonej diodzie LED, a 1 zgaszonej. Trochę dziwnie, ale jest tak ponieważ używamy wyświetlacza o wspólnej anodzie, a zapalanie się poszczególnych segmentów jest realizowanie przez zwieranie poszczególnych segmentów z masą. Tablica zawiera ustawienia segmentów LED do wyświetlenia dziesięciu liczb 0-9.

byte dec_digits[] = {0b11000000,0b11111001,0b10100100,0b10110000,0b10011001,0b10010010,0b10000011,0b11111000,0b10000000,0b10011000 };

Wiedząc jakie bajty chcemy przesłać do rejestru wystarczy odpalić kod, który będzie nam zmieniał bajty zgodnie ze stworzoną tablicą.

 for (int numberToDisplay = 0; numberToDisplay < 10; numberToDisplay++) {
    // take the latchPin low so 
    // the LEDs don't change while you're sending in bits:
    digitalWrite(latchPin, LOW);
    // shift out the bits:
    shiftOut(dataPin, clockPin, MSBFIRST, dec_digits[numberToDisplay]); 
    //take the latch pin high so the LEDs will light up:
    digitalWrite(latchPin, HIGH);
    // pause before next value:
    delay(300);
  }

Spójrzmy na poniższy kawałek kodu

 shiftOut(dataPin, clockPin, MSBFIRST, dec_digits[numberToDisplay]);

Ustawienia segmentów LED są pobierane z wcześniej stworzonej tablicy dec_digits. Jeśli chcemy wyświetlić np. liczbę 8 musimy wysłać ustawienie z naszej tablicy 10000000, co oznacza, że wszystkie diody LED zostaną zapalone oprócz diody służącej jako kropka.

Testowany układ z błędnymi połączeniami

Poprawnie działający układ

Pliki do pobrania: