嵌入式比赛提交的报告
嵌入式芯片与系统设计竞赛设计报告
基于物联网技术的数字农业监测系统
——新之所向 PDL 队 3316
灵动赛道
1
目录
6.2、MCU 向 L610 发送 AT 指令进行连接,以及向腾讯云发送数据 27
陶志霖;黄富达;陆秀萍
我国是一个农业大国,现阶段的农业发展过程中,传统种植主要依靠人的感知能力,存 在极大的不确定性,要想进一步借助现阶段先进的科学技术[1] 、实现农业的精准操作,便于 从业人员的管理,降低生产成本,满足现代农业信息化的需求。利用灵动MB-036 作为主控 板、广和通 L610 作为通信模块 、腾讯云平台等物联网技术,可以把土壤温湿度、光照强度、 大气温湿度等数据上传到云平台。设计基于物联网技术的数字农业监测系统。
关键词:物联网技术;数字农业;监测系统
农业传统种植主要依靠人的感知能力,存在极大的不确定性。本文设计的基 于物联网技术的数字农业监测系统,目标是准确实时的获取农作物生长的环境信 息,通过分析得到环境变化对农作物生长状况影响的规律,为从业人员提供全面 的参考,实现农业的精准操作,满足现代农业信息化,智能化的需求。
应用领域:大棚果园种植、蔬菜大棚、以及花卉生产基地、公园等。
基于物联网技术的农业监测系统将采集到的大气温湿度,土壤温湿度,光照 强度等农业气象信息进行加工,传输和利用,为农业生产在各个时期的精准管理 和预测预警提供信息支持,可应用于大棚果园种植、蔬菜大棚、以及花卉园宅基 地、公园等,系统追求以最少的资源消耗获得最大的优质输出,更便利于从业人 员的管理。系统具有实现高精度采集、实现低成本、网络部署方便、系统实现资 源共享等意义。
该系统采用物联网技术,采用模块化设计,具有技术先进,测量精度高,数 据容量大,遥测距离远,可靠性高的优点。
(1) 具有多种供电方式,交直流两用或配太阳能电池供电
(2) 用于对风速、空气温湿度、光照强度等气象要素进行全天候现场监测。可以 通过专业配套的数据采集通讯线与计算机进行连接,将数据传输到气象计算 机气象数据库中,用于统计分析和处理。
(3) 由气象传感器、气象数据记录仪、电源系统等部分构成。风速、雨量、大气 压力等传感器为气象专用传感器,具有高精度高可靠性的特点。
(4) 有线传输方式:通过标准 USB/RS485 通信接口,与监测中心 PC 机有线连接
(5) 无线传输方式:只要可以上网就可通过 GPRS/NB/LTE 无线传输
(6) 信息管理规范真实高效:实时更新,数据库方式存储,根据需要在前台显示
(7) 简单易用:数字农业监测系统强调易用性与实用性的完美结合。
(1) CRC 校验:对数据进行多项式计算,并将得到的结果附在帧的后面,接收设 备也执行类似的算法,以保证数据传输的正确性和完整性。
(2) 数据转化:可以自动进行数据帧采集处理,只要上电就自动进行数据转化
(3) 连接腾讯云:MCU 或者 PC 机向广和通 L610 发送 AT 指令实现与腾讯云连 接。
(4) 系统采用出错冗余技术,保证运行的安全性。
(5) 响应时间:气象站向 MM32 主控板发送数据到用户收到数据延迟最低 500ms.
(1) 生产环境实时监测, 自动报警
(2) 通过在农业生产现场部署物联网设备(如采集器和传感器),可以实时采集 和监测环境数据和设备状态数据,并上传到云端。用户可通过手机或电脑登 录数字农业监测系统平台,查看园区气象数据、土壤数据和设备状态。当出 现高温、高湿等异常情况时,系统会自动报警,提醒工作人员及时处理,否 则系统会自动排除异常。
(3) 数据共享:通过广和通上传到腾讯云、微信小程序,只需要分享链接便可以 多人实时观测。
(4) 可视化数据大屏:可以量化分析各项参数,同时显示警告信息。
气象采集仪 主体部分
数字农业监测系统数据大屏显示页面
2.2.1.气象数据采集仪——采集传感器的数据
气象数据采集仪是一种集气象数据采集、 存储、传输和管理于一体的无人 值守的气象测量系统。它在气象、工农业生产、旅游、城市环境其他专业领域都 有广泛的用途。气象数据采集仪具有技术先进、测量精度高、运行可靠、功能全 面的特点。有采集、存储、分析和处理气象数据以及超限报警的功能。使用时将 传感器连接到 可以很方便地的获取到周围环境参数。
气象数据采集仪通过 RS-485 黄蓝两线进行连接。该套硬件设备可减少人工 操作,拥有性价比高和高效便捷的优点,数字农业监测平台的无线传输节点结构 如下图所示。其主要模块包括采集温湿度等环境因子的数据采集传感器、负责接 收数据的接口单元、将接收到的数据进行无线传输的转换模块以及为以上模块提 供能量的供电模块。
2.2.2.灵动 MB-036 主控板——编译转化数据
(1) • MM32L073PF (Cortex-M0 MCU:128k FLASH 、8k SRAM)
(2) • 板载 SPI Flash 芯片
(3) • 板载 IIC EEPROM 芯片
(4) • 板载 CAN 转换芯片
(5) • 板载无源蜂鸣器
(6) • 外设 IO 全部引出,方便快速搭载模块测试
(7) • 双 USB 接口,USB-1 支持 USB 仿真、下载和调试,USB-2 支持 USB device 和供电
(8) • 板载 MM32-LINK OB ,可对主控 MCU 进行在线仿真、调试和下载
(9) • 支持 Keil uvision/ IAR EWARM 开发环境
MCU 主要代码流程图
灵动 MB-036 主控板正面图
2.2.3.广和通 L610 模块——通信模块
L610-CN-00 是一款 LTE Cat1 制式的无线通信模组。模组提供了丰富的接口 设置,满足 loT 行业的各种应用诉求。传输速率最高 10MbpsDL,最低 5MbpsUL, 定位覆盖中低速率的物联网市场,例如智慧零售、智慧安防、智慧家居、智慧农 业、智慧城市等多种应用场景。
在学习L610 前,我们要先了解下物联网架构,物联网架构分感知层,网络 层,平台层,应用层,如下图。从中可以看出L610 处于感知层和网络层之间, 起到数据传输通道的作用。物联网整体工作是 MCU 将感知层中传感器的数据通 过 AT 指令的方式,发送给 L610 模块,然后,L610 通过网络,将数据上报云端, 云端接收到数据之后,可运用到各个应用之中。
物联网架构
接下来介绍下 ADP-L610-Arduino 开发板
ADP-L610-Arduino 板带 LTE CAT1 通信模组 L610,自带贴片物联网 SIM 卡; 支持 Arduino 接口,可与 MM32 eMiniBoard 开发板匹配使用;
支持外接串口,并可支持 TTL/RS232 两种电平, 可与外部 MCU 或 PC 连接;
支持 TYPE-C USB 口,可与 PC 直连,USB 口供电并通信,可独立并便捷地 进行通信方面的测试验证。ADP-L610-Arduino 开发板正面图、背面图如下。
ADP-L610-Arduino 开发板正面 ADP-L610-Arduino 开发板背面
MCU 通过 AT 指令的方式,将数据发送给 L610 模块,然后通过网络,传到云端, 我们可以在云端查看数据,收集数据,也可以对数据进行分析,对数据进行分析 要设定一个场景。所以我们选定 L610 连接云平台,实现在云端查看数据,收集 数据和分析数据。
使用沁恒串口工具监测 MCU 发送 AT 的指令
L610 与 MB036 连接框图
2.2.4.RS232/RS485 转 TTL 模块——实现主控板与采集仪通信
RS232 转 TTL 模块,采用美信公司出品的 MAX232 芯片,配合广泛流传的基于 max232 串口电平转换电路,精心设计而成。
RS-232 总线接口具有 ESD 总线保护功能,双绞线输出,浪涌保护功能 600W , 接口芯片 具有隔离及总线保护功能于一身;方便嵌入用户的设备 使 产品具有连接到 RS-232 网络的功能。该系列模块采用灌封工艺,具有很好的隔 离特性,隔离电压高达 1000V DC 。可用于工业通信、煤矿行业、电力监控、楼 宇自动化、石油化工、PLC 与变频器的通信。
RS232 转 TTL 模块
2.2.5 腾讯云平台——数据量化分析
腾讯云是腾讯公司旗下的产品,为开发者及企业提供云服务、云数据、云运 营等整体一站式服务方案。我们使用到了腾讯云的物联网开发平台。腾讯云物联 网开发平台(IoT Explorer)为各行业的设备制造商、方案商及应用开发商提供 一站式设备智能化服务。平台提供海量设备连接与管理能力及小程序应用开发能 力,并打通腾讯云基础产品及 AI 能力,提升传统行业设备智能化的效率,降低 用户的开发运维成本,助力用户业务发展。我们通过 L610 将数据上传到平台上。
把腾讯云上的数据下发到腾讯连连小程序里,可以实现远程监测气象数据。
2.2.6 数字农业监测系统数据大屏——可视化气象数据
本系统还使用了云 MySQL 数据库 ,云数据库 MySQL ( TencentDB for
MySQL)是腾讯云基于开源数据库 MySQL 专业打造的高性能分布式数据存储 服务,让用户能够在云中更轻松地设置、操作和扩展关系数据库。是面向互联网 应用的数据存储服务,且完全兼容 MySQL 协议,适用于面向表结构的场景; 适用 MySQL 的地方都可以使用云数据库。提供高性能、高可靠、易用、便捷 的 MySQL 集群服务。整合了备份、扩容、迁移等功能,同时提供新一代数据 库工具 DMC ,用户可以方便地进行数据库的管理。我们利用其特性,感知层 传输的数据通过 L610 传到网络,将数据上报云端,云端接收到数据之后,显示 到数字农业监测系统数据大屏中。
数字农业监测系统数据大屏
已能够通过气象采集仪采集相关环境参数(如图 3-1 ) ,并通过连接 RS232/RS485 转 TTL 模块(如图 3-2 所示)把采集到的数据以十六进制的数据 传输给主控板(MM32 eMiniBoard 开发板),主控板通过串口 3(usart3)连接 RS232/RS485 转 TTL 模块(如图 3-3 所示)接收传输的数据,通过程序判断接 收的数据,再把数据转换成指定的环境参数数值,最后连接上串口 1(usart1) 与 L610-CN-00(如图 3-4 所示),通过程序把转换后的数值传输到腾讯云(如 图 3-5 所示),最后能够在微信小程序查看到相关的环境参数(图3-6 所示), 同时还能够通过云平台查看具体环境情况(图3-7 所示)。
1 、气象采集仪
参数 | 测量范围 | 精度 | 分辨率 |
大气温度 | -30℃~70℃ | ±0.2℃ | 0. 1℃ |
大气湿度 | 0~ 100%RH | ±3%RH | 0. 1%RH |
光照度 | 0~200k Lux | ±3%F·S | 10Lux |
风速 | 0~60m/s | ±(0.3+0.03V)m/s | 0. 1m/s |
风向 | 0~360° | ±1° | 0.1° |
O2 | 0~20PPM | ±3F·S | 1PPM |
二氧化碳 | 0~2000PPM | ±4%F·S+3% | 1PPM |
PM2.5 | 0~ 1000ug/m³ | ±3F·S | 1ug/m³ |
土壤温度 | -30℃~70℃ | ±0.2℃ | 0. 1℃ |
土壤湿度 | 0~ 100% | ±0.2%(m³ /m³ ) | 0. 1% |
2 、RS-232
(1)RS-232 串口通信最远距离是 50 英尺;
(2)RS232 可做到双向传输,全双工通讯,最高传输速率 20kbps;
(3)RS-232C 上传送的数字量采用负逻辑,且与地对称;
逻辑 1 :-3 ∼ -15V ; 逻辑 0 :+3∼ +15V;
3 、RS-485
(1) 接口电平低,不易损坏芯片。
(2) 传输速率高,10 米时,RS485 的数据最高传输速率可达 35Mbps,在 1200m 时,传输速度可达 100Kbps。
(3) 抗干扰能力强,RS485 接口是采用平衡驱动器和差分接收器的组合,抗共模 干扰能力增强,即抗噪声干扰性好。
(4) 传输距离远,支持节点多, RS485 总线最长可以传输 1200m 以上(速率 ≤100Kbps)一般最大支持 32 个节点,如果使用特制的 485 芯片,可以达到 128 个或者 256 个节点,最大的可以支持到 400 个节点。
4 、灵动 MB-036 主控板
(1)MM32W373PSB (Cortex-M3 MCU:128k FLASH 、20k SRAM);
(2)板载 SPI Flash 芯片、IIC EEPROM 芯片、无源蜂鸣器;
(3)具备 1 个 VR 、4 个 LED 、4 个 KEY;
(4)支持 Arduino 硬件接口;
(5)外设 IO 全部引出,方便快速搭载模块测试;
(6)双 USB 接口,USB-1 支持 USB 仿真、下载和调试,USB-2 支持 USB device 和供电;
(7)板载 MM32-LINK OB ,可对主控 MCU 进行在线仿真、调试和下载;
(8)支持 Keil uvision/ IAR EWARM 开发环境;
(9)空旷地段 18m 的通信距离;
5 、ADP-L610-Arduino 开发板
(1)支持广和通 LTE Cat1/LTE Cat4 MiniPCIe 封装通信模块 ;
(2)支持级联 Arduino 接口,可以串联支持 Arduino 接口的设备 ;
(3) 自带贴片物联网 SIM 卡,并可切换到外卡 ;
(4)支持多种通信接口:Arduino 接口上的串口、2 线串口、RS232、USB ;
(5)支持多种供电方式:Arduino 接口供电、USB 口供电、外部 DC 供电 ;
图 3-1
图 3-2
图 3-3
图 3-4
图 3-5
图 3-6
图 3-7
将物联网应用于农业,推动我国的传统产业改造升级,为我国的农业发展提 供了一个全新的发展平台,实现我国农业现代化,信息化、智能化的发展,这是 一个大而复杂的课题,未来还有很长的路要走。本文的设计的基于物联网技术的 数字农业监测系统,只是实现了简单的数据传输和监测数据的功能,演示系统过 程中发现,由于实际农业生产环境的复杂性,所以尽管在实验室能够实现农田环 境参数监测系统的部分功能,但是将系统应用于实际生产环境还需要进一步努力 改善系统。该系统还可以在以下几个方面展开进一步的扩展:
(1)本系统的协调数据器节点采用串口连接方式向上位机传输数据,协调 器节点必须与计算机终端相连,具有一定的局限性,可以引用GPRS/Wi-Fi 等技 术,实现协调器节点与计算机终端的远端通信。
(2)本系统只是简单实现了对种植园环境信息的实时监测,未来可以添加 执行装置的控制设备,监测到的实时信息,对农业灌溉等设备进行远程控制,达 到真正的智能化管理。
(3)提高数据资源综合利用水平。建设与物联网平台相结合的大数据分析 平台,以农业物联网数据采集为数据基以其他涉农业务数据为分析要素,综合农 业生产及产业结构特点,实现真正大数据应用指导农业生产、指导产业发展的新 格局。
(4)本系统在远程监控端只研发了上位机控制界面,需要通过 Internet 登 录管理界面进行查看,后续可以设计一款手机 APP 监控界面,让操作人员可以 随时随地进行种植园信息的查看。系统后期可增加大数据分析模型,建设智慧农 业综合平台,添加更多种类的传感器和控制装置,应用推广到更广领域的智慧农 业领域。
(5)在系统后续的开发中可以增加几类传感器来检测其他环境因素,例 PH 值 H 值,EC 值等。但伴随着传感器采集数据类型的增加以及传感器节点数的增 加,对微控制器的处理数据能力要求更加严格时,可以采用嵌入 ARM 系统开 发功能或者处理能力更强的处理器。
农业是物联网技术的重点领域之一,物联网应用在农业的应用上已经引起了 广泛的关注。该系统针对感知控制系统、云端数据库和微信小程序等进行设计并 验证,可实时监测种植园的空气温湿度、光照强度、土壤温湿度等各项数据,为 从业人员提供全面的参考,便于从业人员的管理,降低生产成本。该系统具有扩 展性好,性价比高等优势,具有很高的实用价值。
我们通过参加本次嵌入式芯片与系统设计竞赛,学到了很多,像是 RS-232 以及 RS-485 端口,都是在指导老师的指导下第一次接触到这些行业的东西,懵 懵懂懂中学习着如何管理工作进度,如何交流学习。
在参加灵动赛道的时候也是第一次接触到国产 MCU 厂商,刚学完 STM32 就开始写代码,感谢灵动微电子的开发人员,写了很多例程,上手并没有想象中 的难。
在使用广和通模块的时候,十分感谢广和通大学计划的两名负责人,他们建 的群有很多详细资料,解答非常积极热情。
最后,这是我在短暂的大学生活中参加的第一次正式的比赛,感谢指导老师 的耐心指导,感谢小伙伴们的帮助,我们顺利完成了本次项目。感谢灵动微电子 公司的赞助,以及广和通嵌入式比赛负责人的热情讲解,以及感谢组委会提供的 比赛机会,我看到了更广阔的世界。这些都是我们学习成长路上的贵人。
[1] 于彩云,李述广.樱桃种植中影响产量的气候因素探究[J].现代农业研究, 2021,27(1):107-108 .
[2] 王旭 赤 峰 市 设施农业 发 展现状及对 策 [J] ,2011 ,27(9):196-197.
[3] 文黎明,龙亚兰.物联网在农业上的应用J 现代农业科技,2010(15):54-54.
[4] 何传启. 中国现代化报告 2012-农业现代化研究[M].北京,2012.
weather.c
1. #include "uart_nvic.h"
2. #include "weather.h"
3. #include "math.h"
4. #include "hal_uart.h"
5.
6. weather w;
7. //获取气象站数据,存储于结构体中
8.
9. double getTemperature()//获取气象站温度值
10. {
11. u8
bitOne,bitTwo,bitThree,bitFour,bitFive,bitSix,bitSeven,bitEight;
12. double res;
13. if(UART_RX_BUF[0]==0xBB&&UART_RX_BUF[1]==0x10&&UART_RX_BUF[2]==0x03&&UART_RX_B UF[3]==0x00&&UART_RX_BUF[4]==0x02){
14.
15.
16. bitOne=UART_RX_BUF[10]>>4;
17. bitTwo=UART_RX_BUF[10]&0x0F;
18. bitThree=UART_RX_BUF[11]>>4;
19. bitFour=UART_RX_BUF[11]&0x0F;
20. bitFive=UART_RX_BUF[12]>>4;
21. bitSix=UART_RX_BUF[12]&0x0F;
22. bitSeven=UART_RX_BUF[13]>>4;
23. bitEight=UART_RX_BUF[13]&0x0F;
24.
25. res=(bitOne*pow(16,7)+bitTwo*pow(16,6)+bitThree*pow(16,5)+bitFour*pow(16,4)+bi tFive*pow(16,3)+bitSix*pow(16,2)+bitSeven*pow(16,1)+bitEight)/10000.0;
26. if(UART_RX_BUF[8] == 1)
27. w.Temperature= -res;
28. else
29. w.Temperature= res;
30. }
31. return w.Temperature;
32. }
33.
34. double getHumidity()//获取气象站湿度值
35. {
36.
37. u8 bitOne,bitTwo;
38. double res;
39. if(UART_RX_BUF[0]==0xBB&&UART_RX_BUF[1]==0x10&&UART_RX_BUF[2]==0x03&&UART_RX_B UF[3]==0x00&&UART_RX_BUF[4]==0x03){
40. bitOne=UART_RX_BUF[13]>>4;
41. bitTwo=UART_RX_BUF[13]&0x0F;
42. res=(bitOne*16+bitTwo);
43. w.Humidity=res;
44.
45. }
46. return w.Humidity;
47. }
48.
49. double getVelocity()//获取气象站风速值
50. {
51. u8
bitOne,bitTwo,bitThree,bitFour,bitFive,bitSix,bitSeven,bitEight;
52. double res;
53. if(UART_RX_BUF[0]==0xBB&&UART_RX_BUF[1]==0x10&&UART_RX_BUF[2]==0x03&&UART_RX_B UF[3]==0x00&&UART_RX_BUF[4]==0x0D){
54. bitOne=UART_RX_BUF[10]>>4;
55. bitTwo=UART_RX_BUF[10]&0x0F;
56. bitThree=UART_RX_BUF[11]>>4;
57. bitFour=UART_RX_BUF[11]&0x0F;
58. bitFive=UART_RX_BUF[12]>>4;
59. bitSix=UART_RX_BUF[12]&0x0F;
60. bitSeven=UART_RX_BUF[13]>>4;
61. bitEight=UART_RX_BUF[13]&0x0F;
62. res=(bitOne*pow(16,7)+bitTwo*pow(16,6)+bitThree*pow(16,5)+bitFour*pow(16,4)+bi tFive*pow(16,3)+bitSix*pow(16,2)+bitSeven*pow(16,1)+bitEight)/10000;
63. w.Velocity=res;
64.
65. }
66. return w.Velocity;
67. }
68.
69. | double getWind_Direction()//获取气象站风向值 |
70. | { |
71. | u8 bitOne,bitTwo,bitThree,bitFour; |
72. | double res; |
73. if(UART_RX_BUF[0]==0xBB&&UART_RX_BUF[1]==0x10&&UART_RX_BUF[2]==0x03&&UART_RX_B UF[3]==0x00&&UART_RX_BUF[4]==0x0E){ | |
74. | bitOne=UART_RX_BUF[12]>>4; |
75. | bitTwo=UART_RX_BUF[12]&0x0F; |
76. | bitThree=UART_RX_BUF[13]>>4; |
77. | bitFour=UART_RX_BUF[13]&0x0F; |
78. | res=(bitOne*pow(16,3)+bitTwo*pow(16,2)+bitThree*pow(16,1)+bitFour); |
79. | w.Wind_Direction=res; |
80. | |
81. | } |
82. | return w.Wind_Direction; |
83. | } |
84. | |
85. | double getIlluminance()//获取气象站光照值 |
86. | { |
87. | u8 bitOne,bitTwo,bitThree,bitFour; |
88. | double res; |
89. if(UART_RX_BUF[0]==0xBB&&UART_RX_BUF[1]==0x10&&UART_RX_BUF[2]==0x03&&UART_RX_B UF[3]==0x00&&UART_RX_BUF[4]==0x01){ | |
90. | bitOne=UART_RX_BUF[12]>>4; |
91. | bitTwo=UART_RX_BUF[12]&0x0F; |
92. | bitThree=UART_RX_BUF[13]>>4; |
93. | bitFour=UART_RX_BUF[13]&0x0F; |
94. | res=(bitOne*pow(16,3)+bitTwo*pow(16,2)+bitThree*pow(16,1)+bitFour); |
95. | w.Illuminance=res; |
96. | |
97. | } |
98. | return w.Illuminance; |
99. | } |
100. | |
101. | double getCO2()//获取气象站二氧化碳值 |
102. |
|
103. | u8 bitOne,bitTwo,bitThree,bitFour; |
104. | double res; |
105. if(UART_RX_BUF[0]==0xBB&&UART_RX_BUF[1]==0x10&&UART_RX_BUF[2]==0x03&&UART _RX_BUF[3]==0x00&&UART_RX_BUF[4]==0x0A){ | |
106. | bitOne=UART_RX_BUF[12]>>4; |
107. | bitTwo=UART_RX_BUF[12]&0x0F; |
108. | bitThree=UART_RX_BUF[13]>>4; |
109. |
|
110. | res=(bitOne*pow(16,3)+bitTwo*pow(16,2)+bitThree*pow(16,1)+bitFour); |
111. | w.CO2=res; |
112. | |
113. | } |
114. | return w.CO2; |
115. | } |
116. | |
117. | double getSoil_temperature()//获取气象站土壤温度值 |
118. |
|
119. | u8 bitOne,bitTwo,bitThree,bitFour,bitFive,bitSix,bitSeven,bitEight; |
120. | double res; |
121. if(UART_RX_BUF[0]==0xBB&&UART_RX_BUF[1]==0x10&&UART_RX_BUF[2]==0x01&&UART _RX_BUF[3]==0x00&&UART_RX_BUF[4]==0x0B){ | |
122. | bitOne=UART_RX_BUF[10]>>4; |
123. | bitTwo=UART_RX_BUF[10]&0x0F; |
124. | bitThree=UART_RX_BUF[11]>>4; |
125. | bitFour=UART_RX_BUF[11]&0x0F; |
126. | bitFive=UART_RX_BUF[12]>>4; |
127. | bitSix=UART_RX_BUF[12]&0x0F; |
128. | bitSeven=UART_RX_BUF[13]>>4; |
129. | bitEight=UART_RX_BUF[13]&0x0F; |
130. res=(bitOne*pow(16,7)+bitTwo*pow(16,6)+bitThree*pow(16,5)+bitFour*pow(16, 4)+bitFive*pow(16,3)+bitSix*pow(16,2)+bitSeven*pow(16,1)+bitEight)/10000; | |
131. | if(UART_RX_BUF[8] == 1) |
132. | w.Soil_temperature=-res; |
133. | else |
134. | w.Soil_temperature=res; |
135. | } |
136. | return w.Soil_temperature; |
137. | } |
138. | |
139. | double getSoil_humidity()//获取气象站土壤湿度值 |
140. |
|
141. | |
142. | u8 bitOne,bitTwo; |
143. | double res; |
144. if(UART_RX_BUF[0]==0xBB&&UART_RX_BUF[1]==0x10&&UART_RX_BUF[2]==0x01&&UART _RX_BUF[3]==0x00&&UART_RX_BUF[4]==0x0A){ | |
145. | bitOne=UART_RX_BUF[13]>>4; |
146. | bitTwo=UART_RX_BUF[13]&0x0F; |
147. | res=(bitOne*16+bitTwo); |
148. | w.Soil_humidity=res; |
154. double getO2()//获取气象站氧气值
155. |
|
156. | u8 bitOne,bitTwo,bitThree,bitFour,bitFive,bitSix,bitSeven,bitEight; |
157. | double res; |
158. if(UART_RX_BUF[0]==0xBB&&UART_RX_BUF[1]==0x10&&UART_RX_BUF[2]==0x03&&UART _RX_BUF[3]==0x00&&UART_RX_BUF[4]==0x14){ | |
159. | bitOne=UART_RX_BUF[10]>>4; |
160. | bitTwo=UART_RX_BUF[10]&0x0F; |
161. | bitThree=UART_RX_BUF[11]>>4; |
162. | bitFour=UART_RX_BUF[11]&0x0F; |
163. | bitFive=UART_RX_BUF[12]>>4; |
164. | bitSix=UART_RX_BUF[12]&0x0F; |
165. | bitSeven=UART_RX_BUF[13]>>4; |
166. | bitEight=UART_RX_BUF[13]&0x0F; |
167. res=(bitOne*pow(16,7)+bitTwo*pow(16,6)+bitThree*pow(16,5)+bitFour*pow(16, 4)+bitFive*pow(16,3)+bitSix*pow(16,2)+bitSeven*pow(16,1)+bitEight)/10000; | |
168. | w.O2=res; |
169. | |
170. | } |
171. | return w.O2; |
172. | } |
173. | |
174. | double getPM25()//获取气象站PM2.5 值 |
175. |
|
176. | u8 bitOne,bitTwo,bitThree,bitFour; |
177. | double res; |
178. if(UART_RX_BUF[0]==0xBB&&UART_RX_BUF[1]==0x10&&UART_RX_BUF[2]==0x03&&UART _RX_BUF[3]==0x00&&UART_RX_BUF[4]==0x12){ | |
179. | bitOne=UART_RX_BUF[12]>>4; |
180. | bitTwo=UART_RX_BUF[12]&0x0F; |
181. | bitThree=UART_RX_BUF[13]>>4; |
182. | bitFour=UART_RX_BUF[13]&0x0F; |
183. | res=(bitOne*pow(16,3)+bitTwo*pow(16,2)+bitThree*pow(16,1)+bitFour); |
184. | w.PM25=res; |
185. | |
186. | } |
187. | return w.PM25; |
188. | } |
189. |
|
190. | void clearBUF() |
191. |
|
192. | int t; |
193. | for(t=0;t<31;t++) |
194. | { |
195. | UART_RX_BUF[t]=0; |
196. | } |
197. | |
198. | } |
6.2 、 MCU 向 L610 发送AT 指令进行连接, 以及向腾讯云发 送数据
main.c
1. #define _MAIN_C_
2.
3. #include "delay.h"
4. #include "uart_nvic.h"
5. #include "weather.h"
6. #include "uart.h"
7. //定义数据类型
8. char *strx,*extstrx,*Readystrx;
9. char RxBuffer[1024],Rxcouter;
10. char *strstr(const char *, const char *);
11. uint8_t Res;
12. int len;
13. int number;
14. extern int r_flag;
15.
16. void Clear_Buffer(void)
17. {
18. uint8_t i;
19.
20. for(i=0;i<Rxcouter;i++)
21. RxBuffer[i]=0;
22. Rxcouter=0;
23. }
24.
25. int main(void)
26. {
27.
28. //模块初始化,等待3 秒
29. DELAY_Init(); 30.
31. Uart3_Init(115200);
//
设置波特率//发送
32. CONSOLE_Init(9600); //接收
33.
34. printf("模块初始化");
35. DELAY_Ms(3000);
36.
37. //查询版本信息
38. printf("ATI\r\n");
39. DELAY_Ms(4000);
40. strx=strstr((const char*)RxBuffer,(const char*)"Fibocom");
41. while(strx==NULL)
42. {
43. Clear_Buffer();
44. printf("查询信息失败");
45. DELAY_Ms(1000);
46. printf("ATI\r\n");
47. DELAY_Ms(1000);
48. strx=strstr((const char*)RxBuffer,(const char*)"Fibocom L610-CN-00-00 ");
49. }
50. Clear_Buffer();
51. printf("版本信息正确");
52. DELAY_Ms(1000);
53. //请求IP
54. printf("AT+MIPCALL?\r\n");
55. DELAY_Ms(4000);
56. printf("AT+MIPCALL=1");
57. printf("\r\n");
58. strx=strstr((const char*)RxBuffer,(const char*)"+MIPCALL: 1");
59. |
|
60. | { |
61. | Clear_Buffer(); |
62. | printf("还未获取到 IP"); |
63. | DELAY_Ms(1000); |
64. | printf("AT+MIPCALL=1\r\n"); |
65. | DELAY_Ms(1000); |
66. | strx=strstr((const char*)RxBuffer,(const char*)"+MIPCALL: "); |
67. | } |
68. | Clear_Buffer(); |
69. | DELAY_Ms(1000); |
70. | printf("获取 IP 成功"); |
71. | DELAY_Ms(1000); |
72. | |
73. | //设置平台设备信息 |
74. | DELAY_Ms(1000); |
75. r\n"); | printf("AT+TCDEVINFOSET=1,\"WI92LNABUQ\",\"CO2\",\"sFRex8ZITFpI2MdcJKfI7A==\"\ |
76. | DELAY_Ms(1000); |
77. | strx=strstr((const char*)RxBuffer,(const char*)"+TCDEVINFOSET: OK"); |
78. | while(strx==NULL) |
79. | { |
80. | Clear_Buffer(); |
81. | printf("平台信息设置失败"); |
82. | DELAY_Ms(1000); |
83. \r\n"); | printf("AT+TCDEVINFOSET=1,\"WI92LNABUQ\",\"CO2\",\"sFRex8ZITFpI2MdcJKfI7A==\" |
84. | DELAY_Ms(1000); |
85. | strx=strstr((const char*)RxBuffer,(const char*)"+TCDEVINFOSET: OK"); |
86. | } |
87. | Clear_Buffer(); |
88. | |
89. | printf("平台信息设置成功"); |
90. | DELAY_Ms(1000); |
91. | |
92. | //设置连接参数并连接 |
93. | DELAY_Ms(4000); |
94. | printf("AT+TCMQTTCONN=1,20000,240,1,1\r\n"); |
95. | DELAY_Ms(4000); |
96. | strx=strstr((const char*)RxBuffer,(const char*)"+TCMQTTCONN: OK"); |
97. | while(strx==NULL) |
98. | { |
99. Clear_Buffer();
100. printf("连接失败");
101. | DELAY_Ms(1000); |
102. | printf("AT+TCMQTTCONN=1,20000,240,1,0\r\n"); |
103. | DELAY_Ms(1000); |
104. | strx=strstr((const char*)RxBuffer,(const char*)"+TCMQTTCONN: OK"); |
105. | } |
106. | Clear_Buffer(); |
107. | printf("连接成功"); |
108. | DELAY_Ms(1000); |
109. | |
110. | //订阅上报下行属性 |
111. | printf("AT+TCMQTTSUB=\"$thing/down/property/WI92LNABUQ/CO2\",1\r\n"); |
112. | DELAY_Ms(4000); |
113. | strx=strstr((const char*)RxBuffer,(const char*)"+TCMQTTSUB: OK"); |
114. | while(strx==NULL) |
115. | { |
116. | Clear_Buffer(); |
117. | printf("订阅标签失败"); |
118. | DELAY_Ms(1000); |
119. | printf("AT+TCMQTTSUB=\"$thing/down/property/WI92LNABUQ/CO2\",1\r\n"); |
120. | DELAY_Ms(1000); |
121. | strx=strstr((const char*)RxBuffer,(const char*)"+TCMQTTSUB: OK"); |
122. | } |
123. | Clear_Buffer(); |
124. | printf("订阅标签成功"); |
125. | DELAY_Ms(1000); |
126. | //上报属性 |
127. printf("AT+TCMQTTPUB=\"$thing/up/property/WI92LNABUQ/CO2\",1,\"{\\\"metho d\\\":\\\"report\\\",\\\"clientToken\\\":\\\"123\\\",\\\"params\\\":{\\\"CO2\\\":%.1f}}\ "\r\n",w.CO2); | |
128. | DELAY_Ms(1000); |
129. | strx=strstr((const char*)RxBuffer,(const char*)"success"); |
130. | while(strx==NULL) |
131. | { |
132. | Clear_Buffer(); |
133. | printf("上报失败"); |
134. | DELAY_Ms(1000); |
135. printf("AT+TCMQTTPUB=\"$thing/up/property/WI92LNABUQ/CO2\",1,\"{\\\"met hod\\\":\\\"report\\\",\\\"clientToken\\\":\\\"123\\\",\\\"params\\\":{\\\"co2\\\":%.1f}} \"\r\n",w.CO2);
136. DELAY_Ms(1000);
137. strx=strstr((const char*)RxBuffer,(const char*)"success");
138. }
139. | Clear_Buffer(); | ||
140. | printf("上报成功"); | ||
141. | DELAY_Ms(4000); | ||
142. | |||
143. | |||
144. | while(1) { | ||
145. | getTemperature(); | ||
146. | getHumidity(); | ||
147. | getVelocity(); | ||
148. | getWind_Direction(); | ||
149. | getIlluminance(); | ||
150. | getCO2(); | ||
151. | getSoil_temperature(); | ||
152. | getSoil_humidity(); | ||
153. | getO2(); | ||
154. | getPM25(); | ||
155. | |||
156. // printf("温度:%.1f",w.Temperature); | |||
157. printf("\r\n"); | |||
158. printf("AT+TCMQTTPUB=\"$thing/up/property/WI92LNABUQ/CO2\",1,\"{\\\"me thod\\\":\\\"report\\\",\\\"clientToken\\\":\\\"123\\\",\\\"params\\\":{\\\"Temperature\ \\":%.1f}}\"\r\n",w.Temperature); | |||
159. printf("\r\n"); | |||
160. | DELAY_Ms(3000); | ||
161. | //// printf("湿度:%.1f RH",w.Humidity); | ||
162. | printf("\r\n"); | ||
163. printf("AT+TCMQTTPUB=\"$thing/up/property/WI92LNABUQ/CO2\",1,\"{\\\"me thod\\\":\\\"report\\\",\\\"clientToken\\\":\\\"123\\\",\\\"params\\\":{\\\"Humidity\\\": %.1f}}\"\r\n",w.Humidity); | |||
164. | printf("\r\n"); | ||
165. | DELAY_Ms(3000); | ||
166. | //// printf("风速:%.1f m/s",w.Velocity); | ||
167. | printf("\r\n"); | ||
168. printf("AT+TCMQTTPUB=\"$thing/up/property/WI92LNABUQ/CO2\",1,\"{\\\"me thod\\\":\\\"report\\\",\\\"clientToken\\\":\\\"123\\\",\\\"params\\\":{\\\"Velocity\\\": %.1f}}\"\r\n",w.Velocity); | |||
169. | printf("\r\n"); | ||
170. | DELAY_Ms(3000); | ||
171. | //// printf("风向:%.1f | °",w.Wind_Direction); | |
172. | printf("\r\n"); | ||
173. printf("AT+TCMQTTPUB=\"$thing/up/property/WI92LNABUQ/CO2\",1,\"{\\\"me thod\\\":\\\"report\\\",\\\"clientToken\\\":\\\"123\\\",\\\"params\\\":{\\\"Wind_Directi on\\\":%.1f}}\"\r\n",w.Wind_Direction);
174. printf("\r\n");
175. DELAY_Ms(3000);
176. //// printf("CO2:%.1f ",w.CO2);
177. printf("\r\n");
178. printf("AT+TCMQTTPUB=\"$thing/up/property/WI92LNABUQ/CO2\",1,\"{\\\"me thod\\\":\\\"report\\\",\\\"clientToken\\\":\\\"123\\\",\\\"params\\\":{\\\"CO2\\\":%.1f} }\"\r\n",w.CO2);
179. | printf("\r\n"); | ||
180. | DELAY_Ms(3000); | ||
181. | //// printf("土壤温度:%.1f ℃",w.Soil_temperature); | ||
182. | printf("\r\n"); | ||
183. printf("AT+TCMQTTPUB=\"$thing/up/property/WI92LNABUQ/CO2\",1,\"{\\\"me thod\\\":\\\"report\\\",\\\"clientToken\\\":\\\"123\\\",\\\"params\\\":{\\\"Soil_tempera ture\\\":%.1f}}\"\r\n",w.Soil_temperature); | |||
184. | printf("\r\n"); | ||
185. | DELAY_Ms(3000); | ||
186. | //// printf("土壤湿度:%.1f | RH",w.Soil_humidity); | |
187. | printf("\r\n"); | ||
188. printf("AT+TCMQTTPUB=\"$thing/up/property/WI92LNABUQ/CO2\",1,\"{\\\"me thod\\\":\\\"report\\\",\\\"clientToken\\\":\\\"123\\\",\\\"params\\\":{\\\"Soil_humidit y\\\":%.1f}}\"\r\n",w.Soil_humidity); | |||
189. | printf("\r\n"); | ||
190. | DELAY_Ms(3000); | ||
191. | //// printf("O2:%.1f | ",w.O2); | |
192. | printf("\r\n"); | ||
193. printf("AT+TCMQTTPUB=\"$thing/up/property/WI92LNABUQ/CO2\",1,\"{\\\"me thod\\\":\\\"report\\\",\\\"clientToken\\\":\\\"123\\\",\\\"params\\\":{\\\"O2\\\":%.1f}} \"\r\n",w.O2);
194. printf("\r\n");
195. DELAY_Ms(3000);
196. //// printf("光照度%.1f 帕" ,w.Illuminance);
197. printf("\r\n");
198. printf("AT+TCMQTTPUB=\"$thing/up/property/WI92LNABUQ/CO2\",1,\"{\\\"me thod\\\":\\\"report\\\",\\\"clientToken\\\":\\\"123\\\",\\\"params\\\":{\\\"Illuminance\ \\":%.1f}}\"\r\n",w.Illuminance);
199. printf("\r\n");
200. DELAY_Ms(3000);
201. //// printf("PM2.5:%.1f ",w.PM25);
202. printf("\r\n");
203. printf("AT+TCMQTTPUB=\"$thing/up/property/WI92LNABUQ/CO2\",1,\"{\\\"me thod\\\":\\\"report\\\",\\\"clientToken\\\":\\\"123\\\",\\\"params\\\":{\\\"PM25\\\":%.1 f}}\"\r\n",w.PM25);
204. printf("\r\n");
205.
206. printf("\r\n");
207. printf("\r\n");
208.
209. DELAY_Ms(3000);
210.
211. }

浙公网安备 33010602011771号