OLED世界时钟demo

本文演示通过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就可以看到世界时钟的效果: