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"。
詳細使用方式可以參考手冊: "Adafruit GFX Graphics Library"。
- Adafruit_ILI9340:這是定義ILI9340 TFT LCD特定屬性的程式庫,提供作為搭配 Adafruit_GFX 程式庫功能的使用。
- 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();
}
#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);
}
沒有留言:
張貼留言