Lekce 9 - Arduino - Sedmisegmentový displej a pole
V minulém dílu, Arduino - LCD displej a jeho programování, jsme se seznámili s LCD displejem a ukázali jsme si praktické příklady jeho využití.
Dnes se v Arduino tutoriálu naučíme programovat další elektronickou komponentu. Budeme se zabývat součástkou, kterou všichni určitě dobře znáte například z digitálních hodin. Tou je sedmisegmentový displej, tedy displej, který díky logickým hodnotám jednotlivých segmentů dokáže zobrazit čísla a některá písmena. Vytvoříme si opět dva projekty, u kterých si detailně popíšeme postup zhotovení, stejně jako jejich funkčnost.
Sedmisegmentový displej
Sedmisegmentový displej je typ displeje, který je schopen zobrazovat pouze základní číslice a několik symbolů. Každý segment je tvořen jednou nebo více diodami, které jsou schopné svítit. Sedmisegmentové displeje jsou často používány v elektronických přístrojích pro zobrazování čísel nebo symbolů, jako jsou například digitální hodiny, teploměry nebo počítadla. Sedmisegmentový displej může být vyroben z různých materiálů, například z LED nebo LCD:
Seznam součástek
Na zapojení projektu budeme potřebovat tyto součástky:
- 1x mikropočítač Arduino,
- 1x rezistor 220 [Ω],
- 1x sedmisegmentový displej a
- propojovací kabely.
Jako u předchozích úloh budeme náš projekt tvořit v Tinkercadu.
Schéma zapojení displeje
Když se podíváme na náš sedmisegmentový displej, zjistíme, že má celkem osm pinů. Jejich zapojení je však velice jednoduché. Na sedmisegmentovém displeji se nachází jeden GND pin a sedm pinů pro jednotlivé segmenty displeje. GND připojíme jednoduše k GND pinu u Arduina a to přes 220 [Ω] rezistor. Zbývající piny displeje připojíme k libovolným digitálním pinům Arduina.
Ukažme si finální zapojení displeje:
Zapojení je hotové, můžeme se přesunout k programování.
Naprogramování displeje
Náš první program rozsvítí všechny segmenty displeje a ukáže nám tak číslo osm.
Hlavička bude vypadat následovně:
// Definování pinů našeho displeje #define SEGMENT_A 11 #define SEGMENT_B 12 #define SEGMENT_C 2 #define SEGMENT_D 3 #define SEGMENT_E 4 #define SEGMENT_F 10 #define SEGMENT_G 9
Nejdříve jsme definovali všech sedm pinů.
Nyní piny inicializujeme:
void setup() { // Nastavení pinModu na jednotlivých pinech pinMode(SEGMENT_A, OUTPUT); pinMode(SEGMENT_B, OUTPUT); pinMode(SEGMENT_C, OUTPUT); pinMode(SEGMENT_D, OUTPUT); pinMode(SEGMENT_E, OUTPUT); pinMode(SEGMENT_F, OUTPUT); pinMode(SEGMENT_G, OUTPUT); }
V hlavním cyklu segmenty rozsvítíme. Přidáme si rovnou i sekundovou prodlevu a osmičku necháme přepsat na nulu:
void loop() { // Zapnutí jednotlivých segmentů digitalWrite(SEGMENT_A, HIGH); digitalWrite(SEGMENT_B, HIGH); digitalWrite(SEGMENT_C, HIGH); digitalWrite(SEGMENT_D, HIGH); digitalWrite(SEGMENT_E, HIGH); digitalWrite(SEGMENT_F, HIGH); digitalWrite(SEGMENT_G, HIGH); delay(1000); digitalWrite(SEGMENT_G, LOW); delay(1000); }
Funkce loop()
není také vůbec složitá. Přikážeme
rozsvícení všech segmentů displeje pomocí klíčového slova
digitalWrite()
. Jak můžeme vidět, jedná se vlastně jen o
soustavu LED a pracuje se s nimi dost obdobně i v našem stávajícím kódu.
Kdo z vás uhodl, který segment musíme po prodlevě zhasnout, abychom místo
osmičky zobrazili nulu, pochopil princip segmentového displeje bez
problémů.
Než začneme program testovat, zkontrolujeme, že náš displej je připojen přes katodu, nikoliv anodu, jinak nebude správně fungovat. To platí pouze pro projekt v Tinkercadu. Klikneme na sedmisegmentový displej a v nově otevřeném okně, v nabídce Běžný vybereme požadovanou možnost.
Pokud svítí všechny segmenty, máme úspěšně zprovozněný náš sedmisegmentový displej. Mohli bychom říci, že práce s ním není vůbec složitá, protože nepotřebujeme žádné externí knihovny a stačí nám vlastně obdobné příkazy jako u práce se soustavou LED. V pokročilejších příkladech, nebo kdybychom použili více displejů už jen pro zobrazení dvouciferných čísel, by naše řešení přinášelo velké množství kódu.
Pojďme se tedy vrhnout na náš druhý projekt a ukázat si, jak si s použitím pole ovládání sedmisegmentového displeje zjednodušíme.
Sedmisegmentový displej a pole
Náš první projekt je za námi, můžeme se pustit do něčeho trochu složitějšího. V tomto projektu se naučíme, jak pracovat s jednotlivými segmenty a jak si tuto práci výrazně zjednodušit. Zapojení našeho projektu bude zcela totožné, jako při první úloze, tudíž nemusíme nic přepojovat či předělávat. Podíváme se tedy rovnou na části našeho kódu, který si podrobně popíšeme.
Inicializace segmentů
V našem prvním programu jsme si displej pouze rozsvítili, ale teď si
uděláme trochu složitější program a zároveň si ukážeme efektivnější
práci se samotným displejem. Co tedy bude náš program dělat? Pokusíme se
naprogramovat jednoduché odpočítávání od 0
do 9
.
Nebude to nic složitého, tak si v závěru ještě řekneme, jak zobrazovat
náhodná čísla.
Definování pinů našeho displeje měnit nebudeme, do hlavičky si však přidáme novou proměnnou:
// Definování pinů našeho displeje #define SEGMENT_A 11 #define SEGMENT_B 12 #define SEGMENT_C 2 #define SEGMENT_D 3 #define SEGMENT_E 4 #define SEGMENT_F 10 #define SEGMENT_G 9 // Uložení pinů do pole pro efektivnější práci s hodnotami int segmenty_pole[] = {SEGMENT_A, SEGMENT_B, SEGMENT_C, SEGMENT_D, SEGMENT_E, SEGMENT_F, SEGMENT_G};
Doplnili jsme tedy deklaraci pole typu int
, do které jsme si
uložili hodnoty pinů všech sedmi segmentů.
Díky tomu se nám výrazně zjednoduší již samotná inicializace komponent:
void setup() { // Efektivnější nastavení pinModu for (int i = 0; i < sizeof(segmenty_pole); i++) { pinMode(segmenty_pole[i], OUTPUT); } }
Ve funkci setup()
inicializujeme jednotlivé segmenty pomocí
for
cyklu, který nám umožní nastavit jediným příkazem
pinMode()
všem segmentům roli OUTPUT
.
Všimněme si také definice délky cyklu pomocí klíčového
sizeof()
volaném na našem poli. Kdybychom chtěli nastavit
výstupní roli dalším komponentám, můžeme je tak pouze přidat do pole a
délka cyklu by se automaticky změnám uzpůsobila.
Výpis jednotlivých čísel
Posuňme se dál a ukažme si, jak nejlépe vypisovat jednotlivá čísla.
Abychom nepsali dlouhý kód pro každé číslo zvlášť, sáhneme znovu po
2D poli a for
cyklu. Aby byl kód přehledný, přidáme si do
projektu pomocnou funkci vypsani_cisla()
, kterou v hlavní smyčce
budeme volat:
void vypsani_cisla(int hodnota) // Pomocná funkce pro vypsání čísla { // Vytvoření segmentů pro jednotlivá čísla int data_segmentu[11][7] = { {1,1,1,1,1,1,0}, // Vypsání čísla 0 {0,1,1,0,0,0,0}, // Vypsání čísla 1 {1,1,0,1,1,0,1}, // Vypsání čísla 2 {1,1,1,1,0,0,1}, // Vypsání čísla 3 {0,1,1,0,0,1,1}, // Vypsání čísla 4 {1,0,1,1,0,1,1}, // Vypsání čísla 5 {1,0,1,1,1,1,1}, // Vypsání čísla 6 {1,1,1,0,0,0,0}, // Vypsání čísla 7 {1,1,1,1,1,1,1}, // Vypsání čísla 8 {1,1,1,1,0,1,1}, // Vypsání čísla 9 {0,0,0,0,0,0,0}, // Zhasnutí, voláme indexem 10 }; // Vypsání konkrétního čísla for (int i = 0; i < 7; i++) { digitalWrite(segmenty_pole[i], datasegmentu[hodnota][i]); } }
Nová funkce je typu void
, tudíž nemá žádnou návratovou
hodnotu. Jako vstupní parametr bere proměnnou hodnota
typu
int
, tedy číslo, které chceme vypsat. V dalším 2D poli
data_segmentu[11][7]
si poté uložíme jednotlivé zobrazení
čísel od 0
až po 9
včetně možnosti pro
zhasnutí. Pole pak pomocí for
cyklu projedeme a na základě
vloženého čísla konkrétní číslo vykreslíme.
Hlavní smyčka
Nyní si můžeme doplnit funkci loop()
. Zde voláme funkci,
kterou jsem si výše vytvořili, s tím rozdílem, že se tato funkce nachází
ve for
cyklu. Díky ní tudíž vypíšeme všech deset čísel a
ne pouze jedno číslo, čímž si nasimulujeme již zmiňovaný odpočet:
void loop() { // Cyklus pro procházení naší funkce (simulace odpočtu včetně zhasnutí) for (int i = 0; i <= 10; i++) { // Zavolání funkce pro vypsání pole vypsani_cisla(i); delay(500); } // Sem doplníme zobrazení náhodného čísla }
Odpočítávání máme hotové, pojďme si ještě doplnit slíbené zobrazování náhodných čísel.
Funkce random()
Generování náhodných čísel nám zajistí funkce random()
.
Té můžeme předat pouze jeden parametr, a to maximální hodnotu, která již
do výběru nebude zahrnuta. Pro výběr čísla od 0
do
9
napíšeme tedy random(10)
. Pokud bychom chtěli
třeba čísla od 5
do 10
, volali bychom
random(5, 11)
, tedy variantu se dvěma parametry.
Funkci loop()
tedy doplníme o krátké prodlevy a zobrazení
náhodného čísla. V příkladu vložíme funkci random()
přímo
do naší pomocné funkce:
// Vypsání náhodného čísla 0-9 delay(500); vypsani_cisla(random(10)); delay(1000); }
Tím naše práce se sedmisegmentovým displejem končí. Dvourozměrné pole a pomocná funkce nám umožnila výrazně zjednodušit náš projekt. Další zajímavé příklady na nás čekají v příštích lekcích.
V příští lekci, Arduino - Měření tlaku a teploty s OLED displejem, si vytvoříme Arduino projekt na měření tlaku a teploty pomocí BMP280 modulu s OLED displejem a a napíšeme si k němu obslužný program.