2024-01-02

使用 SSD1306 OLED 顯示輸出效果

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

0.96in-OLED

外觀

SSD1306 0.96寸 OLED 的正面

SSD1306 支援 I2C 及 SPI ,模組引出 I2C 的 SCL 及 SDA 引腳

SSD1306 0.96寸 OLED 的背面

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

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

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

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方向(正面)
左排引腳 右排引腳
GP5 1 16 5V
GP6 2 15 GND
GP7 3 14 3V3
GP8 4 13 GP4
GP9 5 12 GP3
GP10 6 11 GP2
GP20 7 10 GP1
GP21 8 9 GP0
編號 引腳 方向 功能
1 GP5 輸入輸出 第5數碼引腳,第5類比引腳,SPI MISO引腳
2 GP6 輸入輸出 第6數碼引腳,SPI MOSI引腳
3 GP7 輸入輸出 第7數碼引腳,SPI SS引腳
4 GP8 輸入輸出 第8數碼引腳,I2C SDA引腳
5 GP9 輸入輸出 第9數碼引腳,I2C SCL引腳
6 GP10 輸入輸出 第10數碼引腳
7 GP20 輸入輸出 第20數碼引腳,UART RX引腳
8 GP21 輸入輸出 第21數碼引腳,UART TX引腳
9 GP0 輸入輸出 第0數碼引腳,第0類比引腳
10 GP1 輸入輸出 第1數碼引腳,第1類比引腳
11 GP2 輸入輸出 第2數碼引腳,第2類比引腳
12 GP3 輸入輸出 第3數碼引腳,第3類比引腳
13 GP4 輸入輸出 第4數碼引腳,第4類比引腳,SPI SCK引腳
14 3V3 輸入輸出 輸出 3.3V 電源
15 GND 接地
16 5V 輸出 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 但設定 I2C 地址時需要 向左偏移1位元
原因是 I2C 使用 7位元地址(第7至第1位元) 及 使用 1位元地址(第0位元) 設定 寫入 或 讀取
例如 0x3D = B00111101 , 向左偏移1位元後成為 B01111010 = 0x7A
如果需要設定為讀取,則將第0位元設定為 1 ,即是 B01111011 = 0x7B

總結

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

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

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

參考資料

沒有留言 :

張貼留言