热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

自制APP连接OneNET实现数据监控和下发控制(MQTT)

文章目录前言一、前期准备二、功能介绍1、自制APP页面展示2、串口助手界面3、OneNET平台显示三、单片机端功能实现1、修改OneNET官方提供的例程2、主函数代码3、上传数据到

文章目录

  • 前言
  • 一、前期准备
  • 二、功能介绍
    • 1、自制APP页面展示
    • 2、串口助手界面
    • 3、OneNET平台显示
  • 三、单片机端功能实现
    • 1、修改OneNET官方提供的例程
    • 2、主函数代码
    • 3、上传数据到APP
    • 4、命令处理
  • 四、APP端功能实现
    • 1、连接MQTT服务器
    • 2、实现订阅与发布
    • 3、APP显示数据
    • 4、APP下发命令
  • 总结




前言

本案例主要实现的功能是自制手机APP连接OneNET的MQTT服务器,同时接收和显示单片机的数据,对单片机上LED灯进行远程控制。
虽说OneNET上有应用管理,可以实现手机端控制单片机,但是这样做有点简单,达不到毕设水平,课设勉强可以及格。如果是自己做一款APP来控制单片机,顿时高大上很多。



一、前期准备

1、STM32F103C8T6最小系统板
2、ESP8266-01S模块
3、在OneNET平台上创建MQTT协议的产品和创建两个设备
4、安装E4A软件,软件不大几百兆下载链接

二、功能介绍

1、自制APP页面展示

由于是连接OneNET的MQTT服务器,故地址端口是固定不变的。
产品ID、设备ID、鉴权信息可以在OneNET平台上获取,这个不必多说。
订阅按钮:订阅主题为EndTopic的主题
发布按钮:发布主题为AppToic的消息,消息内容是123456
三个绿色框分别是光照值、温度值、湿度值。这里的温湿度做了自增处理,不是实际温湿度。
第一个开关:发布主题为AppToic的消息,消息内容是KEY:1或KEY:0
第二个开关:发布主题为AppToic的消息,消息内容是LED1:1或LED1:0

2、串口助手界面

1、EndTopic是单片机端发布消息的主题
2、{“Light”:152.7,“Temp”:104,“Humi”:104}是消息的内容
3、AppTopic是来自APP端发布的消息主题
4、KEY:1是消息内容
在这里插入图片描述

3、OneNET平台显示

APP端和单片机端的设备都显示在线。
在这里插入图片描述

三、单片机端功能实现

1、修改OneNET官方提供的例程

(1)将芯片型号由原先的STM32F103RC更改为STM32F103C8
(2)在全局宏定义中将STM32F10X_HD更改为STM32F10X_MD
(3)将原先的startup_stm32f10x_hd.s的启动文件移除,添加startup_stm32f10x_md.s的
启动文件
(4)在stm32f10x.h文件中,将HSE_VALUE宏的值由原先的12M改为8M
(5)在onenet.c文件上方的三个宏定义分别填入连接平台的三要素
(6)在esp8266.c中,定义了系统需要连接热点名称和密码
(7)从其他例程中移植OneNet_SendData();函数
(8)移植传感器采集数据和LED(PC13)的初始化代码
在这里插入图片描述

2、主函数代码

int main(void)
{unsigned short timeCount = 0; //发送间隔变量unsigned char *dataPtr = NULL;Hardware_Init(); //初始化外围硬件ESP8266_Init(); //初始化ESP8266while(OneNet_DevLink()) //接入OneNETDelayXms(500);Beep_Set(BEEP_ON); //鸣叫提示接入成功DelayXms(250);Beep_Set(BEEP_OFF);OneNet_Subscribe(SubTopics, 1);while(1){if(++timeCount >= 300) //发送间隔3s{//UsartPrintf(USART_DEBUG, "OneNet_Publish\r\n");light = LIght_Intensity(); //读取光照强度的值//可以在这读取温湿度值OneNet_SendData();//发送数据到手机APPtimeCount = 0;ESP8266_Clear();}dataPtr = ESP8266_GetIPD(0); if(dataPtr != NULL)OneNet_RevPro(dataPtr); //下发命令处理DelayXms(10);}
}

3、上传数据到APP

上传数据相关代码如下:

void OneNet_SendData(void)
{char buf[256];memset(buf, 0, sizeof(buf));OneNet_FillBuf(buf); //封装数据流//ESP8266_SendData((unsigned char *)buf, strlen(buf)); //上传数据OneNet_Publish(PubTopics, buf); //发布消息
}

数据封装函数
这个函数的功能是将需要上传的数据打包成JSON格式。

extern u8 temp,humi;
extern float light;
extern const char PubTopics[] ; //发布主题
unsigned char OneNet_FillBuf(char *buf)
{char text[16];memset(text, 0, sizeof(text));strcpy(buf, "{");memset(text, 0, sizeof(text));sprintf(text, "\"Light\":%.1f,",light);strcat(buf, text);memset(text, 0, sizeof(text));sprintf(text, "\"Temp\":%d,", temp++);strcat(buf, text);memset(text, 0, sizeof(text));sprintf(text, "\"Humi\":%d", humi++);strcat(buf, text);strcat(buf, "}");return strlen(buf);
}

4、命令处理

当接收到来自APP端下发的命令后,会调用下发命令处理函数OneNet_RevPro(),在该函数内根据消息内容对单片机进行控制。
函数内部的部分代码如下:

dataPtr &#61; strchr(req_payload, &#39;:&#39;); //搜索&#39;:&#39;if(dataPtr !&#61; NULL && result !&#61; -1) //如果找到了{dataPtr&#43;&#43;;while(*dataPtr >&#61; &#39;0&#39; && *dataPtr <&#61; &#39;9&#39;) //判断是否是下发的命令控制数据{numBuf[num&#43;&#43;] &#61; *dataPtr&#43;&#43;;}num &#61; atoi((const char *)numBuf); //转为数值形式if(strstr((char *)req_payload, "LED1")) //搜索"LED1"{UsartPrintf(USART_DEBUG,"LED1 &#61; %d\r\n", num); //num就是LED1:V 中V的值LED1 &#61; !num; //控制LED灯&#xff0c;低电平点亮}else if(strstr((char *)req_payload, "KEY")) //搜索"KEY"{UsartPrintf(USART_DEBUG,"KEY &#61; %d\r\n", num);}//继续else if添加其他命令}

四、APP端功能实现

这部分主要讲如何制作手机APP连接OneNET平台&#xff0c;并且获取数据和下发命令控制LED灯。APP是使用E4A中文安卓编程开发的&#xff0c;编程思维和C语言很相似&#xff0c;并且是中文编程&#xff0c;只需一天就能基本掌握。

1、连接MQTT服务器

接入云平台主要依靠的是E4A上面的mqtt通讯组件&#xff0c;这个组件命令有八个方法&#xff0c;七个事件。从单片机编程的角度来看&#xff0c;方法相当于函数&#xff0c;可以人为的去调用&#xff0c;事件相当于中断&#xff0c;不需人为调用。而连接OneNET的MQTT服务器就使用了连接服务器方法。
连接服务器方法的调用需要传入七个参数&#xff0c;参数一是服务器地址端口&#xff0c;即OneNET的MQTT服务器地址和端口&#xff1b;参数二填入产品ID&#xff1b;参数三填入鉴权信息&#xff1b;参数四填入设备ID&#xff1b;通过点击连接按钮&#xff0c;就可以调用连接服务器方法&#xff0c;实现接入云平台的功能。

事件 连接按钮.被单击()如果 连接按钮.标题 &#61; "连接" 则 &#39; 产品ID框.内容为空会闪退连接按钮.标题 &#61; "断开"mqtt通讯1.连接服务器(地址端口框.内容,产品ID框.内容,鉴权信息框.内容,设备ID框.内容,,,5)否则 连接按钮.标题 &#61; "连接"mqtt通讯1.断开连接()结束 如果结束 事件

2、实现订阅与发布

订阅和发布分别使用mqtt通讯组件中的订阅消息和发布消息的方法&#xff0c;通过对应的按钮单击事件分别调用这两个方法。
订阅与发布程序编写如下所示。

事件 订阅按钮.被单击()mqtt通讯1.订阅消息(订阅主题框.内容,0)结束 事件事件 发布按钮.被单击()mqtt通讯1.发送消息(发布主题框.内容,文本到字节(发布消息框.内容,"UTF-8"),1,)
结束 事件

订阅消息方法的调用要传入两个参数&#xff0c;参数一是订阅的主题&#xff0c;为了接收单片机端发布的主题消息&#xff0c;这里订阅的是“EndTopic”&#xff1b;参数二是消息策略&#xff0c;可以填入0、1、2&#xff0c;这里填入0&#xff0c;表示只会发送一次推送消息&#xff0c;收不收都不关心&#xff0c;这是因为单片机端会多次发布主题消息&#xff0c;故不需要每次都要接收到。
发布消息方法的调用要传入四个参数&#xff0c;参数一是消息主题&#xff0c;这里填“AppTopic”;参数二是消息内容&#xff0c;参数三是消息策略&#xff0c;这里填入1

3、APP显示数据

由于单片机端发布的消息不只有光照值&#xff0c;还有温湿度等内容&#xff0c;为了方便解读出数据&#xff0c;在单片机端将这些数据打包为JSON格式&#xff0c;然后再发布出去。
当APP端收到消息后&#xff0c;就会触发mqtt通讯里面的收到消息事件&#xff0c;在这事件里面&#xff0c;我们利用E4A中的JSON操作组件对消息内容进行解析&#xff0c;将解析处理的内容存放在JSON对象里面&#xff0c;然后使用JSON操作组件里面的取文本值方法获取JSON对象里指定数据成员的值&#xff0c;最后将这个值赋值给对应的显示标签。
收到消息事件程序编写如下所示

事件 mqtt通讯1.收到消息(消息主题 为 文本型, 消息内容 为 字节型(), 消息策略 为 整数型)接收框.内容 &#61; 接收框.内容 & "\n" & "主题&#xff1a;" & 消息主题 & "\n内容&#xff1a;" & 字节到文本(消息内容,"UTF-8") & "\n策略&#xff1a;" & 消息策略接收框.置光标位置(取文本长度(接收框.内容))&#39;开始json解析变量 JSON对象 为 对象JSON对象 &#61; JSON操作1.解析(字节到文本(消息内容,"UTF-8"))调试输出("JSON成员数&#xff1a;" & JSON操作1.取成员数(JSON对象))光照值标签.标题 &#61; "Light&#xff1a;" & JSON操作1.取文本值(JSON对象 , "Light")温度值标签.标题 &#61; "Temp&#xff1a;" & JSON操作1.取文本值(JSON对象 , "Temp")湿度值标签.标题 &#61; "Humi&#xff1a;" & JSON操作1.取文本值(JSON对象 , "Humi")结束 事件

4、APP下发命令

这里以灯光开关的控制为例子&#xff0c;其他控制功能类似。灯光开关组件状态被改变事件程序如下所示。

事件 开灯按钮.被单击()如果 连接按钮.标题 &#61; "连接" 则 &#39;未连接时退出事件退出结束 如果如果 开灯按钮.标题 &#61; "开灯" 则开灯按钮.标题 &#61; "关灯"mqtt通讯1.发送消息(发布主题框.内容,文本到字节("LED1:1","UTF-8"),1,)否则 开灯按钮.标题 &#61; "开灯" mqtt通讯1.发送消息(发布主题框.内容,文本到字节("LED1:0","UTF-8"),1,)结束 如果结束 事件

单片机端接收到由APP端发布出来的消息后&#xff0c;会通过消息解包函数取出数据包的主题、消息内容、消息策略&#xff0c;如果消息策略是1就先回复Ack给服务器&#xff0c;然后再判断消息内容里面有没有程序设计好的命令字符串&#xff0c;如果有就执行相应的程序。



总结

有需要的话&#xff0c;可以问我拿源码&#xff0c;我有空就会回复。
代码下载链接放这里了&#xff1a;https://github.com/J-CHUN/OneNET-MQTT-APP.git


推荐阅读
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 电话号码的字母组合解题思路和代码示例
    本文介绍了力扣题目《电话号码的字母组合》的解题思路和代码示例。通过使用哈希表和递归求解的方法,可以将给定的电话号码转换为对应的字母组合。详细的解题思路和代码示例可以帮助读者更好地理解和实现该题目。 ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
author-avatar
白堤柳帘佳_688
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有