IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

17. diel - Tvorba vlastnej Arduino knižnice - OOP v praxi

V minulej lekcii, Arduino a analógový pin , sme si povedali niečo o analógovom pinu a ako ho možno využiť na meranie elektrického odporu a napätia.

V dnešnom Arduino tutoriálu si vyskúšame základy objektovo orientovaného programovania v praxi. Vytvoríme triedu pre blikanie LED diódou. Túto knižnicu potom naimportuje do nášho Arduino IDE, aby sme ju mohli kedykoľvek využiť v nejakom ďalšom projekte. Práve znovupoužívání kódu je jednou z výhod OOP. Začnime ale pekne poporiadku.

Prečo použiť triedu?

Trieda dovoľuje vytvoriť objekt, ktorý sa vyznačuje svojím špecifickým správaním a obsahuje svoje vlastné atribúty. Navyše má aj svoju ojedinelú identitu. Výhodu tohto prístupu si ukážme na nasledujúcom programe.

Blikačka bez triedy

Vytvoríme si funkciu pre blikania so všetkými 3 použiteľnými liadku diódami zapojenými na doske Arduino (RX, TX a L). Nebudeme teda potrebovať žiadne schéma zapojenia ani nepájivé poľa, postačí len doska ľubovoľného Arduino.

Kód programu je nasledujúci:

bool stav;
long prepis;

void Blikej(int pin, int interval) {
  if ((millis() - prepis) > interval) {
    stav = !stav;
    prepis = millis();
  }
  digitalWrite(pin, stav);
}

void setup() {
  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  pinMode(13, OUTPUT);
}

void loop() {
  Blikej(0, 125);
  Blikej(1, 250);
  Blikej(13, 500);
}

Kód využíva funkciu millis(), ktorá sa od funkcie delay() (známu z predchádzajúcich lekcií) líši tým, že sa jedná o čítač milisekúnd od spustenia programu, nie o pauzu.

Program má blikať hneď tromi LED diódami a to každú v inom intervale. Aby mohli byť intervaly úplne rôzne, každá dióda si podľa aktuálneho času a posledného času zmeny stavu zistí, či sa má alebo nemá zmeniť jej stav.

Ako môžete vidieť, diódy na doske sa správajú dosť nestabilne. Ako asi tušíte, problém je v tom, že pre všetky volania tejto funkcie je vždy rovnaká premenná pre prepis long prepis. Takže sú ostatní volaní tejto funkcie takto zdržovaná. Takto by to teda nešlo.

Problém by sme určite mohli vyriešiť aj bez objektov, napr. Vytvoriť premennú pre každú liadku zvlášť alebo dať LED diódy do poľa. My si dnes však ukážeme objektové riešenie.

Blikačka sa triedou

Použitím triedy vytvoríme 3 samostatné objekty pre každú z LED diód, so svojimi vlastnými premennými. Takže budú môcť všetky blikať nezávisle na sebe, svojim vlastným intervalom. A to všetko veľmi pohodlným spôsobom.

Trieda

Najprv si deklarujeme triedu Blikacka, ktorá definuje čo všetko budú budúce blikačky mať.

Trieda je vzor, podľa ktorého potom možno vytvoriť ľubovoľné množstvo objektov, ktorým hovoríme inštancie triedy. Tie budú mať všetky tie isté premenné a funkcie ako definuje trieda, ale každý objekt v nich potom bude mať svoje vlastné hodnoty.

Deklarácia metód a atribútov triedy

Kód triedy bude zatiaľ nasledovné:

class Blikacka {
  public:
    Blikacka(int pin);
    void Blikej(int interval);
    void Neblikej();

  private:
    int pin;
    bool stav = false;
    long prepis;
};

Za zloženým blokom ohraničujúcim triedu sa skutočne píše bodkočiarka!

Triede sme deklarovali niekoľko funkcií a premenných. Tým sa teraz terminologicky správne už hovorí metódy a atribúty, pretože patria daným inštanciám triedy, blikačkám, ktoré podľa triedy ako vzoru vytvoríme.

Prvá metóda, Blikacka(), bez dátového typu je tzv. Konštruktor a zavolá sa automaticky hneď po vytvorení konkrétnej novej blikačky. Asi netreba hovoriť, že potom slúži k inicializácii hodnoty atribútov.

Kód metód triedy

Následne po deklarácii triedy doplníme jednotlivé metódy a konštruktor prostredníctvom kvalifikátora "čtyřtečky" :: (čiže operátorovi príslušnosti).

Pod deklaráciou tejto triedy program pokračuje:

// konstruktor
Blikacka::Blikacka(int pin) {
  if (pin < 0 || pin > 13) pin = 13;
  this->pin = pin;
  pinMode(pin,OUTPUT);
}

// metoda pro blikání
void Blikacka::Blikej(int interval) {
  if (interval<= 0) interval = 250;
  if ((millis() - prepis) > interval) {
    stav = !stav;
    prepis = millis();
  }
  digitalWrite(pin,stav);
}

// metoda pro přerušení blikání
void Blikacka::Neblikej() {
  digitalWrite(pin,LOW);
}

// vytvoření tří instancí
Blikacka X(0);
Blikacka Y(1);
Blikacka Z(13);

void setup() {

}

void loop() {
  X.Blikej(125);
  Y.Blikej(250);
  Z.Blikej(500);
}

Metódy sú doplnené podmienkami pre obmedzenie rozsahu užitých pinov Arduino (0 - 13, uvažujme základnú Arduino Nano či Uno), a intervalu - interval 0 ms a menšie je nezmysel.

Všimnite si výrazu this->pin = pin. Týmto hovoríme programu, že sa jedná o atribút triedy s rovnakým názvom pin (v privátnej časti), ktorému priradíme hodnotu z konstruktoru Blikacka(int pin).

Nahráme program do Arduino.

Knižnica Blikacka

Jednoduchšie časť máme za sebou. Ale ako z toho teda urobiť onú znovupoužiteľný knižnicu? Pre knižnicu budeme musieť kód rozdeliť do dvoch samostatných programov (modulov). Ide o:

  • hlavičkový súbor s príponou .h (header) a
  • súbor so zdrojovým kódom s príponou .cpp.

Header .h

Do hlavičky patrí deklarácia triedy, respektíve len jej "hlavičky".

V Arduino IDE si otvoríme nové okno (alebo záložku, ktorej príponu potom prepíšeme) a uložíme ju ako Blikacka.h. Tento názov i prípona sú veľmi dôležité! Použijeme je záväzne ďalej:

#ifndef BLIKACKA_H
#define BLIKACKA_H

#if(ARDUINO>=100)
#include "Arduino.h"
#else
#include "Wprogram.h"
#endif

class Blikacka {
  public:
    Blikacka(int pin);
    void Blikej(int interval = 250);
    void Neblikej();

  private:
    int pin;
    bool stav=false;
    long prepis;
};
#endif

Ale čo to je? Jednoducho povedané ide o príkazy pre kompilátor (konkrétne preprocesor), ktorému hovoríme, čím sa má zaoberať. Prvá časť:

#ifndef BLIKACKA_H
#define BLIKACKA_H

Je bežná konštrukcia jazyka C ++, ktorá zabráni tomu, aby bola knižnica vložená do projektu viackrát. To sa stať môže, ale skôr u zložitejších programov. K tejto sekvencii patrí ešte úplne na konci direktíva #endif, ktorá celý blok #ifndef uzatvára rovnako, ako zložené zátvorky blok programu.

Nasleduje vnorená druhá časť:

#if(ARDUINO>=100)
#include "Arduino.h"
#else
#include "Wprogram.h"
#endif

Toto je skôr zvyk u zložitejších knižníc, testuje sa verzia Arduino IDE, ak je väčšia alebo rovná verziu 1.0.0. Ak áno, prikazuje kompilátora priložiť header Arduino.h, v opačnom prípade Wprogram.h. Ak túto časť ale vynecháme, bude knižnica tiež funkčné.

Nasleduje už spomenutá deklarácia triedy Blikacka. V metóde Blikej() je v jej parametri použitý int interval = 250. To je tzv. Implicitne nastavená hodnota 250 ms pre prípad, že by sme do metódy zabudli nejakú hodnotu explicitne zadať. Keď teda zátvorky nevyplníme, bude program fungovať ako by sme nastavili interval na 250 ms. V zdrojovom kóde už táto hodnota nemusí byť.

Zdrojový kód

Vytvoríme ďalšie nové okno / záložku, ktorú pomenujeme Blikacka.cpp. Sem patrí zvyšok programu, čím je konštruktor a metódy sa "čtyřtečkami":

#include "Blikacka.h"

Blikacka::Blikacka(int pin) {
  if (pin < 0 || pin > 13) pin = 13;
  this->pin = pin;
  pinMode(pin, OUTPUT); // díky tomuto nepotřebujeme smyčku setup()
}

void Blikacka::Blikej(int interval) {
  if (interval < 0) interval = 250;
  if ((millis() - prepis) > interval) {
    stav = !stav;
    prepis = millis();
  }
  digitalWrite(pin, stav);
}

void Blikacka::Neblikej() {
  digitalWrite(pin, LOW);
}

Teraz už len súbory Blikacka.h a Blikacka.cpp skopírujeme do samostatnej zložky Blikacka/, a tento priečinok umiestnime do zložky: C:\Program Files\Arduino\libraries\.

Tak, a teraz máme knižnicu hotovú. Po nakopírovaniu a reštartovaní Arduino IDE ju už nájdeme v zozname dostupných knižníc:

Importované Knižnica v Arduino IDE - Arduino

Kľúčové slová

Čo by to ale bolo za knižnicu bez svojich vlastných "kľúčových slov"? Kľúčové slová sú slová vyhradená špeciálne pre knižnicu. Po ich správnom napísaní by sa v IDE mala tieto slová zvýrazniť (zmena farby textu), a uistiť nás, že sme metódu / konštantu knižnice napísali správne. V opačnom prípade nás kompilátor na chybu rovnako upozorní. A práve ku zvýrazňovanie slúži súbor KEYWORDS v priečinku s ďalšími súbormi knižnice.

V priečinku so súbormi Blikacka.h a Blikacka.cpp vytvoríme nový textový dokument (klikneme pravým tlačidlom myši -> nový -> Textový dokument) a pomenujeme ho KEYWORDS.txt. Do tohto súboru zadáme vybrané slová, ktoré chceme určiť ako kľúčová, ako demonštruje ukážka nižšie:

Blikacka    KEYWORD1

Blikej      KEYWORD2

Neblikej    KEYWORD2

Namiesto medzery musí byť použitý tabulátor!

Tento krok zafarbia kľúčové slová uvedené v textovom súbore:

  • KEYWORD1 sa postará o tučnú oranžovú farbu konštruktor objektov (Blikacka).
  • KEYWORD2 platí pre metódy, je rovnakej farby, avšak bežným písmom (Blikej, Neblikej).

Príklad v knižnici (Example)

A nech je naša knižnica o niečo viac profesionálne, pridáme iste nejaký prehľadný príklad jej použitia. V priečinku knižnice Blikacka/ vytvoríme podpriečinok s názvom examples/. Sem nahráme ľubovoľný sketch s použitím knižnice, najlepšie s použitím všetkých ich funkcií:

#include<Blikacka.h>

Blikacka LED(13);

void setup() {
// put your setup code here, to run once:
}

void loop() {
  if (millis() < 5000) LED.Blikej(500);
  else LED.Neblikej();
}

Ukážka bude blikať diódou L na pinu 13 po dobu 5 sekúnd, a potom sa blikanie preruší. Tento príklad pomenujeme napríklad Blikacka_exmpl.ino. Zložka s našou knižnicou teda bude teraz obsahovať nasledujúce 4 položky:

lbrlbr - Arduino

Príkladov môže byť ľubovoľné množstvo, každý v priečinku examples/ vo svojej vlastnej podpriečinku. Tento príklad teraz máme k dispozícii v sekcii príklady v prostredí Arduino IDE:

Príklad knižnice - Arduino

Skúška na záver

Teraz máme našu blikacie knižnicu odistené a pripravenú na použitie! Môžeme ju vyskúšať na všetkých použiteľných LED diódach na Arduino doske nasledujúcom kusom kódu:

#include<Blikacka.h>

Blikacka X(0);
Blikacka Y(1);
Blikacka Z(13);

void setup() {
  // put your setup code here, to run once:
}

void loop() {
  X.Blikej(125);
  Y.Blikej(250);
  Z.Blikej(500);
}

Po pripojení ďalších externých LED môžete rozblikať i celej Arduino. Vždy len stačí vytvoriť ďalšiu inštanciu triedy Blikacka. K dispozícii máme všetkých 14 pinov (0 - 13).

Celá knižnica je k dispozícii pod lekcií k stiahnutiu.

V budúcej lekcii, Tvorba vlastnej Arduino knižnice - Dokončenie , si vytvoríme našu plnohodnotnú Arduino knižnicu.


 

Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 81x (568 B)
Aplikácia je vrátane zdrojových kódov

 

Predchádzajúci článok
Arduino a analógový pin
Všetky články v sekcii
Arduino
Preskočiť článok
(neodporúčame)
Tvorba vlastnej Arduino knižnice - Dokončenie
Článok pre vás napísal Vašek Doškář
Avatar
Užívateľské hodnotenie:
2 hlasov
Autor pracuje jako pedagog v oblasti elektroniky, elektrotechniky a programování. Rád tvoří appky všeho druhu. Má přehled v jazycích C#, Java, Kotlin, Javascript, Python a Rust
Aktivity