niedziela, 2 maja 2021

[40] Arduino - Tworzenie biblioteki do projektu

W tym poście chciałbym opisać sposób wygenerowania biblioteki dołączanej do projektu Arduino. 

[Źródło: https://store.arduino.cc/usa/arduino-uno-rev3]

Pozwoli na przeniesienie funkcji odpowiedzialnych za określone zadanie do osobnej klasy. Co wpłynie na zwiększenie czytelności kodu umieszczonego w głównym pliku projektu Arduino.

Poniższy przykład będzie dotyczył obsługi wyświetlacza 2x16 ze sterownikiem I2C, obsługiwanego z biblioteki LiquidCrystal_I2C.

Funkcje będą odpowiadały za wyświetlanie prostego menu na wyświetlaczu.

Do folderu z projektem należy dodać dwa pliki *.cpp oraz *.h.

W pliku *.h umieszczamy deklarację klasy wraz z funkcjami oraz zmiennymi. Plik *.cpp zawiera definicję klasy.

Poniżej opis pliku .h zawierający opis funkcji:

  1. #ifndef lcd_i2c_lib_h
  2. #define lcd_i2c_lib_h
  3.  
  4. #include "Arduino.h"
  5.  
  6. class Display
  7. {
  8.   public:
  9.     Display(void);
  10.     initialize(void);
  11.     ClearScreen(void);
  12.     DisplayNumberOfTests(uint16_t numberOfTests);
  13.     NumberOfTestsInfor(uint16_t numberOfTests);
  14.     DisplayPause(uint8_t pauseInfo);
  15.     DisplaySettedSwing(uint8_t maxSwing);
  16.     DisplayTxtInScreen(uint8_t posInLine, uint8_t lineOnDisplay, char *txt);
  17.     DisplayRelayInfo(uint8_t pin1, uint8_t pin2);
  18.     SettingsMenu(void);
  19.    
  20.     DisplayMenuInfo(char *txt, uint16_t valueToDisplay);
  21.     RelayOffMenu(char *txt, uint16_t valueToDisplay);
  22.     RelayTimeMenu(char *txt, uint16_t valueToDisplay);
  23.     SaveSettingMenu(void);
  24.     SettingSavedMenu(void);
  25.     ExitMenuInfo(void);
  26.   private:
  27. };
  28.  
  29. #endif

Biblioteka zawiera głównie funkcję pozwalające na wyświetlenie danych dla wybranej funkcji z menu.

Najpierw należy dołączyć potrzebne biblioteki:

  1. #include <LiquidCrystal_I2C.h>
  2. #include "lcd_i2c_lib.h"

Kolejnym krokiem jest stworzenie obiektu klasy LiquidCrystal wraz z podstawowym konstruktorem. Następnie dodaje funkcję wykonującą podstawowe uruchomienie wyświetlacza:

  1. LiquidCrystal_I2C lcd_i2c(0x27, 16, 2);
  2.  
  3. Display::Display(void) { }
  4.  
  5. Display::initialize(void)
  6. {
  7.   lcd_i2c.init();       // Initialize I2C LCD module
  8.   lcd_i2c.backlight();  // Turn backlight ON
  9. }

W celu wyczyszczenia ekranu korzystam z prostej przygotowanej funkcji. Głównie dlatego, że procedura czyszczenia ekranu zajmuje sporo czasu. Pobrane z biblioteki udostępnionej w serwisie Github:

  1. void LiquidCrystal_I2C::clear(){
  2.     command(LCD_CLEARDISPLAY);// clear display, set cursor position to zero
  3.     delayMicroseconds(2000);  // this command takes a long time!
  4.   if (_oled) setCursor(0,0);
  5. }

Z powodu dosyć długiego czasu wykorzystałem funkcję przesyłającą informacje do wyświetlacza przez wypisanie na nim pustych wierszy:

  1. Display::ClearScreen(void)
  2. {
  3.   lcd_i2c.setCursor(0, 0);
  4.   lcd_i2c.print("                ");
  5.   lcd_i2c.setCursor(0, 1);
  6.   lcd_i2c.print("                ");
  7. }

Poniżej funkcja wyświetlająca czas załączenia przekaźnika:

  1. Display::RelayTimeMenu(char *txt, uint16_t valueToDisplay)
  2. {
  3.   lcd_i2c.setCursor(0, 0);
  4.   lcd_i2c.print(txt);
  5.  
  6.   if(valueToDisplay < 10)
  7.   {
  8.     lcd_i2c.setCursor(0, 1);
  9.     lcd_i2c.print("000");
  10.     lcd_i2c.setCursor(3, 1);
  11.     lcd_i2c.print(valueToDisplay, DEC);
  12.   }
  13.   else if(valueToDisplay < 100)
  14.   {
  15.     lcd_i2c.setCursor(0, 1);
  16.     lcd_i2c.print("00");
  17.     lcd_i2c.setCursor(2, 1);
  18.     lcd_i2c.print(valueToDisplay, DEC);
  19.   }
  20.   else if(valueToDisplay < 1000)
  21.   {
  22.     lcd_i2c.setCursor(0, 1);
  23.     lcd_i2c.print("0");
  24.     lcd_i2c.setCursor(1, 1);
  25.     lcd_i2c.print(valueToDisplay, DEC);
  26.   }
  27.   else
  28.   {
  29.    lcd_i2c.setCursor(0, 1);
  30.    lcd_i2c.print(valueToDisplay, DEC);
  31.   }
  32. }

Powyższą funkcję można w razie potrzebny trochę uprościć przez przeniesienie ustawienia kursora i wypisywania tekstu do osobnej funkcji. 

Pozostałe funkcje umieszczone w bibliotece służą do wyświetlania zmiennej w wybranym menu na ekranie.