🚚 Besplatna dostava za narudžbe veće od 35EUR

KAKO NAPISATI VLASTITI ARDUINO LIBRARY

KAKO NAPISATI VLASTITI ARDUINO LIBRARY-Uncategorized

UVOD

U prijašnjoj lekciji upoznali smo se s 7-segmentnim displayima. Između ostalog, naučili smo zašto je library dobra stvar. Na redu je i da napišemo svoj prvi library. Lekciju ćemo podjeliti prema datotekama, fileovima, koje trebamo izraditi da bi biblioteka, library bio funkcionalan i pregledan.

Ono što želimo, i hoćemo napraviti, su funkcije za pisanje brojeva od 0 do 9, funkcija kojom ćemo ugasiti sve segmente na displayu i funkcija koja će paliti/gasiti točku. Krenimo…

HEADER .H

Header file, spremamo ga s ekstenzijom .h, je jedan od dva nužna file za funkcioniranje librarya. S obzirom da Arduino to ne radi sam, ovdje ćemo definirati sve što koristimo u libraryu. Kreiramo klasu, koju kasnije možemo pozvati u Arduino IDEu, sa svim varijablama i funkcijama koje želimo da budu dostupne korisniku librarya (public) i onim internima koje ćemo koristiti kako bi library bio funkcionalan (private.

Što je klasa?

Ako se do sada niste susreli s pojmom klasa, ona je zapravo skup svih funkcija i varijabli za određeni objekt. Npr. gledajmo na muškarca kao na objekt. Svaki muškarac ima, ili nema, određene karakteristike kao što su IQ, visina, masa ili brkovi. Gledano iz očiju programera IQ je cijelobrojna varijabla int, visina i masa mogu biti float, a brkove imaš ili nemaš pa je logično boolean.

No dobro, vratimo se na izradu librarya. Otvorimo najdraži tekst editor i krenimo:

// kreiramo klasu koju ćemo pozivati u Arduino IDE
class Segment
{
// funkcije koje koristi korisnik librarya
public:
// ovdje cemo postaviti konekciju Dasduina i displaya
Segment(uint8_t pin1, uint8_t pin2, uint8_t pin3, uint8_t pin4, uint8_t pin5, uint8_t pin6, uint8_t pin7, uint8_t pin8);
void Broj(int n);  // funkcija “broj” imati će jedan parametar, broj “n” koji zelimo prikazati
void Tocka();  // funkcija “tocka” ce paliti/gasiti tocku
void Ocisti();  // funkcija ocisti gasi preostale segmente
// interne varijable
private:
uint8_t _pin1;
uint8_t _pin2;
uint8_t _pin3;
uint8_t _pin4;
uint8_t _pin5;
uint8_t _pin6;
uint8_t _pin7;
uint8_t _pin8;
bool b;
};

Bez brige ako nešto nije jasno, glavni dio nalazi se u source fileu kojeg ćemo obraditi za tren. Osim navedenog, Header file mora imati još neke dijelove. Svakako je potrebno implementirati Arduino.h, koji se automatski dodaje pri kompajlanju koda, ali ne i u pisanju librarya.

#include “Arduino.h”

Ovaj dio uvelike ovisi o verziji Arduino IDEa kojeg krisnik ima instaliran. Tako da ovom djelu treba posvetiti puno više pažnje, međutim za sada će ovo biti dovoljno.

Običaj je u Header file dodati i mali dio koda koji provjerava da je library samo jednom dodan u sketch. On izgleda ovako:

#ifndef Segment_h
#define Segment_h
 // dio za kod
#endif

Konačno naš Header izgleda ovako:

/*
    Segment.h - Library for 7 segment display common cathode
    Created by e-radionica.com, 2016.
    */
    #ifndef Segment_h
    #define Segment_h
 #include "Arduino.h"
    class Segment
    {
        public:
            Segment(uint8_t pin1, uint8_t pin2, uint8_t pin3, uint8_t pin4, uint8_t pin5, uint8_t pin6, uint8_t pin7, uint8_t pin8);
            void broj(int n);
            void tocka();
            void ocisti();
        private:
            uint8_t _pin1;
            uint8_t _pin2;
            uint8_t _pin3;
            uint8_t _pin4;
            uint8_t _pin5;
            uint8_t _pin6;
            uint8_t _pin7;
            uint8_t _pin8;
            bool b;
    };
#endif

Sada ga sam trebamo spremiti. Napravimo novi folder u, za Windows OSDocuments – Arduino – Libraries i nazovimo ga Segment ili po želji. Detaljnije o Arduino library-ma ovdje. Važno je da su svi znakovi u imenu prema ASCII standardu. Spremimo napisani kod u kreirani folder i dodajmo mu ekstenziju .h, tako da ime izgleda, npr. Segment.h. Pripazite da naziv nema nikakvu drugu ekstenziju osim .h, kao .txt ili slično.

SOURCE .CPP

Source file je dio gdje se nalazi sav naš kod/logika, a pišemo ga u C++ jeziku. Iako smo već objasnili logiku koju želimo napisati, slobodno škicnite na 7 segmentni display tutorial i podsjetimo se kako radi.

Za početak moramo includati Arduino.h i Segment.h koji smo kreirali upravo. Ponovno, naravno, pišemo u tekst editoru.

#include "Arduino.h"
"include "Segment.h"

Odlično. Vrijeme je da napišemo logiku za konstruktore kreirane u Headeru.

//KLASA  ::konstruktor (parametri)
  Segment::Segment(uint8_t pin1, uint8_t pin2, uint8_t pin3, uint8_t pin4, uint8_t pin5, uint8_t pin6, uint8_t pin7, uint8_t pin8)
  {
    pinMode(pin1, OUTPUT);
    pinMode(pin2, OUTPUT);
    pinMode(pin3, OUTPUT);
    pinMode(pin4, OUTPUT);
    pinMode(pin5, OUTPUT);
    pinMode(pin6, OUTPUT);
    pinMode(pin7, OUTPUT);
    pinMode(pin8, OUTPUT);
    //
    _pin1 = pin1;
    _pin2 = pin2;
    _pin3 = pin3;
    _pin4 = pin4;
    _pin5 = pin5;
    _pin6 = pin6;
    _pin7 = pin7;
    _pin8 = pin8;
    //
    b = false;
  }

Prvi konstruktor “Segment” klase je Segment. Njega koristimo da definiramo na kojim pinovima Dasduina su spojene nožice 7 segmentno displaya. Ako display spojimo na isti način kao u 7 segmentni display tutorialu, ovaj konstruktor u Arduino IDE pozvati ćemo ovako:

/*
Konstruktor proizvoljno ime      pinovi displaya
                            (pin1, pin2, ...         )
                                 pinovi Croduina
---------------------------------------------------- */
Segment         segment     (  2,    3,   4,5,6,7,8,9);

_pin definiramo je želimo odvojiti privatne varijable, od onih koje korisnik librarya koristi. Dakle, ako korisnik napravi neke promjene na public varijabli to neće utjecati na funkcioniranje librarya.

b = false; koristimo kako bi upalili, odnosno ugasili točku na displayu. Njegov konstruktor izgledati će ovako:

void Segment::tocka()
{
    b = !b; // spremi zamjenjenu vrijednost
    digitalWrite(_pin8, b);  // to ce upaliti tocku ako je ugasena i obratno
}

Ostao nam je još konstruktor broj. On će za paramater uzeti cijeli broj između 0 i 9 i zapisati ga na displayu. To izgleda ovako:

void Segment::broj(int n)
{
  switch(n)
  {
    case 0:
    digitalWrite(_pin1, 0);
    digitalWrite(_pin2, 1);
    digitalWrite(_pin3, 1);
    digitalWrite(_pin4, 1);
    digitalWrite(_pin5, 1);
    digitalWrite(_pin6, 1);
    digitalWrite(_pin7, 1);
    digitalWrite(_pin8, 0);
    break;
//... i td. pišemo za svaki pojedinacni broj
   }
}

U Arduino IDE pozivamo ga na sljedeći način:

// palimo broj 0
segment.broj(0);
segment je objekt koji smo stvorili pomoci Segment konstruktora par redova izna
broj je konstruktor kojeg smo upravo kreirali
0 je broj koji želimo prikazati na ekranuKada ispišemo sve, .cpp file nam izgleda ovako:
/*
    Segment.cpp - Library for 7 segment display common cathode
    Created by e-radionica.com, 2016.
    */
#include "Arduino.h"
#include "Segment.h"
Segment::Segment(uint8_t pin1, uint8_t pin2, uint8_t pin3, uint8_t pin4, uint8_t pin5, uint8_t pin6, uint8_t pin7, uint8_t pin8)
{
    pinMode(pin1, OUTPUT);
    pinMode(pin2, OUTPUT);
    pinMode(pin3, OUTPUT);
    pinMode(pin4, OUTPUT);
    pinMode(pin5, OUTPUT);
    pinMode(pin6, OUTPUT);
    pinMode(pin7, OUTPUT);
    pinMode(pin8, OUTPUT);
    //
    _pin1 = pin1;
    _pin2 = pin2;
    _pin3 = pin3;
    _pin4 = pin4;
    _pin5 = pin5;
    _pin6 = pin6;
    _pin7 = pin7;
    _pin8 = pin8;
    //
    b = false;
}
void Segment::broj(int n)
{
switch(n)
{
case 0:
    digitalWrite(_pin1, 0);
    digitalWrite(_pin2, 1);
    digitalWrite(_pin3, 1);
    digitalWrite(_pin4, 1);
    digitalWrite(_pin5, 1);
    digitalWrite(_pin6, 1);
    digitalWrite(_pin7, 1);
    digitalWrite(_pin8, 0);
    break;
case 1:
    digitalWrite(_pin1, 0);
    digitalWrite(_pin2, 0);
    digitalWrite(_pin3, 0);
    digitalWrite(_pin4, 1);
    digitalWrite(_pin5, 0);
    digitalWrite(_pin6, 0);
    digitalWrite(_pin7, 1);
    digitalWrite(_pin8, 0);
    break;
case 2:
    digitalWrite(_pin1, 1);
    digitalWrite(_pin2, 0);
    digitalWrite(_pin3, 1);
    digitalWrite(_pin4, 1);
    digitalWrite(_pin5, 1);
    digitalWrite(_pin6, 1);
    digitalWrite(_pin7, 0);
    digitalWrite(_pin8, 0);
    break;
case 3:
    digitalWrite(_pin1, 1);
    digitalWrite(_pin2, 0);
    digitalWrite(_pin3, 1);
    digitalWrite(_pin4, 1);
    digitalWrite(_pin5, 0);
    digitalWrite(_pin6, 1);
    digitalWrite(_pin7, 1);
    digitalWrite(_pin8, 0);
    break;
case 4:
    digitalWrite(_pin1, 1);
    digitalWrite(_pin2, 1);
    digitalWrite(_pin3, 0);
    digitalWrite(_pin4, 1);
    digitalWrite(_pin5, 0);
    digitalWrite(_pin6, 0);
    digitalWrite(_pin7, 1);
    digitalWrite(_pin8, 0);
    break;
case 5:
    digitalWrite(_pin1, 1);
    digitalWrite(_pin2, 1);
    digitalWrite(_pin3, 1);
    digitalWrite(_pin4, 0);
    digitalWrite(_pin5, 0);
    digitalWrite(_pin6, 1);
    digitalWrite(_pin7, 1);
    digitalWrite(_pin8, 0);
    break;
case 6:
    digitalWrite(_pin1, 1);
    digitalWrite(_pin2, 1);
    digitalWrite(_pin3, 1);
    digitalWrite(_pin4, 0);
    digitalWrite(_pin5, 1);
    digitalWrite(_pin6, 1);
    digitalWrite(_pin7, 1);
    digitalWrite(_pin8, 0);
    break;
case 7:
    digitalWrite(_pin1, 0);
    digitalWrite(_pin2, 0);
    digitalWrite(_pin3, 1);
    digitalWrite(_pin4, 1);
    digitalWrite(_pin5, 0);
    digitalWrite(_pin6, 0);
    digitalWrite(_pin7, 1);
    digitalWrite(_pin8, 0);
    break;
case 8:
    digitalWrite(_pin1, 1);
    digitalWrite(_pin2, 1);
    digitalWrite(_pin3, 1);
    digitalWrite(_pin4, 1);
    digitalWrite(_pin5, 1);
    digitalWrite(_pin6, 1);
    digitalWrite(_pin7, 1);
    digitalWrite(_pin8, 0);
    break;
case 9:
    digitalWrite(_pin1, 1);
    digitalWrite(_pin2, 1);
    digitalWrite(_pin3, 1);
    digitalWrite(_pin4, 1);
    digitalWrite(_pin5, 0);
    digitalWrite(_pin6, 1);
    digitalWrite(_pin7, 1);
    digitalWrite(_pin8, 0);
    break;
}
}
void Segment::tocka()
{
    b = !b;
    digitalWrite(_pin8, b);
}
void Segment::ocisti()
{
    digitalWrite(_pin1, 0);
    digitalWrite(_pin2, 0);
    digitalWrite(_pin3, 0);
    digitalWrite(_pin4, 0);
    digitalWrite(_pin5, 0);
    digitalWrite(_pin6, 0);
    digitalWrite(_pin7, 0);
    digitalWrite(_pin8, 0);
}

Preostaje samo spremiti file na isti način kao i Header. Spremammo ga u isti kreirani folder, ovaj puta s .cpp ekstenzijom.

KEYWORDS

Keywords je .txt file koji omogućuje Arduino IDE da prepozna ključne riječi iz našeg librarya i promjeni im boju u editoru kao bi kod bio pregledniji. Izgledao bi otprilike ovako:

Segment KEYWORD1
broj    KEYWORD2
ocisti  KEYWORD2
tocka   KEYWORD2

Spremamo ga u isti folder kao predhodna dva file s ekstenzijom .txt .

ARDUINO IDE I PRIMJER KODA

Ako želimo da se primjer korištenja libraya pojavi u Arduino IDE File-Examples trebamo kreirati subfolder s nazivom examples. Ovako to izgleda u Windows OS:

U subfolder examples spremiti ćemo primjer korištenja ovog librarya. Možemo ga pisati u Arduino IDE softwareu, a za primjer ćemo napisati odbrojavanje displaya.

//dodajemo kreiranu biblioteku
#include "Segment.h"
//definiramo pinove Croduina prema tutorialu
Segment segment(2,3,4,5,6,7,8,9);
void setup() {
}
void loop() {
  // odbrojavamo u loop-u
  for(int i=9; i>=0; i--)
  {
    segment.broj(i); // pozivaj brojeve od 9 do 0
    delay(1000);     // zaustavi 1 sekundu
  }
  // za kraj zablicaj par puta
  for(int j=0; j<3; j++)
  {
    segment.ocisti();
    segment.tocka();
    delay(500);
    segment.broj(0);
    segment.tocka();
    delay(500);
  }
}

Spremimo ovaj kod u examples folder. Nakon toga nužno je zatvoriti i ponovno otvoriti Arduino IDE kako bi mogli koristiti library.

Nadamo se da nismo previše zakomplicirali ovaj relativno jednostavan postupak izrade vlastitog Arduino librarya. Ako imate poteškoća ili nadogradnji na ovaj tutorial, veselimo se vašem komentaru.