NodeMcu arduino ESP8266 使用U8g2库 在096 oled 显示
提示:以下是本篇文章正文内容,下面案例可供参考
U8g2 是一个用于嵌入式设备的单色图形库。U8g2支持单色OLED和LCD,并支持如SSD1306等多种类型的OLED驱动。
U8g2源码的开源库地址:https://github.com/olikraus/u8g2
U8g2专为Arduino提供的方便安装的库地址:https://github.com/olikraus/U8g2_Arduin
U8g2库在loop中的通用写法是使用do{}while()的形式:
void loop(void) {
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_ncenB10_tr);
u8g2.drawStr(0,24,"Hello new World!");
} while ( u8g2.nextPage() );
//delay(1000);
}
setFont(font) 设置字体
font:u8g2的字体,比较常用的有u8g2_font_unifont_t_symbols(通常使用这个)和u8g2_font_wqy12_t_gb2312b(用于显示汉字)等
setFontMode(num) 设置字体背景颜色模式
num:启用(1)透明模式
num:禁用(0)透明模式
setDrawColor(color) 设置所有绘图函数的位值
color:0(显示RAM中的清晰像素值)
color:1(设置像素值)
color:2(异或模式)
u8g2.begin( ) //开始构造U8G2, 在setup()内使用。 特别说明:初始化在Arduino的环境。 配置OLED的显示模式initDiplay或者省电模式setPowerSave,或者重置(清屏)clearDisplay 。同时检测六个按钮程序(比如前进、后退、确认、上一级…)。如果没有,可以在里定义按钮事件的引脚,用GetMenuEvent函数来定义,来进入到用户想要的界面,详情就看userInterfaceMessage和GetMenuEvent函数。无返回值。
关联使用函数:initDispaly 、setPowersave、clearDisplay
u8g2.clear() // 清除缓冲区"Buffer"内的所有像素点
关联使用函数:print、home、clearBuffer
u8g2.clearBuffer() //清除内存中的所有缓冲区内的像素,而后可以用sendBuffer函数来把缓冲区“Buffer”在屏幕上显示出来,以便清屏。因这个过程是在微处理器中RAM里的副本"Buffer"中进行,标志“F”,所以sendBuffer也就是直接操作副本“Buffer”
void loop(void) {
u8g2.clearBuffer(); //清除当前Buffer内的像素
// 在Buffer内一些操作
u8g2.sendBuffer(); //发送Buffer内容到屏上
delay(1000);
u8g2.enableUTF8Print () //启用 UTF8字集,许可UniCode向print发送字符串。这个函数通常在begin()后调用。
关联使用函数:print、disableUTF8Print
u8g2.disableUTF8Print() //禁用 UTF8字集 (万国语字库),默认是开启的。关联使用函数:print 、enableUTF8Print
u8g2.clearDisplay() //清除显示中所有像素。此过程在begin()中调用。在程序中一般用不上,也是通过sendBuffer和clearBuffer函数显示出来,一样的处理方式。
关联使用函数:begin
u8g2.Print() //在入当前光标位置用当前设置的字体,来打印出(内容)。光标位置可以用setCursor函数。字体可以用setFont函数。
关联使用函数:print(U8x8)、enableUTF8Print、setFont、setCursor、
Arduino IDE 库 安装 U8g2,或者网盘下载加载库U8g2。
代码如下(示例):
#include
#include
#include
//定义了一个宏定义,用于延时显示每一次的画图,方便观察OLED的显示过程:
#define SEND_BUFFER_DISPLAY_MS(ms)\
U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ D5, /* data=*/ D6, /* reset=*/ U8X8_PIN_NONE); // All Boards without Reset of the Display
void setup(void) {
u8g2.begin();
}
void loop(void) {
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_ncenB10_tr);
u8g2.drawStr(0,24,"Hello new World!");
} while ( u8g2.nextPage() );
//delay(1000);
}
U8g2库各类画图函数测试实例 ,绘画线,点,图形,图标,图片
/************************************************************
===================U8g2库各类画图函数测试实例==================
Author:码农爱学习
Date: 2022/03/06
Version: V1.0
Blog: https://xxpcb.gitee.io/
BiliBili: https://space.bilibili.com/146899653
------------------------------------------------------------
硬件:ESP8266 NodeMCU + 12864 SSD1306 OLED显示屏(4pin IIC引脚)
接线:[ESP8266] --- [OLED]
3.3V --- VCC
G (GND) --- GND
D1(GPIO5)--- SCL
D2(GPIO4)--- SDA
************************************************************/
#include
#include
//#define SCL 5
//#define SDA 4
//
//U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /*clock=*/SCL, /*data=*/SDA, /*reset=*/U8X8_PIN_NONE); // All Boards without Reset of the Display
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ D5, /* data=*/ D6, /* reset=*/ U8X8_PIN_NONE); // All Boards without Reset of the Display
#define SEND_BUFFER_DISPLAY_MS(ms)\
do {\
u8g2.sendBuffer(); \
delay(ms);\
}while(0);
void initOLED();
void testDrawPixelFun();
void testDrawLineFun();
void testDrawTriangleFun();
void testDrawRectangleFun();
void testDrawCircleFun();
void testDrawEllipseFun();
void testGlyphFun();
void testDrawStrFun();
void testDrawXBMFun();
void testDrawBattery();
void setup()
{
Serial.begin(9600);
initOLED();
}
void loop()
{
u8g2.firstPage();
do
{
testDrawPixelFun(); //画像素点测试
testDrawLineFun(); //画线测试
testDrawTriangleFun(); //画三角形测试
testDrawRectangleFun(); //画矩形测试
testDrawCircleFun(); //画圆测试
testDrawEllipseFun(); //画椭圆测试
testGlyphFun(); //画图标测试
testDrawStrFun(); //字符、汉字、变量显示测试
u8g2.setFont(u8g2_font_unifont_t_symbols);
testDrawBattery(); //画电池
testDrawXBMFun(); //画自定义图片
} while (u8g2.nextPage());
delay(1000);
}
void initOLED()
{
u8g2.begin();
u8g2.setFont(u8g2_font_unifont_t_symbols);
}
画像素点
//画像素点-填充屏幕
void testDrawPixelToFillScreen()
{
int t = 1000;
u8g2.clearBuffer();
for (int j = 0; j < 64; j++)
{
for (int i = 0; i < 128; i++)
{
u8g2.drawPixel(i, j);
}
}
SEND_BUFFER_DISPLAY_MS(t);
}
//画直线
//画直线
void testDrawLine()
{
int t = 500;
u8g2.clearBuffer();
u8g2.drawStr(33, 14, "drawLine");
u8g2.drawLine(0, 0, 127, 63);
SEND_BUFFER_DISPLAY_MS(t);
u8g2.drawLine(0, 0, 127, 0);
SEND_BUFFER_DISPLAY_MS(t);
u8g2.drawLine(32, 15, 127, 15);
SEND_BUFFER_DISPLAY_MS(t);
u8g2.drawLine(33, 16, 127, 16);
SEND_BUFFER_DISPLAY_MS(t);
u8g2.drawLine(127, 0, 127, 15);
SEND_BUFFER_DISPLAY_MS(t);
u8g2.drawLine(127, 16, 127, 63);
SEND_BUFFER_DISPLAY_MS(t);
}
//画空心圆角矩形
//画空心圆角矩形
void testDrawRFrame()
{
int t = 500;
int x = 16;
int y = 32;
int w = 50;
int h = 20;
int r = 3;
u8g2.clearBuffer();
u8g2.drawStr(0, 15, "drawRFrame");
u8g2.drawRFrame(x, y, w, h, r);
SEND_BUFFER_DISPLAY_MS(t);
u8g2.drawRFrame(x+w+5, y-10, w-20, h+20, r);
SEND_BUFFER_DISPLAY_MS(t);
}
画空心圆
drawEllipse(x,y,rx,ry,opt) 绘制一个空心椭圆
drawFilledEllipse(x,y,rx,ry,opt) 绘制一个实心椭圆
//画空心圆
void testDrawCircle()
{
int t = 500;
int stx = 0; //画图起始x
int sty = 16; //画图起始y
int with = 16;//一个图块的间隔
int r = 15; //圆的半径
u8g2.clearBuffer();
u8g2.drawStr(0, 15, "drawCircle");
u8g2.drawCircle(stx, sty - 1 + with, r, U8G2_DRAW_UPPER_RIGHT); //右上
SEND_BUFFER_DISPLAY_MS(t);
u8g2.drawCircle(stx + with, sty, r, U8G2_DRAW_LOWER_RIGHT); //右下
SEND_BUFFER_DISPLAY_MS(t);
u8g2.drawCircle(stx - 1 + with * 3, sty - 1 + with, r, U8G2_DRAW_UPPER_LEFT); //左上
SEND_BUFFER_DISPLAY_MS(t);
u8g2.drawCircle(stx - 1 + with * 4, sty, r, U8G2_DRAW_LOWER_LEFT); //左下
SEND_BUFFER_DISPLAY_MS(t);
u8g2.drawCircle(stx - 1 + with * 2, sty - 1 + with * 2, r, U8G2_DRAW_ALL);//整个圆
SEND_BUFFER_DISPLAY_MS(t);
}
字符串、汉字和变量显示
drawStr(x,y,string) 绘制一个字符串
x,y起点坐标
string字符串
//字符串/文字/变量显示测试
u8g2.enableUTF8Print();//enable UTF8
u8g2.setFont(u8g2_font_wqy12_t_gb2312b);//设置中文字符集
void testDrawStr()
{
int t = 1000;
u8g2.clearBuffer();
u8g2.drawStr(0, 14, "drawStr / print");
SEND_BUFFER_DISPLAY_MS(t);
u8g2.drawStr(0, 32, "~!@#$%^&*()_+");
SEND_BUFFER_DISPLAY_MS(t);
u8g2.enableUTF8Print();//enable UTF8
u8g2.setFont(u8g2_font_wqy12_t_gb2312b);//设置中文字符集
u8g2.setCursor(0, 48);
u8g2.print("码农爱学习");
SEND_BUFFER_DISPLAY_MS(t);
int a = 234;
u8g2.setCursor(0, 64);
u8g2.print("int a = ");
u8g2.setCursor(40, 64);
u8g2.print(a);//显示变量
SEND_BUFFER_DISPLAY_MS(t);
}
画内置图标
drawGlyph(x,y,addr) 绘制U8g2内置的图标
x,y起点坐标
addr内置图标的地址
U8g2库内置了需要预先定义的图形,通过drawGlyp函数以及指定的地址,即可看OLED上显示对应的图标
void testGlyph()
{
int t = 1000;
u8g2.clearBuffer();
u8g2.drawStr(0, 14, "drawGlyph");
u8g2.drawGlyph(0, 32, 0x23f0);
SEND_BUFFER_DISPLAY_MS(t);
u8g2.drawGlyph(16, 32, 0x23f3);
SEND_BUFFER_DISPLAY_MS(t);
u8g2.drawGlyph(32, 32, 0x2603);
SEND_BUFFER_DISPLAY_MS(t);
u8g2.drawGlyph(48, 32, 0x2615);
SEND_BUFFER_DISPLAY_MS(t);
u8g2.drawGlyph(64, 32, 0x2618);
SEND_BUFFER_DISPLAY_MS(t);
}
画自定义图片
drawXBM(x,y,w,h,addr) 绘制一个实心矩形 (圆角)
x,y起点坐标
w,h图片的宽度和高度`
addr图片(数组)的地址
自定义图片的显示,需要先将图形转换为数组,可以使用如下工具进行图片到数组的转换:
https://tools.clz.me/image-to-bitmap-array
// width: 128, height: 48
const unsigned char bilibili[] U8X8_PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ... 省略若干行 };
void testDrawXBM()
{
int t = 1000;
u8g2.clearBuffer();
u8g2.drawStr(0, 14, "drawXBM");
u8g2.drawXBM(0, 16, 128, 48, bilibili);
SEND_BUFFER_DISPLAY_MS(t);
}
工作电压:3V~5.5V
I2C介面 (位址:0x30)
驱动IC:SSD1306
OLED屏幕分为单色和双色两种
GND 电源地
VCC 电源正(3~5.5V)
SCL/SCK OLED 的 D5 脚,在 IIC 通信中为时钟管脚
SDA OLED 的 D6 脚,在 IIC 通信中为数据管
分辨率为 128*64
/************************************************************
===================ESP8266简易WIFI天气时钟==================
Author:码农爱学习
Date: 2022/05/28
Version: V1.0
Blog: https://xxpcb.gitee.io/
BiliBili: https://space.bilibili.com/146899653
图文教程:https://www.bilibili.com/read/cv16758967
------------------------------------------------------------
硬件:ESP8266 NodeMCU + 12864 SSD1306 OLED显示屏(4pin IIC引脚)
接线:[ESP8266] --- [OLED]
3.3V --- VCC
G (GND) --- GND
D1(GPIO5)--- SCL
D2(GPIO4)--- SDA
************************************************************/
#include
#include
#include
#include
#include
#include
#include
#define SCL 5
#define SDA 4
#define HTTP_TIMEOUT 5000
#define CAPACITY (JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(5) + 70)
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /*clock=*/D5, /*data=*/D6, /*reset=*/U8X8_PIN_NONE); // All Boards without Reset of the Display
//---------------WIFI信息------------------------------
const char ssid[] = "dajiating"; //WiFi名(<---------替换为自己的)
const char pass[] = "DJT13619252979"; //WiFi密码(<---------替换为自己的)
//-----------------------------------------------------
WiFiClient client;
HTTPClient http;
void initOLED();
void initWiFi();
void initNTP();
//--------- weather ---------------
const char* host = "api.seniverse.com"; // 将要连接的服务器地址
const int httpPort = 80; // 将要连接的服务器端口
//心知天气HTTP请求所需信息
String reqUserKey = "SgPyzsfk1cq-k031x"; // 私钥(<---------替换为自己的)
String reqLocation = "Xian"; // 城市
String reqUnit = "c"; // 摄氏/华氏
//建立心知天气API当前天气请求资源地址
String reqRes = "/v3/weather/now.json?key=" + reqUserKey +
+ "&location=" + reqLocation +
"&language=en&unit=" + reqUnit;
//--------网络校时的相关配置---------
#define timeZone (8) //时区设置,采用东8区
#define NTP_PACKET_SIZE (48) // NTP时间在消息的前48个字节里
static const char ntpServerName[] = "ntp1.aliyun.com"; //NTP服务器,使用阿里云
byte packetBuffer[NTP_PACKET_SIZE]; // 输入输出包的缓冲区
unsigned int localPort = 8888; // 用于侦听UDP数据包的本地端口
boolean isNTPConnected = false;
WiFiUDP Udp;
//----------时间、天气信息自定义结构体--------
typedef struct
{
int tm_year;
int tm_mon;
int tm_mday;
int tm_hour;
int tm_min;
int tm_sec;
int tm_week;
}rtc_time_t;
typedef struct
{
String weather; //天气字符串
int iconIdx; //天气对应的图标索引
int temp; //温度
}weather_info_t;
#define IOCN_OVERCAST 0
#define IOCN_CLOUDY 1
#define IOCN_RAIN 2
#define IOCN_SUNNY 3
char* icon_index[4]={"@","A","C","E"};//图标在天气字库里分别代表 阴(0x40),云,雨,晴
typedef struct
{
int XinZhi_code;
int icon_idx;
}weather_code_t;
weather_code_t weather_icon_table[4] = {
{0, IOCN_SUNNY},
{4, IOCN_CLOUDY},
{9, IOCN_OVERCAST},
{13, IOCN_RAIN}
};
//天气相关变量
String g_strWeather = "";
String g_strUpdateTime = "";
int g_iTemperature = 18;
int g_iCode = -1;
int g_iIdx = -1;
//==============================seup&loop=============================
void setup()
{
Serial.begin(9600);
Serial.println("NTP time and WiFi Weather test");
initOLED();
initWiFi();
initNTP();
}
void loop()
{
static int times = 0;
//Serial.println(times);
if ((times == 0) && (WiFi.status() == WL_CONNECTED))
{
// 向心知天气服务器服务器请求信息并对信息进行解析
httpRequest(reqRes);
}
updateShowTime();
if (++times >= 6000)
{
times = 0;
}
delay(300);
}
//======================================================================
void initOLED()
{
u8g2.begin();
u8g2.enableUTF8Print();//用于汉字显示
u8g2.setFont(u8g2_font_wqy14_t_gb2312);
u8g2.clearBuffer();
u8g2.setCursor(0, 14);
u8g2.print("等待WiFi连接");
u8g2.setCursor(0, 30);
u8g2.print("WiFi connection...");
u8g2.sendBuffer();
}
void initWiFi()
{
Serial.print("Connecting WiFi...");
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void initNTP()
{
Udp.begin(localPort);
setSyncProvider(getNtpTime);
setSyncInterval(300); //每300秒同步一次时间
}
/*-------- 网络天气 代码 ----------*/
// 向心知天气服务器服务器请求信息并对信息进行解析
void httpRequest(String reqRes)
{
WiFiClient client;
// 建立http请求信息
String httpRequest = String("GET ") + reqRes + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n";
Serial.println("");
Serial.print("Connecting to ");
Serial.print(host);
// 尝试连接服务器
if (client.connect(host, 80))
{
Serial.println(" Success!");
// 向服务器发送http请求信息
client.print(httpRequest);
Serial.println("Sending request: ");
Serial.println(httpRequest);
// 获取并显示服务器响应状态行
String status_response = client.readStringUntil('\n');
Serial.print("status_response: ");
Serial.println(status_response);
// 使用find跳过HTTP响应头
if (client.find("\r\n\r\n"))
{
Serial.println("Found Header End. Start Parsing.");
}
// 利用ArduinoJson库解析心知天气响应信息
parseInfo(client);
}
else
{
Serial.println(" connection failed!");
}
//断开客户端与服务器连接工作
client.stop();
}
// 利用ArduinoJson库解析心知天气响应信息
void parseInfo(WiFiClient client)
{
const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + 2 * JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6) + 230;
DynamicJsonDocument doc(capacity);
deserializeJson(doc, client);
Serial.println(doc.as<String>());
JsonObject result0 = doc["results"][0];
JsonObject result0_now = result0["now"];
// 通过串口监视器显示以上信息
g_strWeather = result0_now["text"].as<String>();// "Sunny"
g_iCode = result0_now["code"].as<int>();// "0"
g_iTemperature = result0_now["temperature"].as<int>();// "32"
g_strUpdateTime = result0["last_update"].as<String>();// "2020-06-02T14:40:00+08:00"
Serial.println(F("======Weahter Now======="));
Serial.print(F("Weather Now: "));
Serial.print(g_strWeather);
Serial.print(F(" -> "));
Serial.println(g_iCode);
Serial.print(F("Temperature: "));
Serial.println(g_iTemperature);
Serial.print(F("Last Update: "));
Serial.println(g_strUpdateTime);
Serial.println(F("========================"));
for (int i=0; i< 4; i++)
{
if(g_iCode == weather_icon_table[i].XinZhi_code)
{
g_iIdx = weather_icon_table[i].icon_idx;
break;
}
}
}
void my_strcat(char* srcstr, int t)
{
char str_tmp[5];
if(t < 10)
{
strcat(srcstr, "0");
}
itoa(t, str_tmp, 10);
strcat(srcstr, str_tmp);
}
void testShowTimeAndWeather(rtc_time_t &now_time, weather_info_t &weather_info)
{
u8g2.clearBuffer();
int tm_year = now_time.tm_year;
int tm_month = now_time.tm_mon;
int tm_day = now_time.tm_mday;
int tm_hour = now_time.tm_hour;
int tm_minute = now_time.tm_min;
int tm_sec = now_time.tm_sec;
int tm_week = now_time.tm_week;
//时分
char str_big_time[] = "";
my_strcat(str_big_time, tm_hour);
strcat(str_big_time,":");
my_strcat(str_big_time, tm_minute);
u8g2.setFont(u8g2_font_logisoso24_tf);
u8g2.drawStr(0, 30, str_big_time);
//秒
char str_small_sec[] = "";
my_strcat(str_small_sec, tm_sec);
u8g2.setFont(u8g2_font_wqy14_t_gb2312);
u8g2.drawStr(73, 30, str_small_sec);
//日期
char str_date[] = "";
char str_temp[6];
itoa(tm_year,str_temp,10);
strcat(str_date,str_temp);
strcat(str_date,"-");
my_strcat(str_date, tm_month);
strcat(str_date,"-");
my_strcat(str_date, tm_day);
u8g2.drawStr(0, 47, str_date);
u8g2.setCursor(0, 63);
u8g2.print("星期");
switch (tm_week)
{
case 1: u8g2.print("日"); break;
case 2: u8g2.print("一"); break;
case 3: u8g2.print("二"); break;
case 4: u8g2.print("三"); break;
case 5: u8g2.print("四"); break;
case 6: u8g2.print("五"); break;
case 7: u8g2.print("六"); break;
default: break;
}
u8g2.setCursor(60, 63);
u8g2.print("西安");
//分割线
u8g2.drawLine(90, 0, 90, 63);
//天气
if (weather_info.iconIdx<0 || weather_info.iconIdx>3) //没有对应的天气图标
{
Serial.print("no icon for weather: ");
Serial.println(weather_info.weather);
}
else
{
u8g2.setFont(u8g2_font_open_iconic_weather_4x_t );
u8g2.drawStr(96, 34, icon_index[weather_info.iconIdx]);
}
char temperature_tmp[25];
itoa(weather_info.temp, temperature_tmp, 10);
strcat(temperature_tmp,"℃");
u8g2.setFont(u8g2_font_wqy16_t_gb2312);
u8g2.setCursor(96, 55);
u8g2.print(temperature_tmp);
u8g2.sendBuffer();
}
void updateShowTime()
{
rtc_time_t now_time;
now_time.tm_year = year();
now_time.tm_mon = month();
now_time.tm_mday = day();
now_time.tm_hour = hour();
now_time.tm_min = minute();
now_time.tm_sec = second();
now_time.tm_week = weekday();
weather_info_t weather_info;
weather_info.weather = g_strWeather;
weather_info.iconIdx = g_iIdx;
weather_info.temp = g_iTemperature;
testShowTimeAndWeather(now_time, weather_info);
}
/*-------- NTP 代码 ----------*/
time_t getNtpTime()
{
IPAddress ntpServerIP; // NTP服务器的地址
while(Udp.parsePacket() > 0); // 丢弃以前接收的任何数据包
Serial.println("Transmit NTP Request");
// 从池中获取随机服务器
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");
isNTPConnected = true;
Udp.read(packetBuffer, NTP_PACKET_SIZE); // 将数据包读取到缓冲区
unsigned long secsSince1900;
// 将从位置40开始的四个字节转换为长整型,只取前32位整数部分
secsSince1900 = (unsigned long)packetBuffer[40] << 24;
secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
secsSince1900 |= (unsigned long)packetBuffer[43];
Serial.println(secsSince1900);
Serial.println(secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR);
return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
}
}
Serial.println("No NTP Response :-("); //无NTP响应
isNTPConnected = false;
return 0; //如果未得到时间则返回0
}
// 向给定地址的时间服务器发送NTP请求
void sendNTPpacket(IPAddress &address)
{
memset(packetBuffer, 0, NTP_PACKET_SIZE);
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;
Udp.beginPacket(address, 123); //NTP需要使用的UDP端口号为123
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}