niedziela, 28 kwietnia 2019

[36] Arduino - Wyświetlacz sterowany przez UART M7

W tym poście chciałbym opisać bibliotekę odpowiedzialną za sterowanie wyświetlaczem obsługiwanym komendami UART.

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

Opis


Biblioteka składa się z dwóch plików m7_displ.cpp oraz m7_displ.h.

Na samym początku definiujemy rodzaj kolorów jaki będzie dostępny dla wyświetlacza. Należy pamiętać, że wyświetlacz posiada kolory w skali RGB565.

  1. enum class M7Color:uint16_t
  2. {
  3.   COLOR_BLACK = 0x0000,
  4.   COLOR_BLUE = 0x001F,
  5.   COLOR_AQUA = 0x07FF,
  6.   COLOR_FUCHSIA = 0xF81F,
  7.   COLOR_GREEN   = 0x0400,
  8.   COLOR_GREY = 0x8410,
  9.   COLOR_LIME = 0x07E0,
  10.   COLOR_MAROON = 0x8000,
  11.   COLOR_NAVY = 0x0010,
  12.   COLOR_OLIVE   = 0x8400,
  13.   COLOR_PURPLE = 0xC00F,
  14.   COLOR_RED = 0x9800,
  15.   COLOR_SILVER = 0xC618,
  16.   COLOR_TEAL = 0x0410,
  17.   COLOR_YELLOW = 0xFF40,
  18.   COLOR_WHITE = 0xFFFF,
  19.   COLOR_ORANGE = 0xFBE0
  20. };

Teraz przejdę przez dostępne funkcję zdefiniowane w bibliotece.

Czyszczenie wyświetlacza zadanym kolorem z klasy enum lub dowolnym z zakresu.

  1. void M7Display::ClearScreen(HardwareSerial &refSer, M7Color bgColor) {
  2.   char bufferOut[16];
  3.   sprintf(bufferOut, "CLS %d\n\r", bgColor);
  4.   refSer.println(bufferOut);
  5. }
  6. M7WrongCommandParameters M7Display::ClearScreen(HardwareSerial &refSer, uint16_t bgColor) {
  7.   if(bgColor > 65535) {
  8.     return M7WrongCommandParameters::TooBigColorValue;
  9.   }
  10.     char bufferOut[16];
  11.     sprintf(bufferOut, "CLS %u\n\r", bgColor);
  12.   refSer.print(bufferOut);
  13.   return M7WrongCommandParameters::StatOK;
  14. }

Większość funkcji została przygotowana tak aby była możliwość obsługi z kolorem zdefiniowanym w enum lub bezpośrednio wprowadzonym jako wartość 16 bitowa.

Poniżej funkcja przesyłająca ciąg znaków który zostanie wyświetlony na ekranie z zdefiniowanym kolorem tła:

  1. M7WrongCommandParameters M7Display::PrintStringWithBg( HardwareSerial &refSer,
  2.                         const char * str, uint16_t len,
  3.                         M7FontSize fontSize,
  4.                             uint16_t posX, uint16_t posY,
  5.                         M7Color textColor, M7Color bgColor) {
  6.   if(CheckCoordinates(posX, posY)) {
  7.     return M7WrongCommandParameters::WrongPosition;
  8.   }
  9.   if(len > 100) {
  10.     return M7WrongCommandParameters::TooSmallBuffer;
  11.   }
  12.   char text[len + 1];
  13.   memset(text, 0, sizeof text);
  14.   memcpy(text, str, len);
  15.   char bufferOut[128];
  16.   memset(bufferOut, 0, sizeof bufferOut);
  17.   sprintf(bufferOut, "HZB%u %u %u %u %u %s\n\r", (uint16_t)fontSize, posX, posY, textColor, bgColor, text);
  18.   refSer.print(bufferOut);
  19.   return M7WrongCommandParameters::StatOK;
  20. }

Wypisanie tekstu transparentnego wykonywane jest za pomocą następującej funkcji:

  1. M7WrongCommandParameters M7Display::PrintStringTrans(HardwareSerial &refSer, const char * str, uint8_t len,
  2.                     M7FontSize fontSize, uint16_t posX, uint16_t posY, M7Color textColor)
  3. {
  4.   if(CheckCoordinates(posX, posY)) {
  5.     return M7WrongCommandParameters::WrongPosition;
  6.   }
  7.   char text[len + 1];
  8.   memset(text, 0, sizeof text);
  9.   memcpy(text, str, len);
  10.     char bufferOut[128];
  11.     sprintf(bufferOut, "HZ%u %u %u %u %s\n\r", (uint16_t)fontSize, posX, posY, textColor, text);
  12.     refSer.print(bufferOut);
  13.   return M7WrongCommandParameters::StatOK;
  14. }

Wypisanie tekstu domyślną czcionką:

  1. M7WrongCommandParameters M7Display::PrintString(HardwareSerial &refSer, const char * str, uint8_t len, uint16_t posX, uint16_t posY, M7Color textColor) {
  2.   if(len > 100) {
  3.     return M7WrongCommandParameters::TooSmallBuffer;
  4.   }
  5.   char text[len + 1];
  6.   memset(text, 0, sizeof text);
  7.   memcpy(text, str, len);
  8.   char bufferOut[128];
  9.   memset(bufferOut, 0, sizeof bufferOut);
  10.   sprintf(bufferOut, "STR %u %u %u %s\n\r", posX, posY, textColor, text);
  11.   refSer.print(bufferOut);
  12.   return M7WrongCommandParameters::StatOK;
  13. }

Dla powyższego rozkazu należy pamiętać, że tekst/grafika znajdująca się pod tekstem nie zostanie wymazana. Nowy tekst pojawi na na wcześniejszych informacjach. Co pozwali na wprowadzanie tekstu np. na obrazku, natomiast problem się pojawi przy konieczności częstszego edytowania tekstu należy także odświeżać tło.

Teraz opiszę funkcje rysujące.

Rysowanie koła bez wypełnienia:

  1. M7WrongCommandParameters M7Display::DrawCircle(HardwareSerial &refSer, uint16_t posX, uint16_t posY, uint16_t radius, M7Color color)
  2. {
  3.   if(CheckCoordinates(posX, posY)) {
  4.     return M7WrongCommandParameters::WrongPosition;
  5.   }
  6.   char bufferOut[20];
  7.   sprintf(bufferOut, "CIRCLE %u %u %u %u\n\r", posX, posY, radius, color);
  8.   refSer.print(bufferOut);
  9.   return M7WrongCommandParameters::StatOK;
  10. }

Rysowanie prostokąta z wypełnieniem:

  1. M7WrongCommandParameters M7Display::FillInColor(HardwareSerial &refSer, uint16_t posXStart, uint16_t posYStart,
  2.                                 uint16_t posXEnd, uint16_t posYEnd, M7Color color)
  3. {
  4.   if(CheckCoordinates(posXStart, posYStart)) {
  5.     return M7WrongCommandParameters::WrongPosition;
  6.   }
  7.   char bufferOut[20];
  8.   sprintf(bufferOut, "CLR %u %u %u %u %u\n\r", posXStart, posYStart, posXEnd, posYEnd, color);
  9.   refSer.print(bufferOut);
  10.   return M7WrongCommandParameters::StatOK;
  11. }

Rysowanie kropki:

  1. M7WrongCommandParameters M7Display::DrawADot(HardwareSerial &refSer, uint16_t posX, uint16_t posY, M7Color color)
  2. {
  3.   if(CheckCoordinates(posX, posY)) {
  4.     return M7WrongCommandParameters::WrongPosition;
  5.   }
  6.   char bufferOut[20];
  7.   sprintf(bufferOut, "DOT %u %u %u\n\r", posX, posY, color);
  8.   refSer.print(bufferOut);
  9.   return M7WrongCommandParameters::StatOK;
  10. }

Rysowanie linii:

  1. M7WrongCommandParameters M7Display::DrawALine(HardwareSerial &refSer, uint16_t posXStart, uint16_t posYStart,uint16_t posXEnd, uint16_tposYEnd, M7Color color) {
  2.   if(CheckCoordinates(posYStart, posYStart)) {
  3.     return M7WrongCommandParameters::WrongPosition;
  4.   }
  5.   char bufferOut[20];
  6.   sprintf(bufferOut, "LINE %u %u %u %u %u\n\r", posXStart, posYStart, posXEnd, posYEnd, color);
  7.   refSer.print(bufferOut);
  8.   return M7WrongCommandParameters::StatOK;
  9. }

Rysowanie prostokąta bez wypełnienia:

  1. M7WrongCommandParameters M7Display::DrawRectangle(HardwareSerial &refSer, uint16_t posXStart, uint16_t posYStart,uint16_t posXEnd, uint16_tposYEnd, M7Color color) {
  2.   if(CheckCoordinates(posXStart, posYStart)) {
  3.     return M7WrongCommandParameters::WrongPosition;
  4.   }
  5.   char bufferOut[20];
  6.   sprintf(bufferOut, "RECT %u %u %u %u %u\n\r", posXStart, posYStart, posXEnd, posYEnd, color);
  7.   refSer.print(bufferOut);
  8.   return M7WrongCommandParameters::StatOK;
  9. }

Wyświetlenie obrazka z podanej lokalizacji:

  1. M7WrongCommandParameters M7Display::DisplayImageFromPath(HardwareSerial &refSer, uint16_t posXStart, uint16_t posYStart, const char * str,uint8_t len){    
  2.   if(CheckCoordinates(posXStart, posYStart)) {
  3.     return M7WrongCommandParameters::WrongPosition;
  4.   }
  5.   if(len > 100) {
  6.     return M7WrongCommandParameters::TooSmallBuffer;
  7.   }
  8.   char text[len + 1];
  9.   memset(text, 0, sizeof text);
  10.   memcpy(text, str, len);
  11.   char bufferOut[128];
  12.   memset(bufferOut, 0, sizeof bufferOut);
  13.   sprintf(bufferOut, "LOAD %u %u %s\n\r", posXStart, posYStart, text);
  14.   refSer.print(bufferOut);
  15.   return M7WrongCommandParameters::StatOK;
  16. }

Wyświetlacz pozwala na obsługę takich formatów jak BMP, JPG, TGA, PNG.

Funkcja odpowiedzialna za wyświetlenie obrazka na podstawie jego numeru:

  1. M7WrongCommandParameters M7Display::DisplayImageBaseOnID(HardwareSerial &refSer, uint8_t picNumber, uint16_t posX, uint16_t posY)
  2. {
  3.   if(CheckCoordinates(posX, posY)) {
  4.     return M7WrongCommandParameters::WrongPosition;
  5.   }
  6.   char bufferOut[30];
  7.   memset(bufferOut, 0, sizeof bufferOut);
  8.   sprintf(bufferOut, "PIC %u %u %u\n\r", picNumber, posX, posY);
  9.   return M7WrongCommandParameters::StatOK;
  10. }

Wyświetlenie animacji:

  1. M7WrongCommandParameters M7Display::DisplayAnimation(HardwareSerial &refSer, uint8_t animationNumber,
  2.                   uint8_t onOffState, uint16_t posXStart, uint16_t posYStart,
  3.                   uint16_t animationStartPictureNumber, uint16_t endAnimationPictureNumber, uint16_t spacingTimeMs)
  4. {
  5.   if(CheckCoordinates(posXStart, posYStart)) {
  6.     return M7WrongCommandParameters::WrongPosition;
  7.   }
  8.   else if(animationNumber < 1 || animationNumber > 5) {
  9.     return M7WrongCommandParameters::WrongParameters;
  10.   }
  11.   else if(onOffState > 1){
  12.     return M7WrongCommandParameters::WrongParameters;
  13.   }
  14.   char bufferOut[128];
  15.   memset(bufferOut, 0, sizeof bufferOut);
  16.   sprintf(bufferOut, "M%u %u %u %u %u %u %u\n\r", animationNumber, onOffState, posXStart, posYStart,
  17.                         animationStartPictureNumber, endAnimationPictureNumber, spacingTimeMs);
  18.   refSer.print(bufferOut);
  19.   return M7WrongCommandParameters::StatOK;
  20. }

Wycięcie obrazka i wyświetlenie go o zadanej wielkości:

  1. M7WrongCommandParameters M7Display::CutPicture(HardwareSerial &refSeruint8_t picNumber, uint16_t posXStart, uint16_t posYStart, uint16_t posXEnd, uint16_t posYEnd, uint16_t xImageSize, uint16_t yImageSize)
  2. {
  3.   if(CheckCoordinates(posXStart, posYStart)) {
  4.     return M7WrongCommandParameters::WrongPosition;
  5.   }
  6.   char bufferOut[30];
  7.   memset(bufferOut, 0, sizeof bufferOut);
  8.   sprintf(bufferOut, "CUT %u %u %u %u %u %u %u\n\r", picNumber, posXStart, posYStart,
  9.                                                 posXEnd, posYEnd, xImageSize, yImageSize);
  10.   return M7WrongCommandParameters::StatOK;
  11. }

Uruchomienie Buzzera:

  1. void M7Display::BuzzerControl(HardwareSerial &refSer, uint16_t Tb, uint16_t Fb) {
  2.   char bufferOut[20];
  3.   sprintf(bufferOut, "BUZ %u %u\n\r", Tb, Fb);
  4.   refSer.print(bufferOut);
  5. }

Załączenie bądź wyłączenie podświetlania ekranu:

  1. void M7Display::BacklightOn(HardwareSerial &refSer)
  2. {
  3.   char bufferOut[10] = "LEDON\n\r";
  4.   refSer.print(bufferOut);
  5. }
  6. void M7Display::BacklightOff(HardwareSerial &refSer)
  7. {
  8.   char bufferOut[10] = "LEDOFF\n\r";
  9.   refSer.print(bufferOut);
  10. }

Kolejnym elementem biblioteki jest funkcja pobierająca dane z touchpada umieszczonego na wyświetlaczu.

Przycisk definiowany jest po stworzeniu struktury zawierającej informacje o statusie przycisku, pozycji akceptacji dla kliknięcia oraz funkcji obsługującej uruchomienie przycisku.

Funkcje obsługujące pozwalają na zdekodowanie ramki danych oraz sprawdzenie czy dany przycisk został wywołany.

Biblioteki można pobrać z dysku Google pod tym linkiem.