【开源项目】用ESP32制作一个桌面天气预报站,2024年最新深入剖析原理

233 阅读7分钟

  Serial.println(" CONNECTED");   configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);

 // printLocalWeather();   }

void loop() {   if(WiFi.status() == WL_CONNECTED){     printLocalWeather();     }else{     Serial.println("WiFi  Disconnect");    } }


说明:本Demo实现了通过WiFi功能获取网络时间以及通过访问国家气象局提供的`http://www.weather.com.cn/datalcityinfo/101010100.html`来获取天气情况,本接口中“101010100"为城市代码。


**注意**:该例程需要下载ArduinoJson库,下载方式如下图:


![38d9c705f71229040a84a2e8c95ad803.png](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/7e29d2a65f41404289484337bfb5bb29~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1780324084&x-signature=z5UkaapNUfobKgcAlMr3ZhSObA8%3D)


![90678b39bae7d0aa2d8c3244f4172e58.png](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/5810337e9c34401b974ac6881e513823~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1780324084&x-signature=y7xp3zw%2Bfo%2BpuzX3KGTd409vrd0%3D)


##### 结果


![d89c8d2cf3f874057f4712a22379323c.png](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/694455fce64e40fe9a1b5d058b1a53a8~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1780324084&x-signature=uaUEgv6LdGBG2RK7MlUsLBFueNw%3D)


### 四、添加旋转太空人图片


#### 4.1 旋转太空人的动态图


其实是从动态图里面截取下来的4张图片  通过每100毫秒切换一张图片,达到旋转太空人的形态。


![e9d4144a43d5a396d3fcbeae61bd704d.png](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/d239f0ca32de41c3b5d463fb2c3151bd~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1780324084&x-signature=MgZ7oRPVJL50amb5OjEaI4JsMb8%3D)


#### 4.2 把图片转换成数组


![49d1709d92d79ccfaf195606410b3636.png](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/2beeeff136174f249e4c7aef7fe98f9a~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1780324084&x-signature=ORQBbR86TpFQzV6IlN2zPvxlhkw%3D)


#### 4.3 把图片的数组存放到`.h`文件下


![9a806cd8053237e9115dcad57a000b96.png](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/8149788122564308aaef9add21521d15~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1780324084&x-signature=1oMaPJriFI4mbok%2BhjS9fBRxHXg%3D)


#### 4.4 图片的使用代码如下



#include <DFRobot_GDL.h> #include "BMP.h"

#define TFT_DC  D2 #define TFT_CS  D6 #define TFT_RST D3 #define PICNUMBER 6

DFRobot_ST7789_240x240_HW_SPI screen(/dc=/TFT_DC,/cs=/TFT_CS,/rst=/TFT_RST);

void setup() {     screen.begin();

}

void loop() {   screen.drawPIC(/x=/0,/y=/124,/w=/124,/h=/124,/bitmap gImage_Bitmap=/( uint8_t*)gImage_black1);   delay(100);   screen.drawPIC(/x=/0,/y=/124,/w=/124,/h=/124,/bitmap gImage_Bitmap=/( uint8_t*)gImage_black2);   delay(100);   screen.drawPIC(/x=/0,/y=/124,/w=/124,/h=/124,/bitmap gImage_Bitmap=/( uint8_t*)gImage_black3);   delay(100);   screen.drawPIC(/x=/0,/y=/124,/w=/124,/h=/124,/bitmap gImage_Bitmap=/( uint8_t*)gImage_black4);   delay(100);   screen.drawPIC(/x=/0,/y=/124,/w=/124,/h=/124,/bitmap gImage_Bitmap=/( uint8_t*)gImage_black5);

}


#### 4.5 图片动态展示


![74c2b2c28c5ab73f4bd6d94926471f4d.png](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/deb5bde38038416089292df2e4499189~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1780324084&x-signature=dRcMGEYYhms5gir0lVcvTSVBGFI%3D)


### 五、把从网络上获取到的天气和时间信息显示在TFT屏幕


#### 5.1 python环境搭建


在使用setup.py脚本生成自定义字体之前,需要做如下准备:


* 登录网址`https://www.python.org/downloads/`,下载`python3.6`及以上版本;
* 安装完毕后,需要用下列命令安装python第三方依赖包:
* `pip3 install numpy`
* `pip install freetype-py`
* `pip install chardet`


#### 5.2 生成自定义字体


把ttf文件放在库文件的对应ttf文件夹下,这里我提供了一个ttf文件,供大家使用。链接获取[5]:


* 将TTF字体文件存放在ttf文件夹里,例如:SIMKAI.TTF(简体字 楷体)
*`text.txt`文件中输入你想生成的字符,例如:你好,世界!
* 打开`config.txt`文件,配置生成字体文件的名字前缀和字体大小


![f5718ecf93c305b076fd296a143f1a4a.png](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/6d28ae827e514b36b5013e9dbe09a0bf~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1780324084&x-signature=Q0gbCWMhRTonDXvnYE8%2FH%2FScW8Q%3D)


#### 5.3 在屏幕上显示


* 运行`setup.py`脚本,会在font文件夹生成一系列后缀名为`.h`的字体文件,并弹出一个`font.txt`的文本,再进行以下步骤,即可在屏上显示:你好,世界!
* 将font文件夹里的文件复制到`DFRobot_GDL\src\Fonts\Fonts`目录下;
* 将弹出的font.txt的内容粘贴到`DFRobot_GDL\src\Fonts\DFRobot_Font.h`文件中;
* 打开Arduino IDE,构造屏对象,如tft,调用`tft.setFont(&SIMKAIFont48pt)`;
* 调用`tft.println("你好,世界!")`,此时即可在屏上显示"你好,世界!"


![3a38d09aead9e297e54c0386890365db.png](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/4cf9839a5350407c9fb1151cababda89~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1780324084&x-signature=Dlt5p7NFaTAwTHGVPo422xr3LZQ%3D)


#### 5.4 显示天气和时间的代码如下



#include <DFRobot_GDL.h> #include <WiFi.h> #include <HTTPClient.h> #include <ArduinoJson.h> #include "BMP.h" HTTPClient http;

const char* ssid="dfrobotOffice"; const char* password="dfrobot2011"; const char* ntpServer = "pool.ntp.org"; const long gmtOffset_sec = 28800; const int daylightOffset_sec = 0; DynamicJsonDocument doc(1024); DynamicJsonDocument doc1(1024); #define TFT_DC  D2 #define TFT_CS  D6 #define TFT_RST D3 #define PICNUMBER 6

String weekDays[]={"周天", "周一", "周二","周三", "周四", "周五", "周六"};

DFRobot_ST7789_240x240_HW_SPI screen(/dc=/TFT_DC,/cs=/TFT_CS,/rst=/TFT_RST);

void setup() {   Serial.begin(115200);   screen.begin();

  Serial.printf("Connecting to %s",ssid);   WiFi.begin(ssid,password);   while(WiFi.status()!=WL_CONNECTED){     delay(500);     Serial.print(".");   }   Serial.println(" CONNECTED");   configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);

  screen.fillScreen(COLOR_RGB565_BLACK);  

}

void printLocalWeather(){     http.begin("www.weather.com.cn/data/cityin…");     int httpCode = http.GET();     if(httpCode == HTTP_CODE_OK){       String pageData = http .getString();       //Serial.println(pageData);       deserializeJson(doc,pageData);       JsonObject obj = doc.as();       String weatherInfo = obj["weatherinfo"];       deserializeJson(doc1,weatherInfo);       JsonObject obj1 = doc1.as();       String city = obj1["city"];       String temp1 = obj1["temp1"];       String temp2 = obj1["temp2"];       String weather = obj1["weather"];       String cityInfo = city;       String tempInfo =temp1 + "~" + temp2;       String cityWeatherinfo =weather;       Serial.println("获得天气情况如下:");       Serial.print(cityInfo);       Serial.print(tempInfo);       Serial.println(cityWeatherinfo);              struct tm timeinfo;       if(!getLocalTime(&timeinfo)){       Serial.println("Failed to obtian time");       return ;       }       Serial.println(&timeinfo, "%F %R %u"); // 格式化输出

      //显示天气及时间信息       screen.setFont(&simkaiFont72pt );//Set the font to FreeMono12pt7b       screen.setCursor(/x=/15,/y=/0);       screen.println(&timeinfo,"%H");       screen.setCursor(/x=/15,/y=/55);       screen.println(&timeinfo,"%M");       screen.setFont(&simkaiFont72pt );//Set the font to FreeMono12pt7b       screen.setCursor(/x=/0,/y=/0);       screen.setTextColor(COLOR_RGB565_LGRAY);       screen.setTextWrap(true);       screen.setFont(&simkaiFont48pt );//Set the font to FreeMono12pt7b       screen.setCursor(/x=/124,/y=/0);       screen.println(weekDays[timeinfo.tm_wday]);       screen.setFont(&simkaiFont24pt );//设置字体大小 为24像素点大小       screen.setCursor(/x=/130,/y=/70); //设置显示光标       screen.println(cityWeatherinfo);//屏幕显示天气状况,如多云转晴类字样       screen.drawPIC(/x=/125,/y=/200,/w=/24,/h=/24,/bitmap gImage_Bitmap=/( uint8_t*)gImage_black6);//屏幕显示位置图标       screen.setFont(&simkaiFont36pt );//设置字体大小 为36像素点大小       screen.setCursor(/x=/120,/y=/135);//设置显示光标       screen.println(tempInfo);//屏幕显示温度信息       screen.setCursor(/x=/204,/y=/135);       screen.println("°");//显示温度的符号       screen.setCursor(/x=/150,/y=/190);       screen.println(cityInfo);//屏幕显示你所在城市的位置信息   

    }else{       Serial.println("GET ERR");     }     http.end(); }

void loop() {     if(WiFi.status() == WL_CONNECTED){     printLocalWeather();     }else{     Serial.println("WiFi  Disconnect");    }

}


##### 5.5 显示效果


![ad4159e0bd8599e0d09b181b47873424.png](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/180ddc27a3f3491faf225b6915769523~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1780324084&x-signature=9SLkyDDfK4StkhPqMhaZtlwejN8%3D)


### 六、使用电容触摸显示青蛙儿子旅行照片


#### 6.1 电容按键


ESP32提供了电容触摸传感器的功能, 共有T0,T2~T9 共 9个touch传感器可用.分别对应引脚4、2、15、13、12、14、27、33、32. 无需设置PinMode,touchRead()返回值为0~255. 触摸强度越大,返回值越小。烧录此例程,将使用4/D12引脚作为触摸按键,并通过串口监视器返回触摸值。



void setup() {   Serial.begin(9600); }

void loop() {    Serial.printf("touch:%d\n",touchRead(4)); }


##### 结果


![74cc5a86aea231af30727574361ca783.png](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/ce46242a8b7c491787ad9d4089d8b16f~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1780324084&x-signature=EzreYGcKr0DDUANFHhjlhnLpGYI%3D)


#### 6.2 选择放置的图片


![492ff8301520dc7f7d82fbe3074b8921.png](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/2811daf56a0d4ac18ef3ef25ba6d23f9~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1780324084&x-signature=vlxUOtg7CuhtHxf4EkiBo0HIWhk%3D)


#### 6.3 触摸一次就切换一次图片代码



#include <DFRobot_GDL.h> #include "BMP.h"

#define TFT_DC  D2 #define TFT_CS  D6 #define TFT_RST D3 #define PICNUMBER 6 uint8_t randNumber; DFRobot_ST7789_240x240_HW_SPI screen(/dc=/TFT_DC,/cs=/TFT_CS,/rst=/TFT_RST);

uint8_t printfrog(uint8_t number){     switch(number){     case 0:     screen.drawPIC(/x=/0,/y=/0,/w=/240,/h=/240,/bitmap gImage_Bitmap=/( uint8_t*)gImage_qingwa1);//显示的随机图片     delay(2000);     break;     case 1:     screen.drawPIC(/x=/0,/y=/0,/w=/240,/h=/240,/bitmap gImage_Bitmap=/( uint8_t*)gImage_qingwa2);     delay(2000);     break;     case 2:     screen.drawPIC(/x=/0,/y=/0,/w=/240,/h=/240,/bitmap gImage_Bitmap=/( uint8_t*)gImage_qingwa3);     delay(2000);     break;     case 3:     screen.drawPIC(/x=/0,/y=/0,/w=/240,/h=/240,/bitmap gImage_Bitmap=/( uint8_t*)gImage_qingwa4);     delay(2000);     break;     case 4:     screen.drawPIC(/x=/0,/y=/0,/w=/240,/h=/240,/bitmap gImage_Bitmap=/( uint8_t*)gImage_qingwa5);     delay(2000);     break;     case 5:     screen.drawPIC(/x=/0,/y=/0,/w=/240,/h=/240,/bitmap gImage_Bitmap=/( uint8_t*)gImage_qingwa6);     delay(2000);     break;     }

  }

void setup() {   Serial.begin(115200);   screen.begin(); }

void loop() {

     if(touchRead(4)<=20)    {     screen.fillScreen(COLOR_RGB565_BLACK);       Serial.println("摸到了");     randNumber =random(PICNUMBER);     Serial.println(randNumber);//随机数的打印     printfrog(randNumber);

    }     else{       Serial.println("没有摸到");       }   }


#### 6.4  随机触摸显示图片效果展示


![65096fc07059f14c2b56fb1c3d7df24e.png](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/bc428375c09a4409986eb223302c86ce~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1780324084&x-signature=DGgyDwZ%2BgZ4r%2Fhfs0b2sDcjKOBI%3D)


### 七、 完整功能代码展示



点击左下角阅读原文查看


从这次的小应用中我学会了很多东西,比如在tft屏幕上显示图片、动态图、中文。如何抓取天气信息,如何把抓取到的信息显示到tft屏幕上。


所以去旅行吧,不理会繁杂的琐事,自由自在地,去体验一个城市,一段故事,留下一片欢笑。


原文链接:https://mc.dfrobot.com.cn/thread-311127-1-1.html


项目作者: 创客达闻西


首发于DF创客社区


开源项目,转载请务必注明项目出处与原作者信息


#### 参考资料




![img](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/ddc424dfef554ae7b33fcd79b6ca9b02~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1780324084&x-signature=qqllTqKe6AAq4z%2BK6wmHI4APuYk%3D)
![img](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/00420ca167a04fd8ac88984e20982f69~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1780324084&x-signature=YUhB9WFARrwlVpeX0w2UlfnFp1g%3D)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://gitee.com/vip204888)**