| ESP32 教學 | MicroPython | I2C OLED Image 顯示圖像 | 209 |

上篇提到可以透過 Micropython 內建的 ssd1306 模組在顯示文字,這次就來分享透過 I2C OLED Image 圖片的顯示過程,雖然 OLED 螢幕只能單色顯示,但如果可以顯示 LOGO 或一些圖示,對於使用者體驗來說,還是有明顯加分的作用,各位就來好好研究一下囉~

1. I2C OLED Image 影像轉換

為了將圖片轉換成 micropython 程式可以讀取的格式,第一個步驟就是準備一張單色且解析度 128X64 (需換成各位手邊的 OLED 解析度)的圖片,這邊可以利用影像工具軟體達成,像是 Photoshop 等,在 windows 平台最快的方法就是利用小畫家。第二個步驟 就是將此張圖片透過轉檔軟體直接轉換成陣列形式,後續我們就可以直接在程式碼內引用。下面為簡單的示範完整流程:

Step1開啟小畫家,新增檔案 =>調整大小 => 設定為 128×64 像素大小。

Step2開始編輯畫面,最後記得存成單色點陣圖。

Step3:將圖片檔透過轉換程式,轉成陣列型態,這邊推薦大家下載 LCDAssistant 這個小工具,連結如下:http://en.radzio.dxp.pl/bitmap_converter/,找到zip檔下載並解壓縮,開啟執行。

Step4:開啟 LCD Assistant 後,點選上方工具列 File =>Load Image,找到該圖片後,確認下面設定正確。

Step5再次點選 File=>Save Output,將轉換出來的程式碼,先存成文字檔即可。(這邊會存成 star.txt檔)

2. 硬體連接與程式

– 電路連接

電路連接的方法設定採用硬體ID1的I2C預設腳位。

I2c OLED Image

– 完整程式碼

import ssd1306
from machine import Pin, I2C
import framebuf
hw_i2c1 = I2C(1, freq=200000)                
oled096=ssd1306.SSD1306_I2C(128, 64, hw_i2c1)
img64=[
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFC,
0xFC, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFC, 0xFC, 0x00,
0x00, 0x00, 0x00, 0xFC, 0xFC, 0xFC, 0x7C, 0xF8, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
... ...
0x0F, 0x1F, 0x1F, 0x1F, 0x0F, 0x07, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03,
0x07, 0x0F, 0x0F, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
img064b=bytearray(img64)
imgbuf=framebuf.FrameBuffer(img064b,128,64,framebuf.MONO_VLSB)
oled096.blit(imgbuf, 0, 0)
oled096.invert(1)
oled096.show()

– 程式解說

import ssd1306
from machine import Pin, I2C
import framebuf
hw_i2c1 = I2C(1, freq=200000)                
oled096=ssd1306.SSD1306_I2C(128, 64, hw_i2c1)

與前一篇 208-OLED顯示文字 提到的 I2C 初始化設定皆相同,但多導入一個 frambuf 模組,並建立 ssd1306 的物件取名 oled096。

img64=[
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFC,
0xFC, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFC, 0xFC, 0x00,
0x00, 0x00, 0x00, 0xFC, 0xFC, 0xFC, 0x7C, 0xF8, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
img064b=bytearray(img64)

還記得我們有用 LCDAssistant 這個小工具轉出一個文字檔嗎?(可以打開這個文字檔觀看 star.txt)img64 這個序列內容就是直接複製文字檔內的const unsigned char star [] 的內容(…是省略符號,各位如需要的話,直接複製 star.txt 內容才不會有錯誤),因為 framebuf 使用的資料型態是 bytearray,所以將 img64 轉成 bytearray 型態,並取名 img64b。

知識小補充:因為我們在轉檔時時是採用單色與垂直方向排列(Vertical)的方式存檔,所以預設轉出陣列就是 1btye 會有 8 像素,資料排列也就照著直線方式一條一條轉換,img64 原始資料共有 1024 個 bytes,換算成像素也就是1024×8=8192個像素,與我們OLED 的像素128*64=8192 Pixel 是相符的。

imgbuf=framebuf.FrameBuffer(img064b,128,64,framebuf.MONO_VLSB)
oled096.blit(imgbuf, 0, 0)

imgbuf 為新建立的 framebuf 物件,framebuf 第 1 個參數為影像資料的 byte 序列,第 2、3 個參數分別為影像的寬度與高度,第 4 個參數就是像素形式與排列,MONO_VLSB 是指 單色+垂直+LSB(如果是其他形式可以填入framebuf.MONO_HLSBframebuf.RGB565framebuf.GS4_HMSB等。

.blit 這個方法也是源自 framebuf,將建立好的 imgbuf 物件,由指定的 X,Y 位置,依序開始填入 OLED 記憶體內。

補充說明:framebuf 用法可以參閱官網的說明文件 https://docs.micropython.org/en/latest/library/framebuf.html

oled096.invert(1)
oled096.show()

invert 方法為將影像資料進行反白處理,並透過 oledd096.show 將顯示到實際的 OLED 模組。

3. 小結

OLED 模組就像是我們一般使用的 LCD 螢幕,利用操作像素的亮暗來顯示文字或圖案,相較於常見的 LCD1602 或 1604,界面設計上還是可以比較多變化。而 OLED 顯示圖案,除了JIMI 哥今天講述的事先轉換成陣列資料,再複製貼到程式內的方法外,還有一種實務上更好的方法,就是可以將多張影像轉成數個 PGB 檔後,存到 micropyhon 檔案內,直接用 Python 語言 open 的指令開啟讀取編碼,搭配 framebuf 模組操作,進行畫面變化就簡單多,關於這部分的內容,JIMI哥日後可以再補充說明,今天的內容就到這邊,如果各位在操作上如果遇到問題,歡迎在下面留言給我囉!~~

↓↓↓↓↓↓賣場連結↓↓↓↓↓↓

歡迎大家有需要的話,可以多多支持一下我們的蝦皮賣場喔! 😀 

吉米家官方店-創客機器人材料專賣 https://shopee.tw/jimirobot.tw

Follow JIMI哥 Twitter : https://twitter.com/jimirobot  <–得到最新文章通知

發佈留言

Close Menu