W tym poście chciałbym opisać sposób wygenerowania biblioteki dołączanej do projektu Arduino.
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:
- #ifndef lcd_i2c_lib_h
- #define lcd_i2c_lib_h
- #include "Arduino.h"
- class Display
- {
- public:
- Display(void);
- initialize(void);
- ClearScreen(void);
- DisplayNumberOfTests(uint16_t numberOfTests);
- NumberOfTestsInfor(uint16_t numberOfTests);
- DisplayPause(uint8_t pauseInfo);
- DisplaySettedSwing(uint8_t maxSwing);
- DisplayTxtInScreen(uint8_t posInLine, uint8_t lineOnDisplay, char *txt);
- DisplayRelayInfo(uint8_t pin1, uint8_t pin2);
- SettingsMenu(void);
- DisplayMenuInfo(char *txt, uint16_t valueToDisplay);
- RelayOffMenu(char *txt, uint16_t valueToDisplay);
- RelayTimeMenu(char *txt, uint16_t valueToDisplay);
- SaveSettingMenu(void);
- SettingSavedMenu(void);
- ExitMenuInfo(void);
- private:
- };
- #endif
Biblioteka zawiera głównie funkcję pozwalające na wyświetlenie danych dla wybranej funkcji z menu.
Najpierw należy dołączyć potrzebne biblioteki:
- #include <LiquidCrystal_I2C.h>
- #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:
- LiquidCrystal_I2C lcd_i2c(0x27, 16, 2);
- Display::Display(void) { }
- Display::initialize(void)
- {
- lcd_i2c.init(); // Initialize I2C LCD module
- lcd_i2c.backlight(); // Turn backlight ON
- }
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:
- void LiquidCrystal_I2C::clear(){
- command(LCD_CLEARDISPLAY);// clear display, set cursor position to zero
- delayMicroseconds(2000); // this command takes a long time!
- if (_oled) setCursor(0,0);
- }
Z powodu dosyć długiego czasu wykorzystałem funkcję przesyłającą informacje do wyświetlacza przez wypisanie na nim pustych wierszy:
- Display::ClearScreen(void)
- {
- lcd_i2c.setCursor(0, 0);
- lcd_i2c.print(" ");
- lcd_i2c.setCursor(0, 1);
- lcd_i2c.print(" ");
- }
Poniżej funkcja wyświetlająca czas załączenia przekaźnika:
- Display::RelayTimeMenu(char *txt, uint16_t valueToDisplay)
- {
- lcd_i2c.setCursor(0, 0);
- lcd_i2c.print(txt);
- if(valueToDisplay < 10)
- {
- lcd_i2c.setCursor(0, 1);
- lcd_i2c.print("000");
- lcd_i2c.setCursor(3, 1);
- lcd_i2c.print(valueToDisplay, DEC);
- }
- else if(valueToDisplay < 100)
- {
- lcd_i2c.setCursor(0, 1);
- lcd_i2c.print("00");
- lcd_i2c.setCursor(2, 1);
- lcd_i2c.print(valueToDisplay, DEC);
- }
- else if(valueToDisplay < 1000)
- {
- lcd_i2c.setCursor(0, 1);
- lcd_i2c.print("0");
- lcd_i2c.setCursor(1, 1);
- lcd_i2c.print(valueToDisplay, DEC);
- }
- else
- {
- lcd_i2c.setCursor(0, 1);
- lcd_i2c.print(valueToDisplay, DEC);
- }
- }
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.