809浏览
查看: 809|回复: 4

[项目] 自制一个基于Arduino的实时气象站

[复制链接]
本帖最后由 zoey不种土豆 于 2024-8-30 17:06 编辑

项目介绍
本项目将使用 Arduino UNO 和各种气象环境传感器创建一个造型美观且功能齐全的 Arduino 气象站。该气象站配备2.0英寸彩色串口屏,可提供有关温湿度、压力和紫外线水平的实时数据。其干净的图标、动态效果和文本展示效果确保了良好的视觉体验。这个迷你气象站非常适合智能家居自动化和 STEAM教育项目
自制一个基于Arduino的实时气象站图6
你可以从项目中学到
- 传感器集成:了解如何使用 GPIO 引脚连接和配置传感器,以及如何读取和处理数据。
- 数据可视化:将传感器数据集成到显示屏上,用文本、图标、小部件等内容可视化呈现天气信息。
- 界面设计:设计用户友好的气象站界面,优化响应速度和用户体验。
- 编程和调试:使用 Arduino 语言编写代码来控制传感器和显示器,并掌握调试技术以确保程序顺利运行。

硬件清单
1×Arduino UNO 链接
1×Gravity:2.0 英寸 LVGL ESP32-S3 IPS 屏幕,带 8M 闪存(320×240、I2C 和 UART) 链接
1×Gravity:BMP388 气压温度传感器 链接
1×Gravity:LTR390 紫外线传感器(280nm至430nm)- I2C和UART 链接
1×Gravity:DHT11 温湿度传感器(兼容Arduino) 链接

在选择显示器时,列出了以下5个需求:屏幕要小、分辨率高、显示清晰、支持图形和动态样式,并且易于使用、调整和修改。经比较,认为这款 2.0 英寸彩色 IPS 显示器完全满足这些要求:
1.清晰显示:凭借 320×240 高分辨率和 IPS 技术,即使从不同角度观看,也能确保清晰的图像。
2.简单的界面设计:它支持 LVGL 库,使界面设计变得更加简单。无论你是创建图标还是动画,都可以轻松实现。
3.良好的兼容性:它同时提供 I2C 和 UART 接口,使其适用于各种控制器且易于连接。
4.内置强大功能:支持图形和动画显示,节省大量额外工作。
5.快速入门:官方 wiki 提供了 Arduino 库和示例代码,因此即使是初学者也可以快速上手。

软件准备

硬件连接
硬件连接如下:
自制一个基于Arduino的实时气象站图3
项目过程
以下列出了关键的几个部分,可以结合文末的代码一起查看。
1.前期准备
导入项目中涉及显示屏、传感器等库文件进行初始化设置用于管理显示器、传感器和通信功能的基本库。
2.初始化和显示配置
- LCD 显示初始化:设置 LCD 屏幕,包括背景颜色、清空屏幕和计时。
- 定时器设置:设置时间的自动更新并启动计时器
- 显示时间和日期:在指定屏幕坐标上显示当前时间和日期。
- 图标显示:在屏幕上放置“云朵”图标。
3. 添加图标
从U盘存储的图标中选择项目所需的图标,可以自行改变位置、大小。在这个项目中,我们将创建四个传感器(UV、温度、湿度和气压)以及六个植物图标。以下代码演示了如何实现此目的:
自制一个基于Arduino的实时气象站图2
4.添加进度条功能
创建四根进度条来实现传感器数据可视化,分别对应温度、湿度、气压和紫外线强度。
自制一个基于Arduino的实时气象站图1

5.读取并显示数据
读取各个传感器的数据(包括温度、湿度、气压和紫外线强度),将读取到的数据通过进度条和标签的形式实时更新在LCD屏幕上。
代码
  1. #include "DFRobot_LcdDisplay.h"
  2. #include <MsTimer2.h>
  3. DFRobot_Lcd_IIC lcd(&Wire, /*I2CAddr*/ 0x2c);
  4. //LTR390紫外线传感器
  5. #include "DFRobot_LTR390UV.h"
  6. #include <SoftwareSerial.h>
  7. #define UARTMODE //UART模式
  8. SoftwareSerial mySerial(/*rx =*/4, /*tx =*/5);
  9. DFRobot_LTR390UV ltr390(/*addr =*/LTR390UV_DEVICE_ADDR, /*s =*/&mySerial);
  10. //BMP388气压传感器
  11. #include <DFRobot_BMP3XX.h>
  12. DFRobot_BMP388_I2C  sensor(&Wire, sensor.eSDOVDD);
  13. #define CALIBRATE_ABSOLUTE_DIFFERENCE
  14. //DHT11温湿度传感器
  15. #include <dht11.h>
  16. dht11 DHT;
  17. #define DHT11_PIN 10
  18. uint8_t Tem, Hum, Pre, Ult, lcdTimeId,labelId1,labelId2,labelId3,labelId4;
  19. uint8_t hour = 9, Minute = 8, second = 56;
  20. uint8_t lastSecond = 0;
  21. void flash()   //处理时间变化的中断处理程序
  22. {
  23.   second++;
  24.   if (second > 59) {
  25.     second = 0;
  26.     Minute++;
  27.   }
  28.   if (Minute > 59) {
  29.     Minute = 0;
  30.     hour++;
  31.   }
  32. }
  33. void setup(void){
  34.   lcd.begin();
  35.   lcd.setBackgroundColor(WHITE);
  36.   lcd.cleanScreen();
  37.   delay(500);
  38.   MsTimer2::set(1000, flash);        // 中断设置功能,每1000ms进入一次中断
  39.   MsTimer2::start();                 // 开始计数
  40.   lcdTimeId = lcd.drawLcdTime(10, 90, hour, Minute, second, 1, LIGHTGREY); //显示当前的时间
  41.   lcd.drawLcdDate(10, 120, 4, 7, 7, 0, LIGHTGREY); //显示当前的日期
  42.   lcd.drawGif(20, 5, "Cloudy.gif", 512);  //创建图标
  43.   //创建传感器对应图标
  44.   lcd.drawIcon(124, -8, "/sensor icon/thermometer.png", 120);
  45.   lcd.drawIcon(119, 35, "/sensor icon/raindrops.png", 120);
  46.   lcd.drawIcon(110, 78, "/sensor icon/pressure.png", 120);
  47.   lcd.drawIcon(109, 118, "/season icon/sunny.png", 120);
  48.   //创建多个图标
  49.   lcd.drawIcon(0, 176, "/botany icon/Potted plant flower.png", 256);
  50.   lcd.drawIcon(53, 176, "/botany icon/cactus3.png", 256);
  51.   lcd.drawIcon(106, 176, "/botany icon/grass.png", 256);
  52.   lcd.drawIcon(159, 176, "/botany icon/grass1.png", 256);
  53.   lcd.drawIcon(212, 176, "/botany icon/cactus1.png", 256);
  54.   lcd.drawIcon(265, 176, "/botany icon/cactus2.png", 256);
  55.   //创建进度条以显示温度
  56.   Tem = lcd.creatBar(164, 22, 80, 15, ORANGE);
  57.   labelId1 = lcd.drawString( 255, 22, "0lux", 0, ORANGE);
  58.   //创建进度条以显示湿度
  59.   Hum = lcd.creatBar(164, 62, 80, 15, RED);
  60.   labelId2 = lcd.drawString( 255, 62, "0°C", 0, RED);
  61.   //创建进度条以显示气压
  62.   Pre = lcd.creatBar(164, 102, 80, 15, BLUE);
  63.   labelId3 = lcd.drawString( 255, 102, "0%", 0, BLUE);
  64.   //创建进度条以显示紫外线强度
  65.   Ult = lcd.creatBar(164, 142, 80, 15, GREEN);
  66.   labelId4 = lcd.drawString( 255, 142, "0m/s", 0, GREEN);
  67.   //LTR390紫外线传感器初始化设置
  68.   #define UARTMODE
  69.   mySerial.begin(9600);
  70.   Serial.begin(115200);
  71.   while(ltr390.begin() != 0){
  72.     Serial.println(" Sensor initialize failed!!");
  73.     delay(1000);
  74.   }
  75.   Serial.println(" Sensor  initialize success!!");
  76.   ltr390.setALSOrUVSMeasRate(ltr390.e18bit,ltr390.e100ms);//18位数据,采样时间100ms
  77.   ltr390.setALSOrUVSGain(ltr390.eGain3);//3倍增益
  78.   ltr390.setMode(ltr390.eALSMode);//设置紫外线模式
  79.   //BMP388气压传感器初始化设置
  80.     int rslt;
  81.     while( ERR_OK != (rslt = sensor.begin()) ){
  82.       if(ERR_DATA_BUS == rslt){
  83.         Serial.println("Data bus error!!!");
  84.       }else if(ERR_IC_VERSION == rslt){
  85.         Serial.println("Chip versions do not match!!!");
  86.       }
  87.       delay(3000);
  88.     }
  89.     Serial.println("Begin ok!");
  90.     while( !sensor.setSamplingMode(sensor.eUltraPrecision) ){
  91.       Serial.println("Set samping mode fail, retrying....");
  92.       delay(3000);
  93.     }
  94.     delay(100);
  95.     #ifdef CALIBRATE_ABSOLUTE_DIFFERENCE
  96.     if( sensor.calibratedAbsoluteDifference(540.0) ){
  97.       Serial.println("Absolute difference base value set successfully!");
  98.     }
  99.     #endif
  100.     float sampingPeriodus = sensor.getSamplingPeriodUS();
  101.     Serial.print("samping period : ");
  102.     Serial.print(sampingPeriodus);
  103.     Serial.println(" us");
  104.     float sampingFrequencyHz = 1000000 / sampingPeriodus;
  105.     Serial.print("samping frequency : ");
  106.     Serial.print(sampingFrequencyHz);
  107.     Serial.println(" Hz");
  108.     delay(1000);
  109. }
  110. void loop(void){
  111.   if(lastSecond != second){
  112.     lastSecond = second;
  113.     lcd.updateLcdTime(lcdTimeId, 10, 90, hour, Minute, lastSecond, 1, LIGHTGREY); //显示当前时间
  114.   }
  115.   delay(100);
  116.   uint32_t date4 = 0;
  117.   date4 = ltr390.readALSTransformData(); //获取环境光转换后数据
  118.   float date3 = sensor.readPressPa(); //获取气压传感器的气压数据
  119.   DHT.read(DHT11_PIN);  //获取温湿度传感器的温度和湿度数据
  120.   Serial.println("-------------");
  121.   Serial.println(DHT.temperature);
  122.   Serial.println(DHT.humidity);
  123.   Serial.println(date3);
  124.   Serial.println(date4);
  125.   //设置进度条的值
  126.   lcd.setBarValue(Tem, DHT.temperature);
  127.   lcd.updateString(labelId1, 255, 22, String(DHT.temperature)+"°C", 0, ORANGE);
  128.   delay(100);
  129.   lcd.setBarValue(Hum, DHT.humidity);
  130.   lcd.updateString(labelId2, 255, 62, String(DHT.humidity)+"%", 0, RED);
  131.   delay(100);
  132.   lcd.setBarValue(Pre, date3);
  133.   lcd.updateString(labelId3, 255, 102, String(date3)+"Pa", 0, BLUE);
  134.   delay(100);
  135.   lcd.setBarValue(Ult, date4);
  136.   lcd.updateString(labelId4, 255, 142, String(date4)+"lux", 0, GREEN);
  137.   delay(100);
  138. }
复制代码
结语
在这个项目中,我们成功构建了一个功能齐全的气象站,它不仅可以显示各种天气数据,还可以提供美观且直接的界面。通过本项目,你学习了如何集成传感器和过程数据,以及如何使用 LVGL 库可视化数据和设计界面。
再展望一下,我们还可以通过添加更多类型的传感器或将天气数据上传到云端进行远程监控来进一步扩展和优化该项目。我们希望这个项目激发了你的创造力,激励你不断探索和创新,从而开发出更多有趣和实用的电子项目。
自制一个基于Arduino的实时气象站图4

你也可以使用黑色背景,根据自己的喜好对其进行自定义,如下所示:

自制一个基于Arduino的实时气象站图5

zoey不种土豆  超级版主
 楼主|

发表于 2024-8-30 14:50:51

新鲜冒泡
回复

使用道具 举报

hnyzcj  版主

发表于 2024-8-31 07:03:25

优秀
回复

使用道具 举报

auroraAA  管理员

发表于 2024-9-2 09:59:31

学到惹
回复

使用道具 举报

zoey不种土豆  超级版主
 楼主|

发表于 2024-9-2 14:01:02


这么帅的表情我怎么找不到
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail