主要目标

1.从和风天气 <https://www.heweather.com/>API获取天气数据,解析后通过串口发送到战舰开发板上
2.战舰开发板驱动传感器进行实时天气数据的采集,通过串口传到PC机

参考工程

感谢机智云物联网开发者社区的帖子,本系统STM32端很短代码参考自这位大神发的帖子:战舰V3通过ESP8266获得网络天气
<http://club.gizwits.com/thread-8049-1-1.html>,电脑端Java串口的编写主要参考(下载):使用Java实现串口通信
<http://blog.csdn.net/kong_gu_you_lan/article/details/52302075>
,虽然很多代码都不是我动手写的,但是为了这个课设仍然做了许多努力,希望能记录下来。再次感谢这两位大神!

项目笔记

Json字符串的解析

和风天气API返回的是一个Json字符串比如
{"HeWeather6":[{"basic":{"cid":"CN101010100","location":"北京","parent_city":"北京"
,"admin_area":"北京","cnty":"中国","lat":"39.90498734","lon":"116.4052887","tz":
"+8.0"},"update":{"loc":"2018-01-27 16:50","utc":"2018-01-27 08:50"},"status":
"ok","daily_forecast":[{"cond_code_d":"101","cond_code_n":"101","cond_txt_d":
"多云","cond_txt_n":"多云","date":"2018-01-27","hum":"34","mr":"13:16","ms":"02:41"
,"pcpn":"0.0","pop":"0","pres":"1032","sr":"07:26","ss":"17:28","tmp_max":"-2","
tmp_min":"-9","uv_index":"2","vis":"16","wind_deg":"224","wind_dir":"西南风","
wind_sc":"微风","wind_spd":"8"},{"cond_code_d":"100","cond_code_n":"100","
cond_txt_d":"晴","cond_txt_n":"晴","date":"2018-01-28","hum":"15","mr":"14:05","ms
":"03:50","pcpn":"0.0","pop":"0","pres":"1035","sr":"07:25","ss":"17:29","
tmp_max":"-1","tmp_min":"-8","uv_index":"2","vis":"20","wind_deg":"350","
wind_dir":"北风","wind_sc":"微风","wind_spd":"3"},{"cond_code_d":"100","cond_code_n
":"100","cond_txt_d":"晴","cond_txt_n":"晴","date":"2018-01-29","hum":"21","mr":
"15:03","ms":"04:57","pcpn":"0.0","pop":"0","pres":"1032","sr":"07:24","ss":
"17:31","tmp_max":"1","tmp_min":"-8","uv_index":"2","vis":"20","wind_deg":"259"
,"wind_dir":"西南风","wind_sc":"微风","wind_spd":"4"}],"sunrise_sunset":[{"$ref":
"$[0].daily_forecast[0]"},{"$ref":"$[0].daily_forecast[1]"},{"$ref":
"$[0].daily_forecast[2]"}]}]}
可以看出,要想获得合适的数据,就必须解析这个Json字符串,通过谷歌可以找到在线格式化Json工具,大概是这个样子的,附传送门
<https://www.bejson.com/>

这里我们通过在线格式化只是为了方便下一步的解析,首先,创建一个JSONObject对象
JSONObject json1 = JSONObject.fromObject(sb.toString());
创建JSONArray
JSONArray array1 = json1.getJSONArray("HeWeather6");
用array1中的第一个元素再次创建JSONObject对象
JSONObject json2 = JSONObject.fromObject(array1.getString(0));
创建名为daily_forecast的JSONArray
JSONArray array2 = json2.getJSONArray("daily_forecast");
输出最近三天的部分天气数据
for(int i = 0;i < array2.size();i++){ //System.out.println(array2.getString(i))
; String string3 = array2.getString(i); JSONObject json3 = JSONObject.fromObject
(string3); System.out.print("时间:"+json3.getString("date")+" "); System.out
.print("最低温度:"+json3.getString("tmp_min")+" "); System.out.print("最高温度:"+json3
.getString("tmp_max")+" "); System.out.print("天气:"+json3.getString("cond_txt_d"
)+" "); System.out.println("湿度:"+json3.getString("hum")); }
控制台输出
时间:2018-01-27 最低温度:-8 最高温度:-2 天气:晴间多云 湿度:34 时间:2018-01-28 最低温度:-9 最高温度:-1 天气:晴
湿度:15 时间:2018-01-29 最低温度:-8 最高温度:1 天气:晴 湿度:21
小结

我的解析Json思路很简单,不断创建JSONObject和JSONArray对象,层层解析,最后得到需要的数据,点击Json格式大神讲解
<http://blog.csdn.net/xukai871105/article/details/32346797>。

串口发送数据的处理

首先我们要知道,Java编写串口工具串口发送数据的类型都是byte[],这样我们就只需要把要发送的数据变成byte[]类型即可啦,

获取天气数据
WeatherData weatherDataHF = new WeatherData(
"key=db3e861fc7654111800271e316414820&location="+cityName.toString(),
"https://free-api.heweather.com/s6/weather/forecast?parameters");
天气数据的处理


接下来似乎只需要把这些数据通过getBytes()方法转化就可以了但是我们仔细回想一下之前得到的数据,有没有什么不对劲?没错!串口不能发送汉字!!!所以这里就需要对数据进行处理,转化成数字或者字符串,这学期学习了计算机体系结构,所以我参考了一下查表法,把天气转换成特定的数字组合,如晴天为001,阴天为010,温度也用三位数字表示,第一位数字为0则表示高于0℃,为1则表示低于0℃,如最低温度-1℃表示为101。OK,第一个问题解决了。

兴冲冲的去测试串口数据发送,但是发送的数据没有显示什么鬼,奇怪的每次发送之后数据并没有传输,但是使用串口发送助手之后点第一下马上有了结果,翻了翻战舰的串口接收代码,
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d
0x0a结尾)
接收中断必须是ox0d 0x0a结尾!所以需要把数据以\r\n结尾,
StringBuilder weatherData = new StringBuilder(); weatherData.delete(0,
weatherData.length()); weatherData.append(weatherDataHF.getWeatherData());
byte[] order = weatherData.toString().getBytes(); SerialTool.sendToPort
(serialPort, order);
请忽略我清奇的脑回路代码,Java初学者伤不起。

总结

这次课程设计总的来说很多代码都是从网上复制粘贴,但是也还是遇到了不少问题然后大体解决了,尚未解决的问题有:
PC端的UI界面有时会崩溃,猜测是数据传送太快出现溢出
战舰端的数据发送需要高于一定的频率不断发送,不然PC端接收不到数据,猜测是软件问题,串口助手可以正常工作

完整工程文件

基于STM32与和风天气API的交互系统 <http://download.csdn.net/download/m0_37620545/10227385>
注:战舰开发板需要dht11温湿度传感器,没有传感器也可以在keil文件中注释掉相关初始化调用函数。