Arduino - I2C OLED Display
本次會嘗試用 Arduino 連上 0.97" 128x64 I2C 單色 OLED 顯示 Hello World (又是儀式),
首先,把螢幕接到 Arduino 上
Pin | 連接 Arduino | Description |
---|---|---|
VCC | 5V | 這是 Power Supply |
GND | GND | 這是 Ground |
SCL | A5 | Serial Clock |
SDA | A4 | Serial Data |
然後確認一下 Arduino IDE 有沒有安裝以下 Libraries:
沒錯,SSD1306 就是這個 I2C OLED 的驅動晶片。
試玩範例
- 從 Arduino IDE 的選單中打開一個範例
Adafruit SSD1306
->ssd1306_128x64
- 把
#define SCREEN_ADDRESS 0x3D
改成0x3C
,原因是此裝置的 address 實際上是0x3C
- 上傳到 Arduino Nano
執行結果如下:
看起來 OLED 沒壞(喂)
自己寫一個範例程式
看過 Adafruit 的範例程式之後,
可以知道 I2C OLED 在程式裡面是用一個型態為 Adafruit_SSD1306
的物件操作,
可以用它提供的 C++ methods 去做一些繪圖動作。
如果我不用 Adafruit 的繪圖 API,而是直接寫入 frame buffer 呢?這是肯定的。 我剛剛參考 Adafruit 的範例寫了一個程式,會隨機產生雜點並顯示出來。
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// 定義 OLED 螢幕
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define SCREEN_ADDRESS 0x3C // I2C 位址
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);
void setup()
{
// 連接 serial port 到電腦,用來除錯
// baud rate = 9600
Serial.begin(9600);
// 啟動 OLED 螢幕
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
// 啟動失敗之後,回報錯誤並陷入無限迴圈
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
// 設定亂數種子
randomSeed(0x12AB35F);
}
void loop()
{
// 取得 display 之 frame buffer 位址
// 1 bit per pixel
uint8_t* buf = display.getBuffer();
// 塞進隨機亂數
// 64 * 16 的由來是 SCREEN_HEIGHT * SCREEN_WIDTH / 8
for (int i = 0; i < 64 * 16; ++i) {
uint8_t x = (uint8_t)random(0x100);
buf[i] = x;
}
display.display();
delay(100);
}
上傳到 Arduino 的結果:
讓人在意的是,這次 build 出來的 firmware 高達 14K, 是 Arduino Nano (ATmega328P) 之 Flash Memory 的一半, 不知道能不能繞過 Adafruit Library 達成瘦身…
Sketch uses 14394 bytes (46%) of program storage space. Maximum is 30720 bytes.
Global variables use 527 bytes (25%) of dynamic memory, leaving 1521 bytes for local variables. Maximum is 2048 bytes.