本文演示通过OLED显示一个时钟的例子,主要是ESP8266-oled库的使用。
需要的模块
零知ESP8266开发板
OLED SSD1306模块
接线很简单,I2C接口对应连接即可:
接好后实物图如下:
本次使用了OLED和WeatherStation相关的软件库,因此需要在库管理器中安装对应的库。
安装完成后,我们新建工程或打开附件的工程代码:
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <Ticker.h>
#include <JsonListener.h>
#include <SSD1306Wire.h>
#include <OLEDDisplayUi.h>
#include <Wire.h>
#include <WorldClockClient.h>
#include "icons.h"
#include "fonts.h"
/***************************
* Begin Settings
**************************/
// WIFI
const char* WIFI_SSID = "xx";
const char* WIFI_PWD = "xx";
// Setup
const int UPDATE_INTERVAL_SECS = 10 * 60; // Update every 10 minutes
// Display Settings
const int I2C_DISPLAY_ADDRESS = 0x3c;
const int SDA_PIN = D3;
const int SDC_PIN = D4;
// TimeClient settings
// Initialize the oled display for address 0x3c
// sda-pin=14 and sdc-pin=12
SSD1306Wire display(I2C_DISPLAY_ADDRESS, SDA_PIN, SDC_PIN);
OLEDDisplayUi ui ( &display );
/***************************
* End Settings
**************************/
//String timeZoneIds [] = {"America/New_York", "Europe/London", "Europe/Paris", "Australia/Sydney", ""};
//WorldClockClient worldClockClient("de", "CH", "E, dd. MMMMM yyyy", 4, timeZoneIds);
//
String timeZoneIds [] = {"America/New_York", "Europe/London", "Europe/Paris", "Australia/Sydney", "Asia/Shanghai"};
WorldClockClient worldClockClient("zh", "CN", "E, dd. MMMMM yyyy", 5, timeZoneIds);
// flag changed in the ticker function every 10 minutes
bool readyForUpdate = false;
String lastUpdate = "--";
Ticker ticker;
void updateData(OLEDDisplay *display) {
drawProgress(display, 50, "Updating Time...");
worldClockClient.updateTime();
drawProgress(display, 100, "Done...");
readyForUpdate = false;
delay(1000);
}
void drawProgress(OLEDDisplay *display, int percentage, String label) {
display->clear();
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(ArialMT_Plain_10);
display->drawString(64, 10, label);
display->drawProgressBar(10, 28, 108, 12, percentage);
display->display();
}
void drawClock(OLEDDisplay *display, int x, int y, int timeZoneIndex, String city, const uint8_t* icon) {
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(ArialMT_Plain_10);
display->drawString(x + 60, y + 5, city);
display->setFont(Crushed_Plain_36);
display->drawXbm(x, y, 60, 60, icon);
display->drawString(x + 60, y + 15, worldClockClient.getHours(timeZoneIndex) + ":" + worldClockClient.getMinutes(timeZoneIndex));
}
void drawFrame1(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
drawClock(display, x, y, 0, "New York", new_york_bits);
}
void drawFrame2(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
drawClock(display, x, y, 1, "London", london_bits);
}
void drawFrame3(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
drawClock(display, x, y, 2, "Paris", paris_bits);
}
void drawFrame4(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
drawClock(display, x, y, 3, "Sydney", sydney_bits);
}
void drawFrame5(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
drawClock(display, x, y, 4, "Beijing", beijing_bits);
}
void setReadyForWeatherUpdate() {
Serial.println("Setting readyForUpdate to true");
readyForUpdate = true;
}
// this array keeps function pointers to all frames
// frames are the single views that slide from right to left
FrameCallback frames[] = { drawFrame1, drawFrame2, drawFrame3, drawFrame4, drawFrame5};
int numberOfFrames = 5;
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println();
// initialize dispaly
display.init();
display.clear();
display.display();
//display.flipScreenVertically();
display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_CENTER);
display.setContrast(255);
WiFi.begin(WIFI_SSID, WIFI_PWD);
int counter = 0;
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
display.clear();
display.drawString(64, 10, "Connecting to WiFi");
display.drawXbm(46, 30, 8, 8, counter % 3 == 0 ? activeSymbol : inactiveSymbol);
display.drawXbm(60, 30, 8, 8, counter % 3 == 1 ? activeSymbol : inactiveSymbol);
display.drawXbm(74, 30, 8, 8, counter % 3 == 2 ? activeSymbol : inactiveSymbol);
display.display();
counter++;
}
ui.setTargetFPS(30);
// You can change this to
// TOP, LEFT, BOTTOM, RIGHT
ui.setIndicatorPosition(BOTTOM);
// Defines where the first frame is located in the bar.
ui.setIndicatorDirection(LEFT_RIGHT);
// You can change the transition that is used
// SLIDE_LEFT, SLIDE_RIGHT, SLIDE_TOP, SLIDE_DOWN
ui.setFrameAnimation(SLIDE_LEFT);
// Add frames
ui.setFrames(frames, numberOfFrames);
ui.setTimePerFrame(2*1000); // Setup frame display time to 10 sec
// Inital UI takes care of initalising the display too.
ui.init();
Serial.println("");
updateData(&display);
ticker.attach(UPDATE_INTERVAL_SECS, setReadyForWeatherUpdate);
}
void loop() {
if (readyForUpdate && ui.getUiState()->frameState == FIXED) {
updateData(&display);
}
int remainingTimeBudget = ui.update();
if (remainingTimeBudget > 0) {
// You can do some work here
// Don't do stuff if you are below your
// time budget.
delay(remainingTimeBudget);
}
}
完整代码:world_clock.7z(点击下载)
将代码验证并上传到零知-ESP8266上面,打开串口调试工具,可以看到如下结果:
然后OLED就可以看到世界时钟的效果: