10

Coding4Fun - OLED 顯示器 I2C vs SPI 效能評測

 3 years ago
source link: https://blog.darkthread.net/blog/spi-i2c-oled-benchmark/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
OLED 顯示器 I2C vs SPI 效能評測-黑暗執行緒

前陣子買了 Arduino/ESP 用的 TFT 彩色螢幕時,發現通訊介面清一色都是 SPI,不像之前買的 0.96" 128x64 單色 OLED 有 I2C 跟 SPI 兩種規格可選。我大概知道二者的差別是 SPI 要接的訊號線較多,但速度快;I2C 最大的好處是只需要兩條線就可串接一堆設備。由彩色螢幕只用 SPI 這點,可推測 I2C 速度慢應是一大罩門,但究竟有多慢,沒實測過心裡不踏實,便多花 90 塊買了片 SPI 介面 128x64 OLED 滿足好奇心。

thumbnail

爬文知道,I2C 的傳輸速度分為標準版 100 kbps 與快速版 400 kbps (還有更快的 3.4 Mbps,但一般 ESP/Arduino 開發板不支援),而 SPI 的傳輸速度為 10 Mbps 起跳,而 0.96" OLED 使用 SSD1306 晶片,依 DataSheet,SPI Clock 頻率上限為 10 MHz (Interface speed = 1/100ns = 10 MHz),序列訊號的資料傳輸量上限也差不多為 10 Mbps。延伸閱讀:

我打算用 ESP32 來測效能差異,程式庫用之前 Fork Adafruit SSD1306 加入 ttyPrintln() 自動捲動功能的版本。測試方法很簡單,ESP32 同時接 I2C 及 SPI 版 OLED,Adafruit SSD1306 程式庫原本就支援 I2C/SPI 兩種版本,故我分別建立 I2C 及 SPI 版的 Adafruit_SSD1306 物件,分別跑測試先顯示由右向左滑入 64x64 Bitmap 的動畫,再 ttyPrintln() 自動上捲列印數字 0 到 255,測試前後由 micros() 算出耗費的時間(µs):

#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_I2CDevice.h>
#include <Adafruit_SSD1306.h>
#include "bitmap.h"

#define SCREEN_ADDRESS 0x3C

// I2C OLED, SCK=22, SDA=18
Adafruit_SSD1306 displayI2C(128, 64, &Wire, -1);
// SPI OLED, CS=5, RST=17, DC=16, MOSI(D1)=23, SCLK(D0)=18
Adafruit_SSD1306 displaySPI(128, 64, 23, 18, 16, 17, 5);

// the display instance to test
Adafruit_SSD1306 display;

// the test procedure
void runTest(String testName)
{
  // 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
  }

  auto startTime = micros();
  // clear the buffer
  display.clearDisplay();

  // 64x64 image sliding from right to center
  for (int i = 128; i >= 32; i--)
  {
    display.clearDisplay();
    display.drawBitmap(i, 0, guineapigBitmap, 64, 64, WHITE);
    display.display();
  }
  display.setTextColor(WHITE, BLACK);
  display.setCursor(0, 56);

  // print from 0 to 255 with auto scrolling up
  display.ttyPrintln();
  for (int i = 0; i < 256; i++)
  {
    display.ttyPrint(" " + String(i));
    display.display();
  }
  display.ttyPrintln();
  display.ttyPrintln();
  display.display();

  // calculating elapsed time (in µs)
  auto elapsed = micros() - startTime;
  display.ttyPrintln(testName + " elapsed time:");
  display.ttyPrintln(String(elapsed) + " us");
  display.display();
}

void setup()
{
  // test I2C OLED
  display = displayI2C;
  runTest("I2C");
  // test SPI OLED
  display = displaySPI;
  runTest("SPI");
}

void loop()
{
}

令人期待的時刻來臨,答案揭曉 - I2C 耗時 9.8 秒,SPI 耗時 1.2 秒,SPI 快了 8 倍,所以想要快速顯示,選 SPI 就對了。

實測影片


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK