嵌入式比赛提交的报告

嵌入式芯片与系统设计竞赛设计报告

基于物联网技术的数字农业监测系统

——新之所向 PDL 3316

灵动赛道

1

目录

基于物联网技术的数字农业监测系统 3

摘要 3

第一部分 设计概述 3

1.1 设计目的 3

1.2 应用领域 3

1.3 主要技术特点 4

1.4 关键性能指标 4

1.5 主要创新点 5

第二部分 系统组成及功能说明 6

2.1 整体介绍 6

2.2 各模块介绍 7

第三部分 完成情况及性能参数 14

3.1 完成情况 14

3.2 性能参数 14

第四部分 总结 19

4.1 可扩展之处 19

4.2 心得体会 20

第五部分 参考文献 21

第六部分 附录 22

6.1、转化气象数据以及 CRC 冗余校验的代码 22

6.2、MCU 向 L610 发送 AT 指令进行连接,以及向腾讯云发送数据 27

基于物联网技术的数字农业监测系统

陶志霖;黄富达;陆秀萍

摘要

我国是一个农业大国,现阶段的农业发展过程中,传统种植主要依靠人的感知能力,存 在极大的不确定性,要想进一步借助现阶段先进的科学技术[1] 、实现农业的精准操作,便于 从业人员的管理,降低生产成本,满足现代农业信息化的需求。利用灵动MB-036 作为主控 板、广和通 L610 作为通信模块 、腾讯云平台等物联网技术,可以把土壤温湿度、光照强度、 大气温湿度等数据上传到云平台。设计基于物联网技术的数字农业监测系统。

关键词:物联网技术;数字农业;监测系统

第一部分 设计概述

1.1 设计目的

农业传统种植主要依靠人的感知能力,存在极大的不确定性。本文设计的基 于物联网技术的数字农业监测系统,目标是准确实时的获取农作物生长的环境信 息,通过分析得到环境变化对农作物生长状况影响的规律,为从业人员提供全面 的参考,实现农业的精准操作,满足现代农业信息化,智能化的需求。

1.2 应用领域

应用领域:大棚果园种植、蔬菜大棚、以及花卉生产基地、公园等。

基于物联网技术的农业监测系统将采集到的大气温湿度,土壤温湿度,光照 强度等农业气象信息进行加工,传输和利用,为农业生产在各个时期的精准管理 和预测预警提供信息支持,可应用于大棚果园种植、蔬菜大棚、以及花卉园宅基 地、公园等,系统追求以最少的资源消耗获得最大的优质输出,更便利于从业人 员的管理。系统具有实现高精度采集、实现低成本、网络部署方便、系统实现资 源共享等意义。

1.3 主要技术特点

该系统采用物联网技术,采用模块化设计,具有技术先进,测量精度高,数 据容量大,遥测距离远,可靠性高的优点。

(1) 具有多种供电方式,交直流两用或配太阳能电池供电

(2) 用于对风速、空气温湿度、光照强度等气象要素进行全天候现场监测。可以 通过专业配套的数据采集通讯线与计算机进行连接,将数据传输到气象计算 机气象数据库中,用于统计分析和处理。

(3) 由气象传感器、气象数据记录仪、电源系统等部分构成。风速、雨量、大气 压力等传感器为气象专用传感器,具有高精度高可靠性的特点。

(4) 有线传输方式:通过标准 USB/RS485 通信接口,与监测中心 PC 机有线连接

(5) 无线传输方式:只要可以上网就可通过 GPRS/NB/LTE 无线传输

(6) 信息管理规范真实高效:实时更新,数据库方式存储,根据需要在前台显示

(7) 简单易用:数字农业监测系统强调易用性与实用性的完美结合。

1.4 关键性能指标

(1) CRC 校验:对数据进行多项式计算,并将得到的结果附在帧的后面,接收设 备也执行类似的算法,以保证数据传输的正确性和完整性。

(2) 数据转化:可以自动进行数据帧采集处理,只要上电就自动进行数据转化

(3) 连接腾讯云:MCU 或者 PC 机向广和通 L610 发送 AT 指令实现与腾讯云连 接。

(4) 系统采用出错冗余技术,保证运行的安全性。

(5) 响应时间:气象站向 MM32 主控板发送数据到用户收到数据延迟最低 500ms.

1.5 主要创新点

(1) 生产环境实时监测, 自动报警

(2) 通过在农业生产现场部署物联网设备(如采集器和传感器),可以实时采集 和监测环境数据和设备状态数据,并上传到云端。用户可通过手机或电脑登 录数字农业监测系统平台,查看园区气象数据、土壤数据和设备状态。当出 现高温、高湿等异常情况时,系统会自动报警,提醒工作人员及时处理,否 则系统会自动排除异常。

(3) 数据共享:通过广和通上传到腾讯云、微信小程序,只需要分享链接便可以 多人实时观测。

(4) 可视化数据大屏:可以量化分析各项参数,同时显示警告信息。

第二部分 系统组成及功能说明

2.1 整体介绍

气象采集仪 主体部分

数字农业监测系统数据大屏显示页面

2.2 各模块介绍

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 完成情况

已能够通过气象采集仪采集相关环境参数(如图 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 所示)。

3.2 性能参数

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

第四部分 总结

4.1 可扩展之处

将物联网应用于农业,推动我国的传统产业改造升级,为我国的农业发展提 供了一个全新的发展平台,实现我国农业现代化,信息化、智能化的发展,这是 一个大而复杂的课题,未来还有很长的路要走。本文的设计的基于物联网技术的 数字农业监测系统,只是实现了简单的数据传输和监测数据的功能,演示系统过 程中发现,由于实际农业生产环境的复杂性,所以尽管在实验室能够实现农田环 境参数监测系统的部分功能,但是将系统应用于实际生产环境还需要进一步努力 改善系统。该系统还可以在以下几个方面展开进一步的扩展:

(1)本系统的协调数据器节点采用串口连接方式向上位机传输数据,协调 器节点必须与计算机终端相连,具有一定的局限性,可以引用GPRS/Wi-Fi 等技 术,实现协调器节点与计算机终端的远端通信。

(2)本系统只是简单实现了对种植园环境信息的实时监测,未来可以添加 执行装置的控制设备,监测到的实时信息,对农业灌溉等设备进行远程控制,达 到真正的智能化管理。

(3)提高数据资源综合利用水平。建设与物联网平台相结合的大数据分析 平台,以农业物联网数据采集为数据基以其他涉农业务数据为分析要素,综合农 业生产及产业结构特点,实现真正大数据应用指导农业生产、指导产业发展的新 格局。

(4)本系统在远程监控端只研发了上位机控制界面,需要通过 Internet 登 录管理界面进行查看,后续可以设计一款手机 APP 监控界面,让操作人员可以 随时随地进行种植园信息的查看。系统后期可增加大数据分析模型,建设智慧农 业综合平台,添加更多种类的传感器和控制装置,应用推广到更广领域的智慧农 业领域。

(5)在系统后续的开发中可以增加几类传感器来检测其他环境因素,例 PH 值 H 值,EC 值等。但伴随着传感器采集数据类型的增加以及传感器节点数的增 加,对微控制器的处理数据能力要求更加严格时,可以采用嵌入 ARM 系统开 发功能或者处理能力更强的处理器。

4.2 心得体会

农业是物联网技术的重点领域之一,物联网应用在农业的应用上已经引起了 广泛的关注。该系统针对感知控制系统、云端数据库和微信小程序等进行设计并 验证,可实时监测种植园的空气温湿度、光照强度、土壤温湿度等各项数据,为 从业人员提供全面的参考,便于从业人员的管理,降低生产成本。该系统具有扩 展性好,性价比高等优势,具有很高的实用价值。

我们通过参加本次嵌入式芯片与系统设计竞赛,学到了很多,像是 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.

第六部分 附录

6.1 、转化气象数据以及 CRC 冗余校验的代码

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. u8bitOne,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. u8bitOne,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.

bitFour=UART_RX_BUF[13]&0x0F;

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.

while(strx==NULL)

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. }

212. }

posted @ 2025-06-10 22:12  陶志霖找工作专用  阅读(30)  评论(0)    收藏  举报