[Arduino技巧]使用u8g2函式庫建立自訂字庫,讓OLED顯示中文

Arduino的絕大多數的顯示設備,都無法直接顯示中文,除了少數內建中文字庫的LCD。但像是我們常用的OLED就跟中文有些無緣了。一般的解決方法就是用圖形在顯示中文內容,這方法其實也算是可行了。但還有更厲害的招式,就是使用u8g2的顯示器函式庫,它有自訂字型庫的功能,透過它,我們可以自訂自己的字庫!

購買Arduino材料最佳選擇:https://www.jmaker.com.tw/

為何是自訂字庫,而不是「直接」使用字型呢?大家想想,隨便一個中文字型檔,沒有3MB以上不太可能吧,但我們的Arduino開發板不論是記憶體或儲存空間,都是小得可憐,怎麼可能把完整的中文字型載入呢?所以我們就轉個彎,把一些常用的中文字,其實一般Arduino專案常用的中文字也就幾十個或百來字,把這些字存成一個自己的字庫,這樣以後就能像顯示英文一樣的顯示中文了!

而要用到這個功能,就要靠u8g2函式了,有關u8g2的基本使用,請參考傑森以前的文章:
一套u8g2函式庫,玩遍所有OLED

有一點要注意,就算透過程式管理員,安裝了u8g2的函式庫,但並不會安裝我們等一下要用到的工具,所以還是要去自行下載。

https://github.com/olikraus/u8g2

我們主要是需要u8g2/tools/font/這個目錄,所以直接把tools整個目前Copy到電腦上的「Documents\Arduino\libraries\U8g2」目錄中。

進到「u8g2\tools\font\bdfconv」目錄,會看到「bdfconv.exe」這個Dos程式,我們就是要靠它來轉檔的。

我們首先要把需要的字型加入一個「U8g2\tools\font\build\chinese1.map」檔案裡。

用記事本打開它,會看到裡面已經有一些文字的unicode碼,我們只要把想加的文字,加到後面去就可以了。

處理的方法很簡單,找一個軟體或是線上服務,能把文字轉成unicode碼的就可以了。傑森這裡找到一個線上服務,大家可以參考看看。

https://www.ifreesite.com/unicode-ascii-ansi.htm

圖中大家可以發現,每一個字後面都加了一個英文的逗號,這個主要是為了方便啦。

接下來把轉好的unicode碼,一個一個的貼到chinese1.map裡,一字一行,而且大家也發現了,chinese1.map裡的格式是:「$91CC」,而unicode碼的格式是:「」,所以只要把「\u」換成「$」就可以了,這件事可以由記事本中的「取代」來完成,不用自己一個字一個字去改。

然後貼到chinese1.map裡就可以了。

接著用CMD視窗到DOS環境中,執行以下指令:

bdfconv.exe -v ../bdf/unifont.bdf -b 0 -f 1 -M ../build/chinese1.map -d ../bdf/7x13.bdf -n u8g2_font_unifont -o u8g2_font_unifont.c

完成轉碼後,字庫代碼會在u8g2_font_unifont.c檔案中,用記事本打開,把陣列內容複制起來。

接著打開「U8g2\src\clib\u8g2_fonts.c」這個檔案,找到「u8g2_font_unifont_t_chinese1」這個陣列。

把剛才從u8g2_font_unifont.c裡複制的內容,取代「u8g2_font_unifont_t_chinese1」這個陣列內容,記得連陣列大小的文字也要改成新的哦!(這點漏掉真的不行啊!!)

我們來寫支程式來測試看看吧!以下是簡單顯示文字的程式碼,只是多了一行啟用UTF8文字功能,這樣我們才能顯示中文哦!

u8g2.enableUTF8Print();  //啟用UTF8文字的功能  

大家都試試吧,在OLED顯示中文"字",真的不難哦!

#include <Arduino.h>
#include <U8g2lib.h>

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif

//U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ D2, /* data=*/ D1, /* reset=*/ U8X8_PIN_NONE); 
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
//U8G2_SH1106_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);


void setup(void) {
  u8g2.begin();
  u8g2.enableUTF8Print();  //啟用UTF8文字的功能  
}

void loop(void) {
  u8g2.setFont(u8g2_font_unifont_t_chinese1); //使用我們做好的字型
  u8g2.firstPage();
  do {
    u8g2.setCursor(0, 14);
    u8g2.print("傑森創工");
    u8g2.setCursor(0, 35);
    u8g2.print("中文完成,太強了!");   
    u8g2.setCursor(0, 60);
    u8g2.print("時間 16:28");
  } while ( u8g2.nextPage() );
  delay(1000);
}

本文主要是參考了以下的網站,萬分感謝!
https://blog.csdn.net/menghuanbeike/article/details/75666266