123D circuits – Symulacja arduino część 2 (wyświetlacz LCD, wyświetlacz 7 segmentowy)

W tym artykule opiszę jak sterować wyświetlaczami pod arduino. Pod lupę wezmę wyświetlacze LCD oraz 7-segmentowe. Jako że elektronika przy wyświetlaczach LCD jest zdecydowanie prostsza to zacznę od nich.

Wyświetlacze LCD

Wyświetlacze ze sterownikiem hd44780 do sterowania wykorzystują 8 bitową magistrale danych i 3 bitową magistrale sterującą. My jednaj skorzystamy z przyjemniejszej z punktu elektronicznego wersji, czyli magistrala danych na 4 bitach i 2 bity magistrala sterująca.

Użyłem kilka określeń które wytłumaczę:

  • magistrala danych – zbiór linii sygnałowych służących do przesyłania danych
  • magistrala sterująca – zbiór linii sygnałowych sterującymi poprawną wymianą danych

Magistrala sterująca w sterowniku hd44780 zbudowana jest z linii:

  • RS – wybór rejestru
  • RW – wybór typu operacji (czytanie/zapis)
  • E – uruchomienie transmisji

Magistrala danych która jak wspominałem jest 8 bitowa składa się z linii DB0-DB7.

Dodatkowymi „nóżkami” Układu są:

  • VCC – podłączamy napięcie zasilania 5V
  • GND – masa układu
  • V0 – potencjał tego punktu określa kontrast wyświetlacza
  • LED+   – dodatnia końcówka podświetlenia
  • LED-    – ujemna końcówka podświetlenia

W naszej uproszczonej wersji, komunikacja będzie zachodziła tylko w jedną stronę, czyli kontroler wysyła do wyświetlacza, więc pin RW dajemy na stałe do masy, co ustawi wyświetlacz na stałe na czytanie. Dodatkowo z magistrali danych będziemy wykorzystywać tylko linie od DB4 do DB7, otrzymamy 4 bitową magistrale danych. Poniżej przedstawiam jak to wszystko połączyć:

  • GND -> GND
  • VCC -> 5V
  • V0 -> suwak potencjometru
  • RS -> 12 pin arduino
  • RW -> GND
  • E -> 11 pin arduino
  • DB0 -> niepodpięte
  • DB1 -> niepodpięte
  • DB2 -> niepodpięte
  • DB3 -> niepodpięte
  • DB4 -> 5 pin arduino
  • DB5 -> 4 pin arduino
  • DB6 -> 3 pin arduino
  • DB7 -> 2 pin arduino
  • LED+ -> 5V przez rezystor 220Ω
  • LED- -> GND

Poniżej pokazuje jak to powinno wyglądać, niestety nie widać wszystkich szczegółów dla tego cała ta powyższa lista.

1

Kiedy mamy już wszystko podpięte to możemy przejść do programu. Wykorzystamy bibliotekę „LiquidCrystal.h” która jest standardową biblioteką w arduino i zawiera wszystkie potrzebne funkcje. A program wygląda tak:

 

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() 
{
  lcd.begin(16, 2);
  lcd.print("robotyka.net.pl");
}

void loop() 
{
  
}

W pierwszej linii ładujemy plik biblioteki, następnie definiujemy zmienną led i deklarujemy gdzie jest podpięty nasz wyświetlacz(kolejno jest to: RS, E, DB4, DB5, DB6, DB7). W funkcji setup() ustawiamy jaki mamy rozmiar wyświetlacza, czyli 16×2, a następnie wypisujemy napis. Funkcja loop() jest pusta, w kółko robi „nic”.

Jak widać wszystko ładnie się wyświetliło, niestety widać opóźnienia które generuje symulator, ale grunt, że działa. Zaprezentowałem także regulacje kontrastu wyświetlacza w praktyce jest to zależne od konta patrzenia i naświetlenia otoczenia.

Przydatne funkcje do LCD

Aby ustawić kursor w odpowiednim miejscu tam gdzie chcemy zacząć pisać stosuje się funkcje setCursor(x,y). Jako x oznacza się pozycję w lini od 0 do 15, a to numer wiersza 0 lub 1.

Funkcje blink(), oraz noBlink(), służą do kontroli wyglądu kursora, kiedy wywołamy funkcję blink(), na pozycji kursora pojawi się kostka, która będzie migała. Miganie kursora będzie włączone cały czas do puki nie wywołamy funkcji noBlink().

Czasami sachodzi potrzeba wygaszenia wyświetlacza, w tym celu możemy zastosować funkcję noDisplay(), a aby włączyć wyświetlanie korzystamy z funkcji display().

Po szerszy opis biblioteki zapraszam na stronę, gdzie znajduje się szeroki opis każdej z funkcji wraz z przykładami.

Wyświetlacz 7-segmentowy

Ten typ wyświetlaczy jest ceniony z bardzo dobrą czytelność i mimo, że rozwijają się wyświetlacze LCD nadal w wielu zastosowaniach królują wyświetlacze 7-segmentowe. Nazwa bierze się z tego, że zbudowane są z 7 segmentów, z 7 niezależnych diod LED zamkniętych w jednej obudowie i tak samo jak przy diodzie RGB, mają jedno wyjście wspólne, anodę albo katodę(wspólna anoda jest częściej stosowana). Poniższe zdjęcie przestawia jak rozmieszczone są diody i jakie nazwy im przysługują.

2

Co bardziej spostrzegawcze osoby zauważą, że jest 8 diod, a nie siedem. Zgadza się, tą 8 jest kropka, nie zawsze stosowana, ale już od lat znajduje się w standardzie. My akurat nie będziemy obsługiwać tej kropki i skupimy się tylko na 7 segmentach.

Podłączenie takie wyświetlacza wygląda tak jak przy każdej innej diodzie, w symulatorze 123D Circuits mamy dostępne wyświetlacze ze wspólną anodą, a  więc ją podłączamy do plusa zasilania +5V a każdą z diod poprzez rezystor do portu.

3

Dla ułatwienie wykorzystałem najmniejszą dostępną płytkę prototypową.

Program do testów będzie odliczał od 0 do 9, a na koniec wyświetli znak „-„, i później znowu od zera. Ten program nie jest w pełni optymalnym rozwiązaniem, napisałem go w ten sposób aby lepiej pokazać jak to działa.

int ledA = 6;
int ledB = 5;
int ledC = 2;
int ledD = 3;
int ledE = 4;
int ledF = 7;
int ledG = 8;

void print7(int number);
void ledClear();

int i = 0;

void setup() 
{
  pinMode(ledA, OUTPUT);
  pinMode(ledB, OUTPUT);
  pinMode(ledC, OUTPUT);
  pinMode(ledD, OUTPUT);
  pinMode(ledE, OUTPUT);
  pinMode(ledF, OUTPUT);
  pinMode(ledG, OUTPUT);
  ledClear();
}


void loop() 
{
  print7(i);
  i++;
  delay(1000);
  if(i == 11)
    i = 0;
}

void print7(int number)
{
  ledClear();
  switch(number)
  {
  	case 0:
    	digitalWrite(ledA,LOW);
    	digitalWrite(ledB,LOW);
    	digitalWrite(ledC,LOW);
    	digitalWrite(ledD,LOW);
    	digitalWrite(ledE,LOW);
    	digitalWrite(ledF,LOW);
    	break;
  	case 1:
    	digitalWrite(ledB,LOW);
    	digitalWrite(ledC,LOW);
    	break;
  	case 2:
    	digitalWrite(ledA,LOW);
    	digitalWrite(ledB,LOW);
    	digitalWrite(ledG,LOW);
    	digitalWrite(ledE,LOW);
    	digitalWrite(ledD,LOW);
    	break;
  	case 3:
    	digitalWrite(ledA,LOW);
    	digitalWrite(ledB,LOW);
    	digitalWrite(ledG,LOW);
    	digitalWrite(ledC,LOW);
    	digitalWrite(ledD,LOW);
    	break;
  	case 4:
    	digitalWrite(ledB,LOW);
    	digitalWrite(ledC,LOW);
    	digitalWrite(ledG,LOW);
    	digitalWrite(ledF,LOW);
    	break;
  	case 5:
    	digitalWrite(ledA,LOW);
    	digitalWrite(ledF,LOW);
    	digitalWrite(ledG,LOW);
    	digitalWrite(ledC,LOW);
    	digitalWrite(ledD,LOW);
    	break;
  	case 6:
    	digitalWrite(ledA,LOW);
    	digitalWrite(ledF,LOW);
    	digitalWrite(ledG,LOW);
    	digitalWrite(ledE,LOW);
    	digitalWrite(ledD,LOW);
    	digitalWrite(ledC,LOW);
    	break;
  	case 7:
    	digitalWrite(ledA,LOW);
    	digitalWrite(ledB,LOW);
    	digitalWrite(ledC,LOW);
    	break;
  	case 8:
    	digitalWrite(ledA,LOW);
    	digitalWrite(ledB,LOW);
    	digitalWrite(ledC,LOW);
    	digitalWrite(ledD,LOW);
    	digitalWrite(ledE,LOW);
    	digitalWrite(ledF,LOW);
    	digitalWrite(ledG,LOW);
    	break;
  	case 9:
    	digitalWrite(ledA,LOW);
    	digitalWrite(ledB,LOW);
    	digitalWrite(ledC,LOW);
    	digitalWrite(ledD,LOW);
    	digitalWrite(ledF,LOW);
    	digitalWrite(ledG,LOW);
    	break;
    default:
    	digitalWrite(ledG,LOW);
     	break;
  }
}

void ledClear()
{
  digitalWrite(ledA,HIGH);
  digitalWrite(ledB,HIGH);
  digitalWrite(ledC,HIGH);
  digitalWrite(ledD,HIGH);
  digitalWrite(ledE,HIGH);
  digitalWrite(ledF,HIGH);
  digitalWrite(ledG,HIGH);
}

Jest zdecydowanie dłuższy od poprzednich programów, przez to, że napisałem instrukcje do wyświetlania każdej cyfry z osobna. W pierwszych liniach deklarujemy pod jakimi pinami znajdują się poszczególne diody, następnie mamy deklaracje dwóch funkcji i definicje zmiennej pomocniczej. W funkcji setup(), Ustawiamy porty jako wyjścia i czyścimy ekran. Tą funkcję wytłumaczę za chwilę. W funkcji loop(), odliczamy od 0 do 10 i wypisujemy znak na ekran.

No i teraz najciekawsze, czyli wyświetlanie cyfr w funkcji print7(). W zależności od zmiennej number, która zostaje przekazywana do funkcji wyświetlany jest odpowiedni znak, a samo wyświetlanie polega na zapaleniu odpowiedniej kombinacji LED. Dla ułatwienia przed każdym wypisaniem znaku ekran jest czyszczony. W sytuacji kiedy do funkcji zostanie przekazana inna wartość niż 0-9 to program wypisuje znak „-„. W funkcji czyszczącej wyświetlacz ledClear(), po prostu ustawiamy na każde wyjście sterujące LEDami stan wysoki wygaszając wszystko.

Poniższy film zaprezentuje działanie programu.

Czytelność wyświetlaczy 7-segmentowych jest zdecydowanie większa niż na LCD, lepiej widać z dużej odległości i pod różnymi kątami, dla tego też stosuje się je w różnego typu wskaźnikach, zegarach itp.

W przypadku zastosowania większej ilości wyświetlaczy pojawia się problem z wykorzystaniem bardzo dużej ilości pinów mikrokontrolera, ale na to też jest rozwiązanie. Stosuje się tak zwane multipleksowanie, które polega na podłączeniu wszystkich wyświetlaczy pod te same linie, a tylko sterując anodą(lub katodą) wybieramy który wyświetlacz chcemy zapalić w danym momencie. Okazuje się, że jeżeli dostatecznie szybko będziemy zmieniać aktywne wyświetlacze i prze tą chwilę wyświetlać na nim odpowiedni znak, to ludzkie oko nie zauważy tego. A częstotliwość minimalna z jaką trzeba to robić to 50Hz, czyli raz na 20ms każdy z wyświetlaczy musi zostać zapalony. Kiedy dodamy do tego jeszcze bezwładność diody LED, to efekt jest nie zauważalny. Tak więc dla przykładu chcąc używać czterech wyświetlaczy, potrzebujemy tylko 7 linii na wyświetlanie symbolu i 4 linii na wybór wyświetlacza. Świetnie pokazuje to animacja poniżej, którą zapożyczyłem z internetów:

4

Dodatkowym ważnym elementem są tranzystory pracujące jako klucze, ponieważ żaden port mikrokontrolera nie wytrzymał by tak dużego prądu. Warto dokładnie przestudiować tą animacje a pomoże to przy zrozumieniu działania tego mechanizmu. Przyznam, że długo miałem problem w zrealizowaniu tego, ale kiedy tylko sam zacząłem projektować urządzenie gdzie musiałem zastosować multipleksowanie to okazało się to łatwe.

Ta część dobiega końca, mam nadzieje, że tematyka wyświetlaczy nie jest już obca i możemy przejść dalej. A w następnej części trochę ruch, czyli silniki i serwomechanizmy.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.