每天起床的意义就是去拥抱工作!
万万没想到出门就下雨,只有上楼拿伞了!(没有什么能阻挡我去打工)
这突如其来的下雨天让我想起了“一休和尚”的晴天娃娃
据说把晴天娃娃正吊着是求晴天,倒吊着是求雨天(我觉得求下雨还是拜拜萧敬腾比较靠谱,hh~毕竟是公认的“雨神”,有他在下雨没意外)
思路:为了不再发生多跑一趟回家拿伞的事情,我想做一个能随时检测是否快下雨的“玩意”。突然就想起了DFROBOT新推出的esp32-e和温湿度传感器正好可以做一个天气预报站。
功能:用显示屏把esp32-e从中国天气网站获取当天所在城市的温度和天气数据和温湿度传感器获得当前环境的温度和湿度数据显示出来。若当前湿度大于90%,蓝色的娃娃就会被舵机带动往上移动,同时mp3模块会播放设定的音频(目前设置的音频是薛之谦的“下雨天”);若当前湿度值小于70%,橙色的娃娃就会被舵机带动网上移动,同时mp3模块会播放设定的音频(目前设置的音频是周杰伦的“晴天”)。
晴天娃娃天气预报站
说干就干,打工人从来都不墨迹。
一、准备材料
1.硬件材料
-
ESP32-E IoT开发板+扩展版 x 1
-
舵机 x 2
-
喇叭 x 1
-
按钮 x 1
-
3.7V电池 x 1
- 杜邦线 若干
2.晴天娃娃材料
- 洗脸巾 x2
- 颜色笔 x2
- 口罩 x1
- 纸巾 若干
二、制作过程
1.将各个模块按下方图片进行连接
2. 安装开发板和库
(1)安装开发板
- 打开 Arduino 1.8.13,点击File——Preferences——Show verbose output during中勾选compilation和upload,再把json文件网址(如下所示)复制粘贴到Addi tional Boards Manager URLs中,然后点击页面右下角的OK关闭页面。
复制代码 隐藏代码
http://download.dfrobot.top/FireBeetle/package_DFRobot_index.json
复制代码
- 点击Tools——Board——Boards Manager——选择DFRobot AVR Boards板子——点击Install——安装完成后点击右下角Close关闭页面。
(2)安装ArduinoJson库,安装方式如下图
3.烧录程序
复制代码 隐藏代码
#include <ESP32Servo.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <DFRobot_SHT3x.h>
#include <DFRobot_PLAY.h>
#include <DFRobot_LCD.h>
DFRobot_LCD lcd(/*每行16个字符*/16,/*显示2行*/2);
DFRobot_SHT3x sht3x(&Wire,0x45,4); //当ADR连接到VDD时,芯片I2C地址为0x45,该产品通过拨扭开关来选择芯片地址
DFRobot_PLAY mp3Player; //mp3模块的名字
HTTPClient http;
const char* ssid="dfrobot";// wifi的名字,根据实际情况进行更改
const char* password="123456789.";// WiFi的密码.,根据实际情况进行更改
const char* ntpServer = "pool.ntp.org"; //NTP服务器 国内可用的NTP Server:/*0.cn.pool.ntp.org*/ /*cn.pool.ntp.org*/ /*tw.pool.ntp.org*/
const long gmtOffsetSec = 28800; //
const int daylightOffsetSec = 0;//
int buttonPin = D7; //按钮接入D7引脚
DynamicJsonDocument doc(1024);//JSON解析
Servo sunServo;//控制晴天娃娃高度的舵机
Servo rainServo;//控制雨天娃娃高度的舵机
String gTemperature,gWeatherInfo; //全局变量
bool sunnyDay = true; //判断晴天状态变量
bool rainyDay = true; //判断雨天状态变量
bool musicPlaying = false; //判断音乐播放状态
bool lcdShowing = false; //判断lcd显示状态
unsigned long long musicStamp; //音乐播放持续时间
unsigned long long lcdStamp; //lcd显示持续时间
uint16_t musicServo(){
uint16_t ret = 0;
if(sht3x.getHumidityRH()<70 && sunnyDay == true){
sunServo.write(176); //控制晴天娃娃舵机高度为176升起
rainServo.write(5); //控制雨天娃娃舵机高度为5降落
mp3Player.start(); //音乐开始播放
mp3Player.playFileNum(1);//播放1号音频
sunnyDay = false;
rainyDay = true;
ret = 10*1000;
}else if(sht3x.getHumidityRH()>90 && rainyDay == true){
sunServo.write(5); //控制晴天娃娃高度舵机为5降落
rainServo.write(176);//控制雨天娃娃高度舵机为176升起
mp3Player.start(); //音乐开始播放
mp3Player.playFileNum(2);//播放2号音频
rainyDay = false;
sunnyDay = true;
ret = 10*1000;
}
return ret;
}
uint16_t lcdPrint(){
uint16_t ret = 0;
uint8_t button = digitalRead(buttonPin); //读取按钮引脚高低电平
if (button == HIGH){
delay(100);
button = digitalRead(buttonPin);
//经过100毫秒如果还是为高电频就显示
if(button == HIGH){
lcd.setPWM(REG_ONLY,255); //亮屏
lcd.display(); //打开lcd显示
lcd.setCursor(/*列:*/0,/*行:*/0);//设置显示光标
lcd.print("T:");
lcd.setCursor(/*列:*/2,/*行:*/0);
lcd.print(gTemperature); //从网上获取的温度
lcd.setCursor(/*列:*/4,/*行:*/0);
lcd.print("C");
lcd.setCursor(/*列:*/6,/*行:*/0);
lcd.print("W:");
lcd.setCursor(/*列:*/8,/*行:*/0);
lcd.print(gWeatherInfo); //从网上获取的天气信息
lcd.setCursor(/*列:*/0,/*行:*/1);
lcd.print("T:");
int Temperature = sht3x.getTemperatureC(); //从传感器上获取的温度
lcd.print(Temperature);
lcd.setCursor(/*列:*/4,/*行:*/1);
lcd.print("C");
lcd.setCursor(/*列:*/6,/*行:*/1);
lcd.print("H:");
int Humidity = sht3x.getHumidityRH(); //从传感器上获取的湿度
lcd.print(Humidity);
lcd.setCursor(/*列:*/10,/*行:*/1);
lcd.println("%RH ");
ret = 5*1000;
}
}
return ret;
}
void printLocalWeather(){
//提供城市编码的网站:https://blog.csdn.net/qq_40266771/article/details/103905967 下列网址是(成都101270101)你可以进行替换,你所在的城市编码
http.begin("http://d1.weather.com.cn/sk_2d/101270101.html"); //在中国天气网上抓取的成都的温湿度和天气情况
int httpCode = http.GET(); //请求方法:get()/post()
if(httpCode == HTTP_CODE_OK){
String pageData = http .getString();//把获取到的数据传递到pageData
pageData.replace("var dataSK = ","");//replace替换函数 把var dataSk = 去掉只留下json字符串
deserializeJson(doc,pageData);//解析pageData deserialize(反序列化)Json 解析函数 doc接收
JsonObject obj = doc.as<JsonObject>();// 获取顶节点,并把它转成T类型;JsonObject:对象的入口
gWeatherInfo = obj["weathere"].as<String>();//把从网上获取的天气情况转换成字符串赋值给gWeatherInfo
gTemperature = obj["temp"].as<String>(); //把从网上获取的温度转换成字符串赋值给gWeatherInfo
Serial.print("温度:");
Serial.println(gTemperature);
Serial.print("天气情况:");
Serial.println(gWeatherInfo);
}else{
Serial.println("GET ERR"); //打印获取失败
}
http.end();
}
void setup() {
Serial.begin(115200); //设置波特率为115200
Serial.printf("Connecting to %s",ssid);
WiFi.begin(ssid,password); //连接wifi
while(WiFi.status() != WL_CONNECTED){ //当wifi连接时,串口会打印.
delay(500);
Serial.print(".");
}
Serial.println(" CONNECTED");
//初始化并设置并获取时间
configTime(gmtOffsetSec, daylightOffsetSec, ntpServer);
pinMode(buttonPin,INPUT); //设置按钮引脚为输入模式
lcd.init(); //初始化lcd屏幕
Serial2.begin(115200); //mp3模块波特率设置
while(!mp3Player.begin(Serial2)){
Serial.println("初始化失败,请检查接线!");
delay(1000);
}
mp3Player.setVol(/*VOL = */1); //设置音量为1
mp3Player.switchFunction(mp3Player.MUSIC); //进入音乐模式
rainServo.attach(D2); //控制雨天娃娃舵机连接D2引脚
sunServo.attach(D6);//控制晴天娃娃舵机连接D6引脚
}
void loop(){
uint16_t durationLcd; //lcd显示持续时间
uint16_t durationMusic;//music播放持续时间
if(WiFi.status() == WL_CONNECTED){//判断WiFi是否连接成功
printLocalWeather(); //调用获取当地天气的函数
}else{
Serial.println("WiFi Disconnect");//WiFi断开
}
if (musicPlaying == false){
durationMusic = musicServo();//返回值代表音乐播放的时间(ms),返回0代表不播放音乐
if(durationMusic){//假如有参数也就是在播放
musicPlaying = true;//播放就赋值为真
musicStamp = millis();//把系统时间传给musicStamp
}
}
if(lcdShowing == false){
durationLcd = lcdPrint();//lcd如果播放就把参数传进去
if(durationLcd){//假如有参数就是在播放
lcdShowing = true;//lcd播放就赋值为真
lcdStamp = millis();//把系统时间传给lcdStamp
}
}
if(lcdShowing == true && millis()-lcdStamp>=durationLcd){
lcdShowing = false;//lcd播放设置为假
lcd.setPWM(REG_ONLY,0); //息屏
lcd.noDisplay();//lcd关闭显示
}
if(musicPlaying && (millis()-musicStamp >= durationMusic)){
musicPlaying = false;//把播放设置为假
mp3Player.pause();//停止播放
}
}
复制代码
4.设计外壳并用木板切割
5.制作晴天娃娃
将口罩两边的绳子取下来并上色,再将纸巾揉成团放在洗脸巾里并用绳子捆紧就ok了。(材料有限hh~)
6.组装
把各个器件按位置固定好,最后再把外壳组装起来(记得把晴天娃娃挂在舵机的摆臂上哦)
有了这款天气预报站,妈妈再也不用担心我淋雨了~