成品展示:
功能介绍:
【1】联网获取心知天气下发的当日天气信息,如:温度、湿度、风向、风力等级等;
【2】自带RTC时钟,支持人机交互时间修改;
【3】支持2.4Gwifi连接,支持更换地点后直接修改重联wifi信息(含wifi名称、wiif密码,暂不支持中文wifi名称),支持大小写切换、修改后需重启方可重新连接;
【4】实时获取室内温湿度信息;
【5】上述参数交互均在屏幕上完成。
后续功能:过去及未来天气、天气出行信息。。。 。。。
制作过程:
(1)材料清单(含购买链接):3.2寸淘晶驰HMI串口屏(增强版)、ESP8266、DHT11(温湿度传感器)、TF卡(用于屏幕数据下载)、MicroUSB线
注:上述材料仅供参考(老板没给广告费)
(2)软件清单:Arduino IDE、USART HMI
开始:
心知天气进行账号注册,获取你的API私钥,在这里你可以查看官方给的学习文档。
如下图所示,免费提供的信息非常少,请大家申请试用版本!!!
String url = "/v3/weather/now.json?key=Ak47j5BQpzYGO6jnvCBG&location=changsha&language=zh-Hans&unit=c";
如上代码所示,Key=“输入你的API私钥”,Location=“changsha”,这是你的所在地,其他参数无需修改
//因为使用屏幕输入wifi信息,因此这里ssid、password里面的参数为空,第一次使用后需要进入wifi设置配置
String ssid = "";
String password = "";
由于ESP8266的固有特性,连接一次wifi后,该wifi信息会保存在ESP8266里面,只有更换wifi才需重新配置,修改完后记得重启设备。
如何进入wifi配置页面?
答:点击屏幕上的“wifi”图标,点击无线名称或无线密码的输入框,需要有光标闪烁,方可输入信息,点击“Enter”确认退出
如何修改时间?
答:点击时间进入时间设置界面,设置完后点击空白处确认退出
电路搭建部分(省略),因为太简单了
其中DHT11温湿度传感器接ESP8266的GPIO5,屏幕则是串口通讯(TX-RX、RX-TX),ESP8266引脚图如下:
程序讲解:
int k1 = 0;//中间数if (Serial.available() > 0)//判读是否串口有数据{String comdata = "";//缓存清零while (Serial.available() > 0)//循环串口是否有数据{comdata += char(Serial.read());//叠加数据到comdatadelay(2);//延时等待响应}string_length = comdata.length(); //将数据长度赋给string_lengthif(string_length > 0) { //如果有数据//Serial.print(comdata);//Serial.println(" " + String(string_length));for (int i = 0; i <= string_length; i = i + (1)) {
/*从comdata第0个数据开始判断是否有'h'(作为wifi名称和密码之间的间隔符号)*/if(comdata[i] == 'h') {
/*如果判断到'h',则将该字符位置赋给k1,并从comdata【0】开始到k1-1(除去h的位置)累加字符存进ssid里面去,作为WiFi名称*/k1 = i;for(int i = 0; i <= k1-1; i = i + (1)) {ssid += comdata[i];}ssid = ssid;Serial.print("ssid:");Serial.println(ssid);}if(comdata[k1+1] == 'h') {
/*判断'h'后面那个字符时候为'h',因为屏幕这边会输出两个hh作为wifi名称和密码之间的间隔符号*/
/*然后从这个位置到最后开始累加condata的数据,并赋给password作为WiFi密码,执行完后跳出循环*/for(int i = k1 + 2; i <= string_length-3; i = i + (1)) {password += comdata[i];}password = password;Serial.print("password:");Serial.println(password);break;}}}}
//JSON解析
//利用ArduinoJson库解析心知返回的json天气数据
//可以利用 https://arduinojson.org/v5/assistant/ Arduinojson助手生成相关json解析代码 很方便!!!
const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6) + JSON_OBJECT_SIZE(13) + 370;
DynamicJsonBuffer jsonBuffer(capacity);const char* json = "{\"results\":[{\"location\":{\"id\":\"WX4FBXXFKE4F\",\"name\":\"北京\",\"country\":\"CN\",\"path\":\"北京,北京,中国\",\"timezone\":\"Asia/Shanghai\",\"timezone_offset\":\"+08:00\"},\"now\":{\"text\":\"多云\",\"code\":\"4\",\"temperature\":\"12\",\"feels_like\":\"11\",\"pressure\":\"1014\",\"humidity\":\"87\",\"visibility\":\"5.0\",\"wind_direction\":\"南\",\"wind_direction_degree\":\"183\",\"wind_speed\":\"14.04\",\"wind_scale\":\"3\",\"clouds\":\"90\",\"dew_point\":\"\"},\"last_update\":\"2019-04-27T17:40:08+08:00\"}]}";JsonObject& root = jsonBuffer.parseObject(json_weather_data);JsonObject& results_0 = root["results"][0];JsonObject& results_0_location = results_0["location"];
const char* results_0_location_id = results_0_location["id"]; // "WX4FBXXFKE4F"
const char* results_0_location_name = results_0_location["name"]; // "北京"
const char* results_0_location_country = results_0_location["country"]; // "CN"
const char* results_0_location_path = results_0_location["path"]; // "北京,北京,中国"
const char* results_0_location_timezone = results_0_location["timezone"]; // "Asia/Shanghai"
const char* results_0_location_timezone_offset = results_0_location["timezone_offset"]; // "+08:00"JsonObject& results_0_now = results_0["now"];
const char* results_0_now_text = results_0_now["text"]; // "多云" 当地天气
const char* results_0_now_code = results_0_now["code"]; // "4" 天气代码
const char* results_0_now_temperature = results_0_now["temperature"]; // "12" 当前温度
const char* results_0_now_feels_like = results_0_now["feels_like"]; // "11"
const char* results_0_now_pressure = results_0_now["pressure"]; // "1014" 气压
const char* results_0_now_humidity = results_0_now["humidity"]; // "87" 湿度
const char* results_0_now_visibility = results_0_now["visibility"]; // "5.0"
const char* results_0_now_wind_direction = results_0_now["wind_direction"]; // "南" 风向
const char* results_0_now_wind_direction_degree = results_0_now["wind_direction_degree"]; // "183"
const char* results_0_now_wind_speed = results_0_now["wind_speed"]; // "14.04" 风速
const char* results_0_now_wind_scale = results_0_now["wind_scale"]; // "3" 风速等级
const char* results_0_now_clouds = results_0_now["clouds"]; // "90"
const char* results_0_now_dew_point = results_0_now["dew_point"]; // ""const char* results_0_last_update = results_0["last_update"]; // "2019-04-27T17:40:08+08:00"
上图截图来源:https://docs.seniverse.com/api/weather/now.html
code = String(results_0_now_code).toInt();
/*将获取到的天气代码转换成整形数据,并判断控制屏幕显示的天气图片*/switch (code) { //天气代码case 0:Serial.print("p1.pic=11");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=11");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 1:Serial.print("p1.pic=12");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=12");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 2:Serial.print("p1.pic=13");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=13");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 3:Serial.print("p1.pic=14");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=14");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 4:Serial.print("p1.pic=15");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=15");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 5:Serial.print("p1.pic=16");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=16");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 6:Serial.print("p1.pic=17");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=17");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 7:Serial.print("p1.pic=18");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=18");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 8:Serial.print("p1.pic=19");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=19");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 9:Serial.print("p1.pic=20");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=20");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 10:Serial.print("p1.pic=21");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=21");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 11:Serial.print("p1.pic=22");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=22");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 12:Serial.print("p1.pic=23");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=23");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 13:Serial.print("p1.pic=24");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=24");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 14:Serial.print("p1.pic=25");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=25");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 15:Serial.print("p1.pic=26");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=26");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 16:Serial.print("p1.pic=27");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=27");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 17:Serial.print("p1.pic=28");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=28");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 18:Serial.print("p1.pic=29");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=29");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 19:Serial.print("p1.pic=30");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=30");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 20:Serial.print("p1.pic=31");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=31");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 21:Serial.print("p1.pic=32");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=32");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 22:Serial.print("p1.pic=33");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=33");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 23:Serial.print("p1.pic=34");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=34");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 24:Serial.print("p1.pic=35");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=35");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 25:Serial.print("p1.pic=36");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=36");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 26:Serial.print("p1.pic=37");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=37");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 27:Serial.print("p1.pic=38");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=38");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 28:Serial.print("p1.pic=39");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=39");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 29:Serial.print("p1.pic=40");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=40");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 30:Serial.print("p1.pic=41");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=41");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 31:Serial.print("p1.pic=42");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=42");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 32:Serial.print("p1.pic=43");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=43");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 33:Serial.print("p1.pic=44");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=44");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 34:Serial.print("p1.pic=45");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=45");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 35:Serial.print("p1.pic=46");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=46");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 36:Serial.print("p1.pic=47");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=47");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 37:Serial.print("p1.pic=48");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=48");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 38:Serial.print("p1.pic=49");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=49");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break;case 99:Serial.print("p1.pic=50");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);Serial.print("p1.pic=50");Serial.write(0xff);Serial.write(0xff);Serial.write(0xff);delay(10);break; }
存在的问题:
【1】风向信息JSON解析过来的是中文,使用串口直接发送 t1.txt="东北",屏幕这边会显示错误信息,使用HMI的调试工程是正常的;
【2】wifi信息尽量避免出现“h”,可能出现无法正确设置wifi信息,我的程序是判断连续出现两个“hh”,hh的前面是wifi名称,hh的后面是wifi密码;
【3】wifi信息配置完成需要重启,才能连接重新配置的wifi。
注:以上问题不应该该作品的正常使用。
资料下载:源代码、工程均开源
程序、HMI
到此,该作品的制作过程及重点需要讲解的部分已经完成。
后续的外观结构部分,后期补上
最终成品:
作品欣赏:
主界面
时间设置
WiFi配置
正常工作
欲知详情,可添加微信,咱们一对一交流。