【项目1】多功能墨水屏新闻、天气台历(二)

【项目1】多功能墨水屏新闻、天气台历(一)_喜暖知寒的博客-CSDN博客ArduinoJson 、GxEPD2、Timezone​、U8g2、U8g2_for_Adafruit_GFX、Dht11​https://blog.csdn.net/qq_41650023/article/details/124586018?spm=1001.2014.3001.5501


目录

NTP.h

定义

initNTP():Login to WiFi network and assign the time sync provider

getNTPTime():NTP Time Provider Code

sendNTPpacket():Send an NTP request to the time server at the given address

get_weather()、updatetime()、hitokoto()、newsdisplay()、gettem()

get_weather()

updatetime()

hitokoto()一言

newsdisplay()新闻

gettem()温湿度


开始看loop()函数中的第二步,initNTP()函数,定义在NTP.h文件中。

NTP.h

定义

#include <Arduino.h>
#include <TimeLib.h>
#include <WiFiUdp.h>

#define LOCALPORT     5000 // Local port to listen for UDP packets
#define NTP_PACKET_SIZE 48 // NTP time stamp is in the first 48 bytes of the message

// A UDP instance to let us send and receive packets over UDP
WiFiUDP udp;

byte packetBuffer[NTP_PACKET_SIZE]; // Buffer to hold incoming and outgoing packets

// Don't hardwire the IP address or we won't get the benefits of the time server pool.
const char *ntpServerName ;//= "time.windows.com";//"1.cn.pool.ntp.org";
IPAddress timeServerIP(120,25,108,11);  //ONENET -- NTP
//IPAddress timeServerIP(183,230,40,42);  //ONENET -- NTP

这个文件看起来不像是作者写的,本文件定义比较规范。

TimerLibGitHub - PaulStoffregen/Time: Time library for Arduino

initNTP():Login to WiFi network and assign the time sync provider

// Login to WiFi network and assign the time sync provider
//登录WiFi网络并指定时间同步提供商
void initNTP() {

  // Login suceeded so set UDP local port
  //登录成功,因此设置UDP本地端口
  udp.begin(LOCALPORT);        //初始化WiFiUDP库和网络设置,启动WiFiUDP套接字,侦听本地端口。

  // Set the time provider to NTP
  //将时间提供程序设置为NTP 
  setSyncProvider(getNTPTime);
}

getNTPTime():NTP Time Provider Code

// NTP Time Provider Code
time_t getNTPTime() {

  int attempts = 10;

  // Try multiple attempts to return the NTP time
  //尝试多次返回NTP时间
  while (attempts--) {

    // Get a server from the pool
    if(ntpServerName != NULL){
        WiFi.hostByName(ntpServerName, timeServerIP);    //从网站名获取IP地址
    }
    Serial.printf("Time server IP address: ");
    Serial.println(timeServerIP);

    while (udp.parsePacket() > 0); // Discard any previously received packets
                                   // 检查是否有UDP数据包传入,返回值数据包大小

    Serial.println("Transmitted NTP Request");
    sendNTPpacket(timeServerIP);

    uint32_t beginWait = millis();        //返回运行毫秒数
    while (millis() - beginWait < 1500) {
      int size = udp.parsePacket();
      if (size >= NTP_PACKET_SIZE) {
        Serial.println("Received 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
        //将从位置40开始的四个字节转换为长整数 
        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("Got the time");

        return secsSince1900 - 2208988800UL;
      }
      delay(10);
    }
    Serial.println("Retrying NTP request");
    delay(4000);
  }
  Serial.println("No NTP Response");
  return 0;
}

sendNTPpacket():Send an NTP request to the time server at the given address


// Send an NTP request to the time server at the given address
//向指定地址的时间服务器发送NTP请求 
unsigned long sendNTPpacket(IPAddress& address) {

  // Set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE);

  // Initialize values needed to form NTP request
  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();
}

get_weather()、updatetime()、hitokoto()、newsdisplay()、gettem()

get_weather()定义在disolayCode文件中。

get_weather()

图像定义在ImageData.c中,通过ImageData.h声明引用。

主要是右侧日期下方部分的显示。

/*天气信息*/
void get_weather(void){
    String tubiao = actual.weather_name;
    Serial.println(tubiao);
    if(tubiao=="多云"||tubiao=="晴间多云"||tubiao=="大部多云"){
      display.drawInvertedBitmap(280, 15, duoyun, 128, 128, GxEPD_BLACK);//画图
    }else if(tubiao=="晴"){
      display.drawInvertedBitmap(280, 15, qing, 128, 128, GxEPD_BLACK);//画图
    }else if(tubiao=="阴"){
      display.drawInvertedBitmap(280, 15, yin, 128, 128, GxEPD_BLACK);//画图
    }else if(tubiao=="阵雨"){
      display.drawInvertedBitmap(280, 15, zhenyu, 128, 128, GxEPD_BLACK);//画图
    }else if(tubiao=="雷阵雨"){
      display.drawInvertedBitmap(280, 15, leizhenyu, 128, 128, GxEPD_BLACK);//画图
    }else if(tubiao=="雷阵雨伴有冰雹"){
      display.drawInvertedBitmap(280, 15, leizhenyubanyoubingbao, 128, 128, GxEPD_BLACK);//画图
    }else if(tubiao=="小雨"){
      display.drawInvertedBitmap(280, 15, xiaoyu, 128, 128, GxEPD_BLACK);//画图
    }else if(tubiao=="中雨"){
      display.drawInvertedBitmap(280, 15, zhongyu, 128, 128, GxEPD_BLACK);//画图
    }else if(tubiao=="大雨"){
      display.drawInvertedBitmap(280, 15, dayu, 128, 128, GxEPD_BLACK);//画图
    }else if(tubiao=="暴雨"||tubiao=="大暴雨"||tubiao=="特大暴雨"){
      display.drawInvertedBitmap(280, 15, baoyu, 128, 128, GxEPD_BLACK);//画图
    }else if(tubiao=="冻雨"){
      display.drawInvertedBitmap(280, 15, dongyu, 128, 128, GxEPD_BLACK);//画图
    }else if(tubiao=="雨夹雪"){
      display.drawInvertedBitmap(280, 15, yujiaxue, 128, 128, GxEPD_BLACK);//画图
    }else if(tubiao=="阵雪"){
      display.drawInvertedBitmap(280, 15, zhenxue, 128, 128, GxEPD_BLACK);//画图
    }else if(tubiao=="小雪"){
      display.drawInvertedBitmap(280, 15, xiaoxue, 128, 128, GxEPD_BLACK);//画图
    }else if(tubiao=="中雪"){
      display.drawInvertedBitmap(280, 15, zhongxue, 128, 128, GxEPD_BLACK);//画图
    }else if(tubiao=="大雪"){
      display.drawInvertedBitmap(280, 15, daxue, 128, 128, GxEPD_BLACK);//画图
    }else if(tubiao=="暴雪"){
      display.drawInvertedBitmap(280, 15, baoxue, 128, 128, GxEPD_BLACK);//画图
    }else if(tubiao=="浮尘"){
      display.drawInvertedBitmap(280, 15, fuchen, 128, 128, GxEPD_BLACK);//画图
    }else if(tubiao=="扬沙"||tubiao=="沙尘暴"||tubiao=="强沙尘暴"){
      display.drawInvertedBitmap(280, 15, shachenbao, 128, 128, GxEPD_BLACK);//画图
    }else if(tubiao=="雾"){
      display.drawInvertedBitmap(280, 15, dawu, 128, 128, GxEPD_BLACK);//画图
    }else if(tubiao=="霾"){
      display.drawInvertedBitmap(280, 15, mai, 128, 128, GxEPD_BLACK);//画图
    }else if(tubiao=="未知"){
      display.drawInvertedBitmap(280, 15, weizhi, 128, 128, GxEPD_BLACK);//画图
    }
    
    /*位置+温度*/
  display.drawInvertedBitmap(280, 128, weizhi, 32, 28, GxEPD_RED);//画图
  u8g2Fonts.setCursor(312, 150);
  u8g2Fonts.setFont(chinese_city_gb2312);
  u8g2Fonts.setForegroundColor(GxEPD_BLACK);  // 设置前景色
  u8g2Fonts.setBackgroundColor(GxEPD_WHITE);  // 设置背景色
  u8g2Fonts.print(String(actual.city));
//  u8g2Fonts.setCursor(283,222);
    u8g2Fonts.setCursor(272,242);
    u8g2Fonts.print("今天");
    u8g2Fonts.setCursor(272,262);
    u8g2Fonts.print("明天");
    u8g2Fonts.setCursor(272,282);
    u8g2Fonts.print("后天");
    String text_day0, text_night0, dn0_s;
    String text_day1, text_night1, dn1_s;
    String text_day2, text_night2, dn2_s;
    const char* dn0; const char* dn1; const char* dn2;

    if (strcmp(future.date0_text_day, future.date0_text_night) != 0) //今天
    {
      text_day0 = future.date0_text_day;
      text_night0 = future.date0_text_night;
      dn0_s = text_day0 + "转" + text_night0;
      dn0 = dn0_s.c_str();
      u8g2Fonts.setCursor(300, 242);
      u8g2Fonts.print(dn0);
    }
    else
    {
      dn0 = future.date0_text_night;
      u8g2Fonts.setCursor(300, 242);
      u8g2Fonts.print(dn0);
    }

    if (strcmp(future.date1_text_day, future.date1_text_night) != 0) //明天
    {
      text_day1 = future.date1_text_day;
      text_night1 = future.date1_text_night;
      dn1_s = text_day1 + "转" + text_night1;
      dn1 = dn1_s.c_str();
      u8g2Fonts.setCursor(300, 262);
      u8g2Fonts.print(dn1);
    }
    else
    {
      dn1 = future.date1_text_night;
      u8g2Fonts.setCursor(300, 262);
      u8g2Fonts.print(dn1);
    }

    if (strcmp(future.date2_text_day, future.date2_text_night) != 0) //后天
    {
      text_day2 = future.date2_text_day;
      text_night2 = future.date2_text_night;
      dn2_s = text_day2 + "转" + text_night2;
      dn2 = dn2_s.c_str();
      u8g2Fonts.setCursor(300, 282);
      u8g2Fonts.print(dn2);
    }
    else
    {
      dn2 = future.date2_text_night;
      u8g2Fonts.setCursor(300, 282);
      u8g2Fonts.print(dn2);
    }
  //显示高低温
    String  high0, high1, high2, low0, low1, low2, hl0_s, hl1_s, hl2_s;
    high0 = future.date0_high; high1 = future.date1_high; high2 = future.date2_high;
    low0 = future.date0_low; low1 = future.date1_low; low2 = future.date2_low;
    hl0_s = high0 + "/" + low0;
    hl1_s = high1 + "/" + low1;
    hl2_s = high2 + "/" + low2;
    const char* hl0 = hl0_s.c_str();
    const char* hl1 = hl1_s.c_str();
    const char* hl2 = hl2_s.c_str();
    u8g2Fonts.setCursor(373,242);
    u8g2Fonts.print(hl0);
    u8g2Fonts.setCursor(373,262);
    u8g2Fonts.print(hl1);
    u8g2Fonts.setCursor(373,282);
    u8g2Fonts.print(hl2);
  
}

updatetime()

#define STD_TIMEZONE_OFFSET +8 
/*get time*/

/*时间日期数字格式化*/
String pressNum(int num) {
    if (num < 10 )
      return "0" + String(num);
    else
      return String(num);
}


void updatetime() {
  String timedate,timetim="";
  int weekdays, days, months,years,minutes,hours; 
  TimeChangeRule *tcr;        // Pointer to the time change rule
  time_t utc = now();
  TimeChangeRule mySTD = {"", First,  Sun, Jan, 0, STD_TIMEZONE_OFFSET * 60};
  Timezone myTZ(mySTD, mySTD);
  time_t localTime = myTZ.toLocal(utc, &tcr);
  weekdays = weekday(localTime);
  Serial.print("周");
  Serial.println(weekdays);
//  if(weekdays!=7){
//    weekdays-=1;
//  }else{
//    weekdays=1;
//  }
  days = day(localTime);
  months = month(localTime);
  years = year(localTime);
  timedate+=String(pressNum(months)) ;
  timedate+= "月" ;
  
//  if(weekdays==0) weekdays=7;
  minutes =   minute(localTime);
  hours   =   hour(localTime) ;   //12 hour format use : hourFormat12(localTime)  isPM()/isAM()
  timetim="星期";
  if(weekdays==2)timetim+="一"; 
  else if(weekdays==3)timetim+="二"; 
  else if(weekdays==4)timetim+="三"; 
  else if(weekdays==5)timetim+="四"; 
  else if(weekdays==6)timetim+="五"; 
  else if(weekdays==7)timetim+="六"; 
  else if(weekdays==1)timetim+="天"; 
  timetim+=" ";
  timetim+=String(hours);
  timetim+=" 点 ";
  if(minutes<10){
    timetim+="0";
   }
  timetim+=String(minutes);
  Serial.print(String(years)+"-"+String(months)+"-"+String(days)+"-");
  Serial.println(timetim);
  
  if(days<10){
    display.drawInvertedBitmap(301, 144, ling, 48, 66, GxEPD_RED);//画图
    if(days==1){
      display.drawInvertedBitmap(349, 144, yi, 18, 66, GxEPD_RED);//画图
    }else if(days==2){
      display.drawInvertedBitmap(349, 144, er, 48, 66, GxEPD_RED);//画图
    }else if(days==3){
      display.drawInvertedBitmap(349, 144, san, 48, 66, GxEPD_RED);//画图
    }else if(days==4){
      display.drawInvertedBitmap(349, 144, si, 48, 66, GxEPD_RED);//画图
    }else if(days==5){
      display.drawInvertedBitmap(349, 144, wu, 48, 66, GxEPD_RED);//画图
    }else if(days==6){
      display.drawInvertedBitmap(349, 144, liu, 48, 66, GxEPD_RED);//画图
    }else if(days==7){
      display.drawInvertedBitmap(349, 144, qi, 48, 66, GxEPD_RED);//画图
    }else if(days==8){
      display.drawInvertedBitmap(349, 144, ba, 48, 66, GxEPD_RED);//画图
    }else if(days==9){
      display.drawInvertedBitmap(349, 144, jiu, 48, 66, GxEPD_RED);//画图
    }
    
  }else if(days>=10&&days<20){
      display.drawInvertedBitmap(301, 144, yi, 18, 66, GxEPD_RED);//画图
    if(days==10){
      display.drawInvertedBitmap(349, 144, ling, 48, 66, GxEPD_RED);//画图
    }else if(days==11){
      display.drawInvertedBitmap(349, 144, yi, 18, 66, GxEPD_RED);//画图
    }else if(days==12){
      display.drawInvertedBitmap(349, 144, er, 48, 66, GxEPD_RED);//画图
    }else if(days==13){
      display.drawInvertedBitmap(349, 144, san, 48, 66, GxEPD_RED);//画图
    }else if(days==14){
      display.drawInvertedBitmap(349, 144, si, 48, 66, GxEPD_RED);//画图
    }else if(days==15){
      display.drawInvertedBitmap(349, 144, wu, 48, 66, GxEPD_RED);//画图
    }else if(days==16){
      display.drawInvertedBitmap(349, 144, liu, 48, 66, GxEPD_RED);//画图
    }else if(days==17){
      display.drawInvertedBitmap(349, 144, qi, 48, 66, GxEPD_RED);//画图
    }else if(days==18){
      display.drawInvertedBitmap(349, 144, ba, 48, 66, GxEPD_RED);//画图
    }else if(days==19){
      display.drawInvertedBitmap(349, 144, jiu, 48, 66, GxEPD_RED);//画图
    }
  }else if(days>=20&&days<30){
    display.drawInvertedBitmap(301, 144, er, 48, 66, GxEPD_RED);//画图
    if(days==20){
      display.drawInvertedBitmap(349, 144, ling, 48, 66, GxEPD_RED);//画图
    }else if(days==21){
      display.drawInvertedBitmap(349, 144, yi, 18, 66, GxEPD_RED);//画图
    }else if(days==22){
      display.drawInvertedBitmap(349, 144, er, 48, 66, GxEPD_RED);//画图
    }else if(days==23){
      display.drawInvertedBitmap(349, 144, san, 48, 66, GxEPD_RED);//画图
    }else if(days==24){
      display.drawInvertedBitmap(349, 144, si, 48, 66, GxEPD_RED);//画图
    }else if(days==25){
      display.drawInvertedBitmap(349, 144, wu, 48, 66, GxEPD_RED);//画图
    }else if(days==26){
      display.drawInvertedBitmap(349, 144, liu, 48, 66, GxEPD_RED);//画图
    }else if(days==27){
      display.drawInvertedBitmap(349, 144, qi, 48, 66, GxEPD_RED);//画图
    }else if(days==28){
      display.drawInvertedBitmap(349, 144, ba, 48, 66, GxEPD_RED);//画图
    }else if(days==29){
      display.drawInvertedBitmap(349, 144, jiu, 48, 66, GxEPD_RED);//画图
    }
  }else{
      display.drawInvertedBitmap(301, 144, san, 48, 66, GxEPD_RED);//画图
    if(days==30){
      display.drawInvertedBitmap(349, 144, ling, 48, 66, GxEPD_RED);//画图
    }else if(days==31){
      display.drawInvertedBitmap(349, 144, yi, 18, 66, GxEPD_RED);//画图
    }
  }
  u8g2Fonts.setFont(chinese_city_gb2312);
  u8g2Fonts.setForegroundColor(GxEPD_BLACK);  // 设置前景色
  u8g2Fonts.setBackgroundColor(GxEPD_WHITE);  // 设置背景色
  u8g2Fonts.setCursor(300, 30);//标记:位置需要修改
  u8g2Fonts.print(timetim);
}

hitokoto()一言

void hitokoto(){
//  display.drawRect(0, 0, 38, 12,1);
  u8g2Fonts.setFont(chinese_city_gb2312);
  u8g2Fonts.setForegroundColor(GxEPD_RED);  // 设置前景色
  u8g2Fonts.setBackgroundColor(GxEPD_WHITE);  // 设置背景色
  u8g2Fonts.setCursor(42, 12);
  u8g2Fonts.print(String(yiyan.hitokoto));
  display.drawInvertedBitmap(0, 0, yiyanp, 38, 12, GxEPD_RED);//画图
  
}

newsdisplay()新闻

void newsdisplay(){
  display.drawLine(269, 25, 269, 296, 0);
  u8g2Fonts.setFont(chinese_city_gb2312);
  u8g2Fonts.setForegroundColor(GxEPD_BLACK);  // 设置前景色
  u8g2Fonts.setBackgroundColor(GxEPD_WHITE);  // 设置背景色
  if(udc%3==0){
    display.drawInvertedBitmap(75, 16, weibo, 32, 32, GxEPD_BLACK);//画图
    u8g2Fonts.setCursor(106,38);
    u8g2Fonts.print("微博热点");
  }else if(udc%3==1){
    display.drawInvertedBitmap(75, 16, toutiao, 32, 32, GxEPD_BLACK);//画图
    u8g2Fonts.setCursor(106,38);
    u8g2Fonts.print("央视新闻");
    
  }else{
    display.drawInvertedBitmap(75, 16, zhihu, 32, 32, GxEPD_BLACK);//画图
    u8g2Fonts.setCursor(106,38);
    u8g2Fonts.print("知乎热榜");
  }
  String news_title,tt="";
  for(int i=0;i<11;i++){            //11行
    u8g2Fonts.setCursor(4,60+i*22);
    news_title =String(xinwen.title[i]);
    if(news_title.length()>54){
       for(int j=0;j<54;j++){
         tt+=news_title[j];
       }
       u8g2Fonts.print(tt);
     }else{
      u8g2Fonts.print(news_title);
     }
    tt="";
  }
  
}

gettem()温湿度

dht11 DHT11;
void gettem(){
  DHT11.read(21);
  String temperature=String(DHT11.temperature)+"℃";
  String humidity = String(DHT11.humidity)+"%";
  u8g2Fonts.setFont(chinese_city_gb2312);
  u8g2Fonts.setForegroundColor(GxEPD_BLACK);  // 设置前景色
  u8g2Fonts.setBackgroundColor(GxEPD_WHITE);  // 设置背景色
  u8g2Fonts.setCursor(272,222);
  u8g2Fonts.print("室内");
  display.drawInvertedBitmap(312, 210, wendu, 16, 16, GxEPD_BLACK);//画图
  u8g2Fonts.setCursor(330,222);
  u8g2Fonts.print(temperature);
  display.drawInvertedBitmap(358, 210, shidu, 16, 16, GxEPD_BLACK);//画图
  u8g2Fonts.setCursor(376,222);
  u8g2Fonts.print(humidity);
}

不太会的地方        ①wifi配网        ②获取时间        ③WiFiUdp

学习吧,我的宝~ ~

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值