[第六課] OLED顯示原理 (I2C)
人生很窄,得失只在方寸間;人生很寬,成敗猶在千里外。~魯迅
話說,嵌入式系統的設計,貴在精巧且反應敏捷;我們再複習一下,Seeeduino XIAO這主控板可支援一組 SPI D2 D8 D9 D10 (連接NFC ReWriter模組)、一組 I2C D4 D5 (連接OLED顯示器模組與RTC)、與一組 UART D6 D7 (連接DFPlayer Mini模組);雖然對目前的應用可說是剛剛好,但也沒有多餘的輸入端子來做互動,必須仰仗NFC標籤的感應來操控。所以這組OLED顯示器就有舉足輕重的溝通角色,負責顯示本機狀態、目前時間、播放模式與音軌的目錄與曲目編號...等。
在引用連接時,除使用 u8g2lib 外,也要啟動 I2C 的通訊:
#include <U8g2lib.h>#ifdef U8X8_HAVE_HW_I2C#include <Wire.h>#endif/* OLED Display via I2C*/U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
然後,在 setup() 時,啟用:
u8g2.begin();u8g2.enableUTF8Print();
這 OLED顯示器 其實是點陣式,有 128 x 64 點的解析度。也就是說,你看到的英文文字,其實是一點一點『畫』上去的;而每個圖案或文字都是由不同尺寸的字型庫所描述那『一點一點』的內容。就舉上面的例子,這個名為 u8g2_font_open_iconic_app_4x_t 的字型檔,是存放 32x32 點的圖案的點陣資料,其字型編碼自#64開始;我們會用到時鐘的圖示,取用方法如下:
case TIME:u8g2.setFont(u8g2_font_open_iconic_app_4x_t);u8g2.drawGlyph(x, y, 69);break;
先來看圖文混合模式,將螢幕分成上 (st)、中 (sr)、下 (ss) 三個區域,上與下為訊息標題與提示,均使用 u8g2_font_ncenB08_tr 的字型 (12x11);而中間區域依照訊息的種類(kind),會有不同的切割與規畫;如果以通用的 0xFF 型為例:前 32x32 作為圖像顯示,之後為通用的本文顯示:可以是曲目資訊、時間等。此例的下面還列出其他 0x01 、 0x02 、 0xF1 的三種模式,請自行參考。
來看一下 draw 的程式碼:
void draw(uint8_t symbol, byte kind){u8g2.firstPage();do {drawSTATE(symbol, kind);u8g2.setFont(u8g2_font_ncenB08_tr);u8g2.setCursor(0, 12);u8g2.print(st);u8g2.setCursor(0, 62);u8g2.print(ss);//drawScrollString(offset, s);} while ( u8g2.nextPage() );delay(20);}
中間區域的顯示由 drawSTATE(symbol, kind) 負責。
剛才提到還有一種『多行文字』顯示的方式,其原理就是把中間的區域,再分割成三行文字顯示一樣是取用和上、下區相同的字型:
void drawTXT(String sl1, String sl2, String sl3){u8g2.firstPage();do {u8g2.setFont(u8g2_font_ncenB08_tr);u8g2.setCursor(0, 12);u8g2.print(st);u8g2.setCursor(0, 24);u8g2.print(sl1);u8g2.setCursor(0, 36);u8g2.print(sl2);u8g2.setCursor(0, 48);u8g2.print(sl3);u8g2.setCursor(0, 62);u8g2.print(ss);} while ( u8g2.nextPage() );}
最後,要提醒一下,考慮到人類視覺暫留的時間,更新完螢幕的顯示後,別忘了Delay至少300ms的時間:
draw(TRK, 0x01); //以0x01類顯示“TRK"曲目資訊。delay(2000); //因為歌曲已經開始播放,此處暫停兩秒無妨。
下回見。
留言
張貼留言