四.10-5 OLED顯示器綜合顯示實習—WiFi連線相關畫面設計
在練習過Adafruit公司在SSD1306這款OLED顯示器上所提供的一些指令之後,為了配合之後物聯網章節的應用,特地設計了這個實習將前面所使用的指令與功能做一個混合型的示範,好讓使用者能對這個OLED顯示器的使用能有更清楚的觀念。在這個小單元中,將會帶領大家將前面介紹過的三種功能,也就是文字顯示、繪圖與貼圖等指令函式,以ESP系列模組(ESP8266或ESP32系列都可以使用)自動連接WiFi分享器的場景,設計一些可能用到的UI介面圖像,以作為這個章節的結束。
◎功能與動作說明:
在這個範例程式中,我們會令OLED顯示器交互的顯示下面三種畫面,第一種和第二種很類似,都是使用在ESP系列模組在連接WiFi分享器的場景,差別只是在螢幕最下方的小方塊是以單塊跑馬燈的方式由左至右移動,還是隨時間逐漸增多方塊的方式顯示;這兩種畫面的功能相同,使用者可依自己的喜好選擇其中之一來使用。第三種則是設計在使用者無法連線上WiFi分享器時,ESP系列模組進入存取點(Access Point)模式,並等待使用者連線後,進入掃描周圍WiFi分享器,及手動選擇所要連線WiFi分享器的畫面。
圖4、31-1 ESP系列模組連接WiFi分享器畫面之一
圖4、31-2 ESP系列模組連接WiFi分享器畫面之二
圖4、31-3 ESP系列模組進入存取點(Access Point)模式畫面
上述三個畫面所用到相關指令如下:
ESP系列模組連接WiFi分享器畫面之一:畫面上方以貼圖指令貼上一代表WiFi的簡易圖示,中間顯示一提示用的文字訊息”WiFi Connecting…”,下方以繪圖指令畫出一動態的矩形填滿方塊跑馬燈,方向由左至右每隔0.5秒移動一格,共12格。
ESP系列模組連接WiFi分享器畫面之二:畫面上中兩個部分與前面的相同,只是下方以繪圖指令畫出一動態的矩形填滿方塊堆疊,方向由左至右每隔0.5秒增加一格,同樣共12格。
ESP系列模組進入存取點(Access Point)模式畫面:畫面左下方以貼圖指令貼上一代表AP存取點的簡易圖示,其餘都是顯示提示用的文字訊息,由上而下依序是”Access Point Mode!”,代表AP存取點名稱的”ESP_AP001”,及右下方的本地IP位址”Local IP=192.168.4.1”。
◎電路圖:
本次實習所使用之電路與前面幾個相同,學者可依自己的方便自行選用。
◎ 程式列表與說明:
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "image.h"
#include "image2.h"
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
void setup() {
Serial.begin(115200);
Serial.begin(115200);
Serial.println();
// initialize with the I2C addr 0x3C
if(display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) // Address 0x3D for 128x64
Serial.println("SSD1036 OLED allocation Successed!");
else {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
delay(2000); // Pause for 2 seconds
// 顯示圖示畫面的無窮迴圈:
while (1) {
// 顯示 ESP系列模組連接WiFi分享器畫面之一:
for (int i=0;i<12 ;i++)
{
display.clearDisplay();
// Draw bitmap on the screen
display.drawBitmap(30, 0, WiFiMap2, 70, 40, WHITE);
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,46);
display.println("WiFi Connecting...");
display.fillRect(i*10, 58, 6, 6, WHITE);
display.display();
delay(500);
}
// 顯示 ESP系列模組連接WiFi分享器畫面之二:
for (int i=0;i<12 ;i++)
{
display.clearDisplay();
// Draw bitmap on the screen
display.drawBitmap(30, 0, WiFiMap2, 70, 40, WHITE);
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,46);
display.println("WiFi Connecting...");
for(int j=0;j<i+1;j++)
display.fillRect(j*10+3, 58, 6, 6, WHITE);
display.display();
delay(500);
}
// ESP系列模組進入存取點(Access Point)模式畫面:
display.clearDisplay();
// Draw bitmap on the screen
display.drawBitmap(0, 28, WiFi_AP4, 55, 35, WHITE);
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.println(" Access Point Mode!");
display.setTextSize(2);
display.setCursor(0,10);
display.println(" ESP_AP001");
display.setTextSize(1);
display.setCursor(58,35);
display.println(" Local IP=");
display.setCursor(58,45);
display.println("192.168.4.1");
display.display();
delay(5000);
}
// 顯示圖示畫面的無窮迴圈結束
}
void loop() {}
// image.h的檔案內容, 圖片大小為70x40 px
const unsigned char WiFiMap2 [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff,
0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x7f,
0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x1f, 0xff, 0x00, 0x00, 0x00,
0x0f, 0xfc, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x1f, 0xf0,
0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfc, 0x00, 0x01, 0xfc, 0x00, 0x00, 0x00, 0x00,
0x00, 0xfe, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x80, 0x0f, 0xc0, 0x00, 0x1f,
0xff, 0xf0, 0x00, 0x0f, 0xc0, 0x1f, 0x80, 0x01, 0xff, 0xff, 0xfe, 0x00, 0x07, 0xe0, 0x3f, 0x00,
0x0f, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xf0, 0x3c, 0x00, 0x3f, 0xf8, 0x00, 0x3f, 0xf0, 0x00, 0xf0,
0x18, 0x00, 0xff, 0x80, 0x00, 0x07, 0xfc, 0x00, 0x60, 0x00, 0x03, 0xfc, 0x00, 0x00, 0x00, 0xff,
0x00, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00,
0x00, 0x0f, 0xc0, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x3e, 0x00,
0x07, 0xff, 0x80, 0x01, 0xf0, 0x00, 0x00, 0x1c, 0x00, 0x3f, 0xff, 0xf0, 0x00, 0xe0, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfe, 0x01, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x0f,
0xc0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00,
0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfe, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfe,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// image2.h的檔案內容, 圖片大小為55x35 px
const unsigned char WiFi_AP4 [] PROGMEM = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff,
0xff, 0xfe, 0x7f, 0xff, 0x9e, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0x8e, 0xff, 0xff, 0xff, 0xf8,
0xe7, 0xf9, 0xc6, 0xff, 0xff, 0xff, 0xf9, 0xc7, 0xf8, 0xe6, 0xff, 0xff, 0xff, 0xf1, 0xcf, 0x3c,
0xe6, 0xff, 0xff, 0xff, 0xf3, 0x8e, 0x0c, 0x62, 0xff, 0xff, 0xff, 0xf3, 0x8e, 0x0e, 0x62, 0xff,
0xff, 0xff, 0xf1, 0xce, 0x1c, 0xe2, 0xff, 0xff, 0xff, 0xf9, 0xcf, 0x3c, 0xe6, 0xff, 0xff, 0xff,
0xf9, 0xe7, 0x39, 0xc6, 0xff, 0xff, 0xff, 0xfc, 0xff, 0x3f, 0xce, 0xff, 0xff, 0xff, 0xfe, 0x7f,
0x3f, 0x9e, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfe,
0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff,
0xff, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0xff, 0xff,
0xff, 0x3f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f,
0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe6, 0x8f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xe6, 0x8f, 0xff, 0xff, 0xf9, 0xf3, 0xf3, 0xe6, 0x8f, 0xff, 0xff,
0xe0, 0xe0, 0xc1, 0xe6, 0x8e, 0x00, 0x01, 0xe0, 0xe4, 0xc0, 0xe6, 0x8f, 0xff, 0xff, 0xf0, 0xf1,
0xe1, 0xe6, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe6, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe6,
0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xfe
};
程式名稱:ESP_OLED_Connect1.ino
本範例程式最前面的1~22行,除了4、5兩行用來引入兩張所需的圖片點陣檔之外,其他都是沿用之前的範例;而真正的主體程式就是setup()其餘的部分,其中包含了一個展示三張圖片的無窮while(1) {}(25~75行)迴圈,在這個迴圈中的26~39行程式是用來顯示第一種ESP系列模組連接WiFi分享器畫面,其內容如下:
26. // 顯示 ESP系列模組連接WiFi分享器畫面之一:
27. for (int i=0;i<12 ;i++)
28. {
29. display.clearDisplay();
30. // Draw bitmap on the screen
31. display.drawBitmap(30, 0, WiFiMap2, 70, 40, WHITE);
32. display.setTextSize(1);
33. display.setTextColor(WHITE);
34. display.setCursor(0,46);
35. display.println("WiFi Connecting...");
36. display.fillRect(i*10, 58, 6, 6, WHITE);
37. display.display();
38 delay(500);
39. }
整個程式是一個執行12次的for()迴圈,迴圈中一開始當然是清除之前內容(29行),然後把下面的圖案貼在螢幕(30,0)開始的位置上(31行);這張圖片已經在前面介紹過的『image2cpp』網站上調整成 70X40 px的大小,使用的檔案名稱為『WiFiMap2』,畫面為反白,也就是黑色的部分在螢幕上會以白色的方式顯示。
圖4、32 WiFi分享器示意畫面
這個貼圖的指令內容如下:
31. display.drawBitmap(30, 0, WiFiMap2, 70, 40, WHITE);
接著在OLED螢幕的中間顯示「WiFi Connecting…」這樣的提示文字(34、35行),然後依迴圈的次序,由左至右在螢幕的下方顯示一個填滿的矩形小方塊(36行),而每個方塊顯示的時間為0.5秒,這樣一來便可以在螢幕上看到跑馬燈的效果了!
而下面的40~54行程式是第二種ESP系列模組連接WiFi分享器畫面,同樣是一個執行12次的for()迴圈,和前面不同之處,就是螢幕下方本來是顯示單一個填滿的矩形小方塊,在此將它擴充為下列的for()迴圈形式:
50. for(int j=0;j<i+1;j++)
51. display.fillRect(j*10+3, 58, 6, 6, WHITE);
也就是說隨著外層的迴圈次數增加,螢幕上所顯示填滿矩形小方塊數目也會隨之增加,這樣一來便可以在螢幕上看到時間累進的效果了!
一般ESP系列模組在開機後,如果沒有連上任何的WiFi分享器,我們會讓ESP系統進入AP存取點模式,好供使用者以手動的方式先掃描周圍可見的WiFi分享器,然後選擇可用的WiFi分享器並輸入連線密碼後(如果有的話),啟動連線功能,因此第三個顯示畫面便是在提供這種使用者的UI操作介面。
本範例程式的55~72行是這個使用者UI操作介面的實作部分,首先會在螢幕的左下方貼上【圖4、33】名稱為『WiFiMap4』的小圖,這個圖單純只是做為裝飾之用,並沒有其他的功能。
58. display.drawBitmap(0, 28, WiFi_AP4, 55, 35, WHITE);
圖4、33 ESP系列模組進入存取點(Access Point)模式使用之貼圖
接著由上而下先在OLED顯示器螢幕上方顯示" Access Point Mode!"提示訊息(59~62行),然後是這個AP存取點的SSID名稱「ESP_AP001」(63~65行),最後則是這個AP存取點的本地IP位址「192.168.4.1」(66~70行);由這三種訊息的字形大小不一樣,因此必須每次去切換。
剩下的80~104行也就是”image.h”這個引入檔中『WiFiMap2』這個圖檔的內容,而107~124行則是”image2.h”這個引入檔中『WiFiMap4』圖檔的內容,如果大家不喜歡開新的引入檔頁面,可以照上面範例程式的格式直接使用,只是要記得把4、5行的引用部份去掉。
最後完成的畫面已經上傳到下列的網址上,請讀者自行去觀看執行的結果;不過請注意本範例程式只是在設計OLED顯示器上可能用到的UI介面,並沒有去實作自動連線WiFi分享器的功能,這部分會在後面物聯網的單元再為大家介紹。
沒有留言:
張貼留言