ESP8266 開發板 with 0.91 inch OLED Display – WeMos TTGO

在前面的文章,我們就評估過一張 1.8 吋 SPI 介面的全彩顯示器。但您一定會發現使用 D1-mini,就已會被佔掉五支 GPIOs,因此剩下能運用的腳位就不多了。也因此 WeMos 又出了另一張開發板,稱為 TTGO,板上配置了一張 0.91 吋的 OLED 顯示器。而當前筆者將要運用的是單色顯示,故它是不是全彩的筆者就未查證了。此顯示器使用了 I2C 作為傳輸介面,這意謂著佔用掉的兩根 PIN 還可復用,沒錯吧 I2C Bus。再加上,此板並不使用 ESP8266MOD 模組,意謂著更多的 GPIOs 將會被釋放出來,運用度更高。當然相對面 de-modulation(假借,去模組化)就有可能劣於 ESP8266MOD 抗干擾。
本文將快速地驅動這張開發板。這在 Arduino 的世界裏並不是新鮮事。
20210503 補充:這張開發板可以直接對電池充電,不過電池本身須具保護板。另外這張板,容易變得無法 write flash 更新。建議嘗試使用改版的。
20230814 補充:U8g2 的 reset pin 指定為 -1。若板子沒有 reset pin 給接,則如此設之;若有,建議 pull-high/low(不確定)以避免浪費一支 GPIO。



20210511 補充 如附圖說明

請注意,筆者有發現用上 SIL USB2UR chip,必須在 setup() 一開頭 delay 上至少 2 秒。
步驟
- 安裝額外必要的函式庫,按關鍵字來搜尋程式庫:Adafruit SSD1306,U8g2
- 在網路上找尋可用的範例,筆者稍作修改並貼於下。From “Simple Stuff Matters”。這份範例的出處。



參考資料
教學影片,內容蠻詳盡的。筆者也聽不懂,請打開字幕多少有些幫助。點擊此。
範例
說明:請將 wifi_ssid 及 wifi_password 改成您的 AP 的,否則無法連線程式會一直停頓在那連線。另外運行時請打開序例埠監控視窗,鮑率設成 115200,可觀看進度。若一直出現點點點就代表連線連不上請檢查連線。至於 OTA 是什麼筆者也不是很清楚,但它在此範例不影響什麼,只要求連線成功即可。
板子請選擇 “NodeMCU 0.9 (ESP-12 Module)”或其類似。
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////                                                                                                          ////
////  TTGO ESP8266 0.91 inch OLED demo w/ OTA                                                                 ////
////  requires U8g2 library                                                                                   ////
////  Select "NodeMCU 0.9 (ESP-12 Module)" board                                                              ////
////  More examples at http://simplestuffmatters.com                                                          ////
////  USB drivers: https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers  ////
////                                                                                                          ////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <ESP8266WiFi.h>  //For ESP8266
#include <ESP8266mDNS.h>  //For OTA
#include <WiFiUdp.h>      //For OTA
#include <ArduinoOTA.h>   //For OTA
#include <Arduino.h>
#include <U8g2lib.h>      // make sure to add U8g2 library and restart Arduino IDE  
#include <SPI.h>
#include <Wire.h>
#define OLED_SDA  2
#define OLED_SCL 14
#define OLED_RST  4
U8G2_SSD1306_128X32_UNIVISION_F_SW_I2C u8g2(U8G2_R0, OLED_SCL, OLED_SDA , OLED_RST);
const char *text = "U8g2 OTA";  // scroll this text from right to left
//WIFI configuration
#define wifi_ssid "rewirte_this_word_to_your_ssid"
#define wifi_password "rewirte_this_word_to_your_ssids_password"
#define WiFi_hostname "ESP8266-TTGO"
//Necesary to make Arduino Software autodetect OTA device
WiFiServer TelnetServer(8266);
void setup_wifi() {
  delay(100);
  Serial.println("");
  Serial.print("Connecting to ");
  Serial.println(wifi_ssid);
  WiFi.hostname(WiFi_hostname);
  WiFi.begin(wifi_ssid, wifi_password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.print("   IP address: ");
  Serial.println(WiFi.localIP());
  Serial.print("Configuring OTA device...");
  TelnetServer.begin();   //Necesary to make Arduino Software autodetect OTA device  
  ArduinoOTA.onStart([]() {Serial.println("OTA starting...");});
  ArduinoOTA.onEnd([]() {Serial.println("OTA update finished!");Serial.println("Rebooting...");});
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {Serial.printf("OTA in progress: %u%%\r\n", (progress / (total / 100)));});  
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
    else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
    else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
    else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
    else if (error == OTA_END_ERROR) Serial.println("End Failed");
  });
  ArduinoOTA.begin();
  Serial.println("Wifi OK, OTA Ready on telnet 8266.");
}
char str1[17];        // ******** intended for a wiggling string on display
byte dir1;            // ******** intended for a wiggling string on display
void setup() {
  Serial.begin(115200);
  setup_wifi();  
  u8g2.begin();
  strcpy(str1, text); // ******** intended for a wiggling string on display
}
// a null-terminated string already in an frmsz-size frm-frame with or without leading spaces will be wiggling in it.
// dir stores 0(forward) or 1(backward, non-zero) represents current direction which will be auto reversed.
void TextInFrameWiggle(byte &dir, byte frmsz, char *frm){
  
  for (int i=0, j=0; i<frmsz; i++){
    if (frm[i]!=' '){ // find the 1st non-space character incl. 0
      if (dir){ // backward
        if (i){
          do {frm[i-1]=frm[i];} while (frm[i++]);
          return;
        }
        else dir=0;
      }
      // forward
      j=i;
      while (frm[j++]);
      if (j-i==frmsz) return; // means no-leading-space string occupies entire frame
      if (j==frmsz){ // time to turnaround
        --i;
        dir=1;
        continue;
      }
      do {frm[j]=frm[j-1];} while (--j!=i);
      frm[j]=' ';
      return;
    }
  }
}
void loop() {
  ArduinoOTA.handle();
  u8g2.clearBuffer();          // clear the internal memory
  u8g2.setFont(u8g2_font_8x13B_mf); // choose a suitable font
  
  TextInFrameWiggle(dir1, 17, str1); // ******** intended for a wiggling string on display
  
  u8g2.drawStr(0,10,str1);  // write something to the internal memory
  IPAddress myip= WiFi.localIP();
  String sFullip = String(myip[0]) + "." + myip[1] + "." + myip[2] + "." + myip[3];
  u8g2.drawStr(0,28,sFullip.c_str());  // write something to the internal memory
    
  u8g2.sendBuffer();          // transfer internal memory to the display
  delay(1);  
}