OLED

與 Arduino 接口的 OLED 圖形顯示模塊

SSD1306 OLED 驅動器及其接口

該模塊的核心是一個強大的單芯片 CMOS OLED 驅動控制器 – SSD1306。它可以通過多種方式與微控制器通信,包括I2C 和 SPI。

SPI 通常比 I2C 快,但需要更多的 I/O 引腳。而 I2C 只需要兩個引腳,可以與其他 I2C 外設共享。這是引腳和速度之間的權衡。所以,這真的歸結為你的選擇。

由於 SSD1306 控制器的多功能性,該模塊有不同的尺寸和顏色:例如 128x64、128×32,帶有白色 OLED、藍色 OLED 和雙色 OLED。

電源要求

OLED 顯示器在沒有背光的情況下工作,因為它自己發光。這就是為什麼該顯示器具有如此高的對比度、極寬的視角並且可以顯示深黑色的原因。背光的缺失顯著降低了運行 OLED 所需的功率。顯示器平均使用大約20mA 的電流,儘管這取決於顯示器的點亮程度。

SSD1306 控制器的工作電壓為1.65V 至 3.3V,而 OLED 面板需要 7V 至 15V 的電源電壓。所有這些不同的電源要求都可以使用內部電荷泵電路來滿足。這使得它可以輕鬆連接到 Arduino 或任何 5V 邏輯微控制器,而無需使用任何邏輯電平轉換器。

OLED 內存映射

無論 OLED 模塊的大小如何,SSD1306 驅動程序都有一個內置的 1KB圖形顯示數據 RAM (GDDRAM),用於保存要顯示的位模式的屏幕。這個 1K 的內存區域被組織成 8 頁(從 0 到 7)。每頁包含 128 列/段(塊 0 到 127)。並且每列可以存儲 8 位數據(從 0 到 7)。

8 頁 x 128 段 x 8 位數據 = 8192 位 = 1024 字節 = 1KB 內存

每個位代表屏幕上的特定 OLED 像素,可以通過編程方式打開或關閉。

128×64 OLED 屏幕顯示RAM 的所有內容,而128×32 OLED 屏幕僅顯示RAM 的4 頁(一半內容)。

以下是完整的規格:

  • 顯示技術 OLED(有機發光二極管)

  • 單片機接口 I2C / SPI

  • 屏幕尺寸 0.96 英寸寬

  • 解析度 128×64 像素

  • 工作電壓 3.3V – 5V

  • 工作電流 最大 20mA

  • 可視角度 160°

  • 每行字符數 21

  • 字符行數 7

#include<Adafruit_SSD1306.h>

通過輸入“adafruit ssd1306”來過濾您的搜索。尋找 Adafruit 的 Adafruit SSD1306。單擊該條目,然後選擇安裝。

#include<Adafruit_GFX .h>

通過輸入“Adafruit GFX Library”來過濾您的搜索。這個 Adafruit SSD1306 庫是一個特定於硬件的庫,用於處理較低級別的功能。它需要與Adafruit GFX 庫配對以顯示圖形基元,如點、線、圓、矩形等。也安裝此庫。

基礎顯示程式

#include<Wire.h>#include<Adafruit_GFX.h>#include<Adafruit_SSD1306.h>#define CREEN_WIDTH 128 //設定OLED螢幕的寬度像素#define CREEN_HEIGHT 64 //設定OLED螢幕的寬度像素#define OLED_RESET -1 //Reset pin如果OLED上沒有RESET腳位,將它設置為-1
Adafruit_SSD1306 display(CREEN_WIDTH, CREEN_HEIGHT, &Wire, OLED_RESET); //OLED顯示器使用2C連線並宣告名為display物件bool OLEDStatus = true;void setup() { Serial.begin(9600); if(!display.begin(SSD1306_SWITCHCAPVCC,0x3c)) { //設定位址為 0x3c Serial.println(F("SSD1306 allocation falled")); //F(字串):將字串儲存在fash並非在RAM OLEDStatus = false; //開啟OLED失敗 } if(OLEDStatus == true) testdrawchar(); //Draw characters of the default font}
void loop() {}
void testdrawchar(void) { display.clearDisplay(); //清除緩衝區資料 display.setTextSize(1); //設定文字尺寸為1,1:6x8,2:12x16,3:18x24...etc display.setCursor(0, 0); //設定起始點位置(0,0) display.setTextColor(BLACK, WHITE); //黑字白底 display.println("Hello") ; //將"Hello"存入RAM display.setCursor(0,16); //設定起始點位置(0,16) display.setTextSize(2); //設定文字尺寸為2 display.setTextColor(WHITE); //設定文字顏色為白色(亮點) display.println("Hello"); //將"Hello"存入RAM display.setTextSize(3); //設定文字尺寸為3 display.println("Hello"); //將"Hello"存入RAM display.display(); //顯示所設定文字}

使用OLED顯示目前時間

/*中文字型編碼網站"https://www.23bei.com/tool-218.html"注意--"取模方式" [橫向8點左高位],"强制全角" [ASCII不轉換全角]*/
#include <Wire.h>#include <Adafruit_GFX.h>#include <Adafruit_SSD1306.h>#include <WiFi.h>#include "time.h"
#define CREEN_WIDTH 128 //設定OLED螢幕的寬度像素#define CREEN_HEIGHT 64 //設定OLED螢幕的寬度像素#define OLED_RESET -1 //Reset pin如果OLED上沒有RESET腳位,將它設置為-1
Adafruit_SSD1306 display(CREEN_WIDTH, CREEN_HEIGHT, &Wire, OLED_RESET); //OLED顯示器使用2C連線並宣告名為display物件
const char* ssid = "ssid"; //連線名稱const char* password ="password"; //連線密碼
const char* ntpServer = "pool.ntp.org"; //NTP Server網址const long gmtOffset_sec =28800; //台灣為GMT8小时·8hrs=28800secconst int daylightOffset_sec= 0; //日光節時間為0
bool OLEDStatus = true;
static const unsigned char PROGMEM str_1[]={ //現0x00,0x08,0x01,0xFC,0xFD,0x08,0x11,0x08,0x11,0xF8,0x11,0x08,0x11,0x08,0x7D,0xF8,0x11,0x08,0x11,0x08,0x11,0xF8,0x1D,0x48,0xF0,0xA0,0x41,0x22,0x02,0x22,0x0C,0x1E};static const unsigned char PROGMEM str_2[]={ //在0x02,0x00,0x02,0x00,0x02,0x04,0xFF,0xFE,0x04,0x00,0x04,0x40,0x08,0x40,0x08,0x48,0x13,0xFC,0x30,0x40,0x50,0x40,0x90,0x40,0x10,0x40,0x10,0x44,0x17,0xFE,0x10,0x00};static const unsigned char PROGMEM str_3[]={ //時0x00,0x20,0x04,0x20,0x7E,0xF8,0x44,0x20,0x44,0x20,0x45,0xFC,0x44,0x10,0x7C,0x10,0x47,0xFE,0x44,0x10,0x44,0x90,0x44,0x50,0x7C,0x50,0x44,0x10,0x00,0x50,0x00,0x20};static const unsigned char PROGMEM str_4[]={ //間0x00,0x08,0x7C,0xFC,0x44,0x88,0x7C,0xF8,0x44,0x88,0x7C,0xF8,0x40,0x08,0x4F,0xC8,0x48,0x48,0x4F,0xC8,0x48,0x48,0x4F,0xC8,0x48,0x48,0x40,0x08,0x40,0x28,0x40,0x10};
void setup() { Serial.begin(9600); if(!display.begin(SSD1306_SWITCHCAPVCC,0x3c)) { //設定位址為 0x3c Serial.println(F("SSD1306 allocation falled")); //F(字串):將字串儲存在fash並非在RAM OLEDStatus = false; //開啟OLED失敗 } Serial.printf("Connecting to %s ", ssid); //顯示連線AP SSID WiFi.begin(ssid, password); //建立WiFi連線while (WiFi.status() != WL_CONNECTED) { //當狀態不是已連線 Serial.print("."); //印出一個"." } Serial.println(" CONNECTED"); //初始化並取回時間 configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); //設定NTP參數} void loop() { struct tm timeinfo; //建立一個時間結構,為timeinfo if(!getLocalTime(&timeinfo)){ //取回NTP時間 Serial.println("Failedto obtain time"); //若失敗,顯示失敗訊息" return; } Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S"); //顯示"星期,月日年,時:分:秒
if(OLEDStatus==true) { display.clearDisplay(); //清除緩衝區資料 display.setTextSize(2); //設定字型大小為2
display.setCursor(4,0); //設定文字起始位置為(4,0) display.setTextColor(WHITE, BLACK); //設定白字黑底 display.println(&timeinfo, "%F"); //設定文字内容為年月日,格式為"西元年-月-日"
display.setCursor(10,16); //設定文字起始位置為(10,16) display.println(&timeinfo, "%A"); //設定文字内容為星期,格式為Mondy Tu· display.drawBitmap(0, 32, str_1, 16, 16, WHITE); //現,位置( 0,32)字型大小16*16顏色白色 display.drawBitmap(18, 32, str_2, 16, 16, WHITE); //在,位置(18,32)字型大小16*16顏色白色 display.drawBitmap(36, 32, str_3, 16, 16, WHITE); //時,位置(36,32),字型大小16*16顏色自色 display.drawBitmap(54, 32, str_4, 16, 16, WHITE); //間,位置(54,32),字型大小16*16,顏色白色
display.setCursor(16,50); //設定文字起始位置為(16,48) display.println(&timeinfo, "%T"); //設定文字內容為年月日,格式為"時:分:秒" display.display(); //顯示所設定的文字 } delay(1000); }