有一天突發奇想想弄個不用調整的時鐘,還要OLED顯示的因此製作了這個專題
#clock
#NTP
#網路時鍾
#時鐘
#OLED
#SSD1306
網路時鍾
這個程式實驗過可以使用在D1 mini 的模組
0.96”白色OLED I2C 位址0x3C
| |
D1 mini ESP8266
|
小鄭那裏買的
|
ESP8266_oled_ssd1306_master.zip
|
Oled 函數庫
|
Time 函數庫
|
Pin
Pin
|
Function
|
ESP-8266 Pin
|
TX
|
TXD
|
TXD
|
RX
|
RXD
|
RXD
|
A0
|
Analog input, max 3.3V input
|
A0
|
D0
|
IO
|
GPIO16
|
D1
|
IO, SCL
|
GPIO5
|
D2
|
IO, SDA
|
GPIO4
|
D3
|
IO,10k Pull-up
|
GPIO0
|
D4
|
IO, 10k pull-up, BUILTIN_LED
|
GPIO2
|
D5
|
IO, SCK
|
GPIO14
|
D6
|
IO, MISO
|
GPIO12
|
D7
|
IO, MOSI
|
GPIO13
|
D8
|
IO,10k pull-down, SS
|
GPIO15
|
G
|
Ground
|
GND
|
5V
|
5V
|
–
|
3V3
|
3.3V
|
3.3V
|
RST
|
Reset
|
RST
|
程式碼如下:
//#include
// OLED 網路時鐘 0.96“ 白色 位址0x3c
//
/* 網路時鐘,配合4位顯示LED範例
* 程式整理:Jason--> 2018-03-05 by lee chin Wei append I2C LCD
* http://blog.geeks.tw
*
* 本範例要配合 Paul Stoffregen寫的Time函式庫:
* https://github.com/PaulStoffregen/Time
*/
#include
#include
#include
//#include // "
#include // IIC communication I2C使用的函數
//#include
//#include
#include "SSD1306.h" // alias for `#include "SSD1306Wire.h"`
SSD1306 display(0x3c, D2, D1); // D1 mini SDA: D2 , SCL : D1 設定I2C pin
//#define CLK D6 //CLK pin,可自行決定接到哪個PIN
//#define DIO D7 //DIO pin,可自行決定接到哪個PIN
//TM1637 tm1637(CLK,DIO);
//LiquidCrystal_I2C lcd(0x3f,16,2); // Check I2C address of LCD, normally 0x27 or 0x3F
int point_flag =0;
const char ssid[] = "your network SSID"; // your network SSID (name)
const char pass[] = "your passwork"; // your network password
char daysOfTheWeek[7][12] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
String date;
String t;
const char * days[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"} ;
//const char * months[] = {"Jan", "Feb", "Mar", "Apr", "May", "June", "July", "Aug", "Sep", "Oct", "Nov", "Dec"} ;
const char * months[] = {"01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"} ;
const char * ampm[] = {"AM", "PM"} ;
// NTP Server:
static const char ntpServerName[] = "us.pool.ntp.org";
const int timeZone = 8; //台灣時區+8
int hourH = 0; //
int hourL = 0; //
int minH = 0; //
int minL = 0; //
int secH = 0; //
int secL = 0; //
int monH = 0;
int monL = 0;
int dayH = 0;
int dayL = 0;
int dayOfWeek = 0;
int cnt = 0;
//建立與NTP的連線
WiFiUDP Udp;
unsigned int localPort = 8888; // local port to listen for UDP packets
time_t getNtpTime();
void setup()
{
// Initialising the UI will init the display too.
display.init();
display.flipScreenVertically();
display.setFont(ArialMT_Plain_10);
// tm1637.init();
// tm1637.set(BRIGHT_TYPICAL); //BRIGHT_TYPICAL = 2,BRIGHT_DARKEST = 0,BRIGHTEST = 7;
// tm1637.display(0,0); //設定每一位燈號顯示的內容,參數1:燈號,參數2:顯示的數字
// tm1637.display(1,0);
// tm1637.display(2,0);
// tm1637.display(3,0);
// Wire.begin(D2,D1); // D1 mini SDA D2 , SCL D1 一定要加這一行還可以正常顯示出來 (0,2); //sda=0 | D3, scl=2 | D4
// lcd.backlight();
// lcd.clear();
// lcd.home(); // At column=0, row=0
Serial.begin(115200);
while (!Serial) ; // Needed for Leonardo only
delay(250);
//建立WiFi連線
Serial.println("NTP 網路時鐘");
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.print("IP number assigned by DHCP is ");
Serial.println(WiFi.localIP());
Serial.println("Starting UDP");
Udp.begin(localPort);
Serial.print("Local port: ");
Serial.println(Udp.localPort());
Serial.println("waiting for sync");
setSyncProvider(getNtpTime);
setSyncInterval(300);
}
time_t prevDisplay = 0; // 記錄上一次的時間,如果相同,LED就不用更新
void loop()
{
if (timeStatus() != timeNotSet) {
if (now() != prevDisplay) { //時間變化就顯示
prevDisplay = now(); //把目前時間丟給prevDisplay
// Serial.println(now());
digitalClockDisplay(); //呼叫顯示時間的副程式
}
}
}
void digitalClockDisplay()
{
// lcd.home(); // At column=0, row=0
//設定每一位燈號顯示的內容,參數1:燈號,參數2:顯示的數字
// tm1637.display(0,hour() / 10);
// tm1637.display(1,hour() % 10);
// tm1637.display(2,minute() / 10);
// tm1637.display(3,minute() % 10);
//==============================================
// now format the Time variables into strings with proper names for month, day etc
date = String(year())+"/"+String(months[month()-1])+"/"+String(day())+" "+String(days[weekday()-1]);
// date += days[weekday()-1];
// date += ", ";
// date += months[month()-1];
// date += " ";
// date += day();
// date += ", ";
// date += year();
// format the time to 12-hour format with AM/PM and no seconds
t = String(hour())+":"+twoDigits(minute())+":"+twoDigits(second());
// t += String(hour());
// t += ":";
// if(minute() < 10) // add a zero if minute is under 10
// t += "0";
// t += String( minute());
// t += ":";
// if (second()<10 span="">10>
// t +="0";
// t += String(second());
// t += ampm[isPM(local)];
// Font Demo1
// create more fonts at http://oleddisplay.squix.ch/
display.clear();
display.setTextAlignment(TEXT_ALIGN_LEFT);
//顯示時和分之間的:,如果目前是顯示,就設定下次不顯示
if(point_flag){
// tm1637.point(POINT_OFF);
point_flag = 0;
}else{
// tm1637.point(POINT_ON);
// display.setTextAlignment(TEXT_ALIGN_LEFT);
display.setFont(ArialMT_Plain_10);
display.drawString(0, 0, "Prog by LEECW");
display.setFont(ArialMT_Plain_10);
display.drawString(0, 10,date);
point_flag = 1;
}
display.setFont(ArialMT_Plain_24);
display.drawString(0,32,t);
display.display();
}
// utility function for digital clock display: prints leading 0
String twoDigits(int digits){
if(digits < = 10) {
String i = '0'+String(digits);
return i;
}
else {
return String(digits);
}
}
/*-------- NTP 程式碼 ----------*/
const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets
time_t getNtpTime()
{
IPAddress ntpServerIP; // NTP server's ip address
while (Udp.parsePacket() > 0) ; // discard any previously received packets
Serial.println("Transmit NTP Request");
// get a random server from the pool
WiFi.hostByName(ntpServerName, ntpServerIP);
Serial.print(ntpServerName);
Serial.print(": ");
Serial.println(ntpServerIP);
sendNTPpacket(ntpServerIP);
uint32_t beginWait = millis();
while (millis() - beginWait < 1500) {
int size = Udp.parsePacket();
if (size > = NTP_PACKET_SIZE) {
Serial.println("Receive NTP Response");
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer
unsigned long secsSince1900;
// convert four bytes starting at location 40 to a long integer
secsSince1900 = (unsigned long)packetBuffer[40] << 24;
secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
secsSince1900 |= (unsigned long)packetBuffer[43];
return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
}
}
Serial.println("No NTP Response :-(");
return 0; // return 0 if unable to get the time
}
// send an NTP request to the time server at the given address
void sendNTPpacket(IPAddress &address)
{
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123); //NTP requests are to port 123
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}
沒有留言:
張貼留言