2015-06-28

EVShield筆記(2):UI Module使用者介面擴展板程式摘要

EVShield 雖然可以透過 Arduino IDE 的 Serial Console來顯示訊息或輸入資料,不過必須是與電腦連線的狀態,而 mindsensors 則推出了一個 UI Module For EVShield or Arduino 擴展板,具備 320x240 解析度的 2.2" 彩色 TFT 螢幕 以及 一個五向搖桿,提供更方便與彈性的使用介面。




UI Module Arduino程式庫

UI Module本身是Arduino擴展版,並不需要與 EVShield搭配才能使用。
其中TFT LED 是 SPI介面的 Adafruit ILI9340,五向搖桿則是使用 Arduino的 A1(Up)、A2(Down)、A0(Right)、A3(Left)、D2(Center) 五個Digital pins。

在mindsensors官網中共提供了三個下載的Arduino程式庫:

  • Adafruit_GFX這是 Adafruit 原廠 LCD/OLED 顯示器的通用繪圖及文字顯示功能程式庫,須搭配特定顯示器的程式庫一起使用,如:Adafruit ILI9340。
    詳細使用方式可以參考手冊
    : "Adafruit GFX Graphics Library"。

  • EVs_UIModule這是 mindsensors 提供的 UI Module程式庫,除繼承前面兩個程式庫的顯示控制功能之外,另定義讀取五向搖桿狀態以及簡化的螢幕控制與文字功能。
在Arduino sketch中需要按照以下順序 include程式庫,才能夠使用定義的功能:

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9340.h>
#include <EVs_UIModule.h>

void  setup()
{
  Serial.begin(115200);  
  delay(1000); 
  
  uim.begin();
}
  

UI Module使用者介面實作

UI Module雖然具有比 EV3 更生動的彩色螢幕,不過受限於 Arduino 硬體資源,需要妥善規劃運用方式,才能夠充分發揮效果,因此,就先以預計要移植到 EVShield 的 "樂高積木顏色分類機" 的需求,實作一個顯示積木顏色的 UI 畫面。

在下圖中,將螢幕UI畫面區分成三個功能區:



首先主頁面包含固定內容的首列與最後一列,以及在第二列顯示可自行定義的專案標題 ("Lego Bricks Color Sorter")。
接下來在第三列,作為設定顯示目前執行中動作的標題 ("
Display Color")。
而在第三列下方區域,則作為動態顯示執行結果或狀態訊息 ("
Cool RED")。

在以上三個功能區域,分別以呼叫不同的 Functions 來顯示內容,相關的程式碼如下:


//////////////////////////////////////////////////////////////////////////////////////////
// EVSH_UIM_MainPage
// Mseeage display area  : (0, 50) - (320, 219) w:320, h:170
// Clear the display area: uim.fillRect(0, 50, 320, 170, EVs_UIM_BLACK); 
//////////////////////////////////////////////////////////////////////////////////////////
void EVSH_UIM_MainPage(char* titleMsg)
{
  uim.clearScreen();
  uim.setCursor(88,0);
  uim.setTextSize(3);
  uim.setTextColor(EVs_UIM_RED);
  uim.print("EVShield");

  int xPos = (320 - strlen(titleMsg)*6*2)/2;
  xPos = (xPos < 0 ? 0 : xPos);
  uim.setCursor(xPos, 32);
  uim.setTextSize(2);
  uim.setTextColor(EVs_UIM_YELLOW);
  uim.print(titleMsg);
  uim.drawFastHLine(0, 48, 320, EVs_UIM_YELLOW);  
 
  uim.drawFastHLine(0, 221, 320, EVs_UIM_YELLOW);
  uim.setCursor(0,223);
  uim.setTextSize(2);
  uim.setTextColor(EVs_UIM_YELLOW);
  uim.print(" CH LEGO  YouTube:chchenyt");
}



//////////////////////////////////////////////////////////////////////////////////////////
// EVSH__UIM_actionMsg
// Space area 1: (0, 50)-(320, 61) h: 12
// Message area: (0, 62)-(320, 85) h: 24(8x3)
// Space area 2: (0, 86)-(320, 97) h: 12
// Text size is 3, max characters will be 17.
//////////////////////////////////////////////////////////////////////////////////////////
void EVSH_UIM_actionMsg(char* msg) {
  const int actionTextSize = 3;  
  int xPos = (320 - strlen(msg)*6*actionTextSize)/2;  
  if(xPos<0) xPos = 0;  
  uim.fillRect(0, 50, 320, 48, EVs_UIM_BLACK);
  uim.setCursor(xPos, 62);
  uim.setTextSize(actionTextSize);  
  uim.setTextColor(EVs_UIM_MAGENTA);  
  uim.print(msg);
}


//////////////////////////////////////////////////////////////////////////////////////////
// EVSH__UIM_reportMsg
// Space area 1: (0,  98)-(320, 126) h: 29
// Message area: (0, 127)-(320, 190) h: 64(8x8)
// Space area 2: (0, 191)-(320, 219) h: 29
//////////////////////////////////////////////////////////////////////////////////////////
void EVSH_UIM_reportMsg(char* msg, uint16_t textColor) {
  int textLen  = strlen(msg);
  int textSize = 5; // Max 10 characters
  int yPos = 139;
  if(textLen<=6)      {textSize = 8; yPos=127;}
  else if(textLen<=7) {textSize = 7; yPos=131;}
  else if(textLen<=8) {textSize = 6; yPos=135;}     
  int xPos = (320 - textLen*6*textSize)/2;  
  if(xPos<0) xPos = 0;
  uim.fillRect(0, 98, 320, 122, EVs_UIM_BLACK);
  
  uim.setCursor(xPos, yPos);
  uim.setTextSize(textSize);
  if(textColor == EVs_UIM_BLACK) {
    uim.fillRect(0, yPos-1, 320, 8*textSize+1, EVs_UIM_WHITE);
    uim.setTextColor(EVs_UIM_BLACK, EVs_UIM_WHITE);
  }
  else
    uim.setTextColor(textColor);
  uim.print(msg);
}

沒有留言:

張貼留言