David Lin

David Lin

一個軟體工程師的隨意筆記

25 May 2021

Arduino - I2C OLED Display

本次會嘗試用 Arduino 連上 0.97" 128x64 I2C 單色 OLED 顯示 Hello World (又是儀式),

首先,把螢幕接到 Arduino 上

OLED Pins

Pin連接 ArduinoDescription
VCC5V這是 Power Supply
GNDGND這是 Ground
SCLA5Serial Clock
SDAA4Serial Data

Wiring

然後確認一下 Arduino IDE 有沒有安裝以下 Libraries:

沒錯,SSD1306 就是這個 I2C OLED 的驅動晶片。

試玩範例

  1. 從 Arduino IDE 的選單中打開一個範例 Adafruit SSD1306 -> ssd1306_128x64
  2. #define SCREEN_ADDRESS 0x3D 改成 0x3C,原因是此裝置的 address 實際上是 0x3C
  3. 上傳到 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.

References

comments powered by Disqus