使用 SSD1306 OLED 顯示輸出效果

在下使用微控制器或開發板製作電子工具時,經常需要使用 序列(Serial) 來偵錯或測試效果
但當電子工具獨立運作時,便無法顯示 序列(Serial) 的內容
而先前試用 LCD熒幕 體積比較大,亦需要較多線路,使用上比較不便
因此在下嘗試尋找比較細小,線路較少,容易操作的顯示工具

0.96in-OLED

外觀

SSD1306 0.96寸 OLED 的正面

SSD1306 支援 I 2 C 及 SPI ,模組引出 I 2 C 的 SCL 及 SDA 引腳

SSD1306 0.96寸 OLED 的背面

模組使用 0x3C 作為 I 2 C 從機地址
有需要的話,亦可以將連接到 0x3C 電阻除焊,連接到 0x3D ,便可以更改 I 2 C 從機地址
但亦即是一組 I 2 C 最多只支援 2個 SSD1306 OLED ,除非使用另一組 I 2 C
不過,如果只顯示效果資料,2個 SSD1306 OLED 已經足夠
(Address 串錯字)

引腳
編號引腳方向功能
1GND接地
2VCC電源
3SCK輸入序列時脈
4SDA輸入序列資料

在下根據引腳功能焊接不同顏色的引腳

ESP32-C3 Super-Mini

外觀

ESP32-C3 Super-Mini 的正面

ESP32-C3 Super-Mini 當然是使用 ESP32-C3晶片
ESP32-C3 具備 WiFi 及 BLE HID 功能

接駁電源後,紅色LED會亮著

可以控制亮度的藍色LED,直接連接到 ESP32-C3 的 GP8
接地時 亮著 或 PWM訊號越低越光

BOOT按鈕,直接連接到 ESP32-C3 的 GP9 ,接地時起動裝置會進入 起動模式
按下時接地

RST按鈕,接地時 重置裝置
按下時接地

ESP32-C3 不是使用傳統天線,或電路板天線,而是使用更節省空間的 晶片天線

ESP32-C3 Super Mini 的背面
顯示引腳名稱

引腳
USB方向(正面)
左排引腳右排引腳
GP51165V
GP6215GND
GP73143V3
GP8413GP4
GP9512GP3
GP10611GP2
GP20710GP1
GP2189GP0
編號引腳方向功能
1GP5輸入輸出第5數碼引腳,第5類比引腳,SPI MISO引腳
2GP6輸入輸出第6數碼引腳,SPI MOSI引腳
3GP7輸入輸出第7數碼引腳,SPI SS引腳
4GP8輸入輸出第8數碼引腳,I 2 C SDA引腳
5GP9輸入輸出第9數碼引腳,I 2 C SCL引腳
6GP10輸入輸出第10數碼引腳
7GP20輸入輸出第20數碼引腳,UART RX引腳
8GP21輸入輸出第21數碼引腳,UART TX引腳
9GP0輸入輸出第0數碼引腳,第0類比引腳
10GP1輸入輸出第1數碼引腳,第1類比引腳
11GP2輸入輸出第2數碼引腳,第2類比引腳
12GP3輸入輸出第3數碼引腳,第3類比引腳
13GP4輸入輸出第4數碼引腳,第4類比引腳,SPI SCK引腳
143V3輸入輸出輸出 3.3V 電源
15GND接地
165V輸出 5V 電源

同樣根據引腳功能焊接不同顏色的引腳

線路原型

使用 ESP32-C3 測試 OLED

測試線路

由於線路簡單,因此 測試線路 與 線路原型 相同

測試效果

在下使用 u8g2 函式庫,簡化開發時間

#include <U8g2lib.h>
#define I2C_SCL 9
#define I2C_SDA 8
#define WIDTH 8
#define HEIGHT 8
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE, I2C_SCL, I2C_SDA);
void setup() {
	u8g2.begin();
	u8g2.setI2CAddress(0x3C << 1);
	u8g2.clearBuffer();
}
void loop() {
	u8g2.setDrawColor(1);
	fillScreen();
	u8g2.setDrawColor(0);
	fillScreen();
}
void fillScreen() {
	for (byte y = 0; y < 64; y += HEIGHT) {
		for (byte x = 0; x < 128; x += WIDTH) {
			u8g2.drawBox(x, y, WIDTH, HEIGHT);
			u8g2.sendBuffer();
		}
	}
}

展示將熒幕的內容填滿再清空
(由於鏡頭的更新率比OLED快,因此OLED更新內容時,會有掃描線)

#include <U8g2lib.h>
#define I2C_SCL 4
#define I2C_SDA 6
#define BOOT 9
#define LED 8
bool pressed = true;
unsigned int count = 0;
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE, I2C_SCL, I2C_SDA);
void setup() {
	pinMode(BOOT, INPUT_PULLUP);
	pinMode(LED, OUTPUT);
	u8g2.begin();
	u8g2.setI2CAddress(0x3C << 1);
	u8g2.setFontPosTop();
	u8g2.setFont(u8g2_font_6x10_tr);
	u8g2.setDrawColor(1);
	u8g2.clearBuffer();
}
void loop() {
	if (pressed == false && digitalRead(BOOT) == LOW) {
		digitalWrite(LED, LOW);
		pressed = true;
		char timeString[12];
		runTime(timeString);
		u8g2.drawStr(0, 0, timeString);
		u8g2.drawStr(0, 8, String(count++).c_str());
		u8g2.sendBuffer();
	} else if (pressed == true && digitalRead(BOOT) == HIGH) {
		digitalWrite(LED, HIGH);
		pressed = false;
	}
	delay(10);
}
void runTime(char timeString[12]) {
	unsigned long milliseconds = millis();
	byte hours = milliseconds / 3600000;
	milliseconds %= 3600000;
	byte minutes = milliseconds / 60000;
	milliseconds %= 60000;
	byte seconds = milliseconds / 1000;
	milliseconds %= 1000;
	sprintf(timeString, "%02d:%02d:%02d.%03d", hours, minutes, seconds, (unsigned int) milliseconds);
}

展示按下 BOOT鈕按 (GP9) 的互動效果

補充資料

在下測試的 0.96in-OLED ,第一引腳是 GND , 但有部分第一引腳是 VCC
因此接駁時要注意次序,否則 VCC 及 GND 反向接駁,很大機會會燒毀晶片或熒幕

雖然 0.96in-OLED 顯示能夠使用 0x3C 及 0x3D 但設定 I 2 C 地址時需要 向左偏移1位元
原因是 I 2 C 使用 7位元地址(第7至第1位元) 及 使用 1位元地址(第0位元) 設定 寫入 或 讀取
例如 0x3D = B00111101 , 向左偏移1位元後成為 B01111010 = 0x7A
如果需要設定為讀取,則將第0位元設定為 1 ,即是 B01111011 = 0x7B

總結

基本上 u8g2 函式庫支援大部分已知的 OLED , u8g2 範例已經提供大量控制 OLED 的建構子
I 2 C 及 SPI 也支援,亦能夠自行設定引腳控制 OLED

SSD1306 OLED 尺寸細小,方便安裝到細小的空間及顯示輸出資料,不需要依賴序列輸出

另外 SSD1306 OLED 成本大約是 1至4美金 (視乎尺寸),成本比其他顯示熒幕裝置便宜
非常適合製作需要具備回饋或顯示效果的小型電子裝置

參考資料