STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现

文章目录

  • 前言
  • 一.软件安装
  • 二.代码改进
    • 1.串口接收
    • 2.JSON数据解析
  • 三.云产品流转
    • 1.作用
    • 2.自定义产品功能&添加设备
    • 3.创建数据传输规则
  • 四.MYSQL操作
  • 五.NODE-RED操作
    • 1.总体思路
    • 2.安装节点
    • 3.节点配置
    • 4.页面布局
  • 结语


前言

本篇分享:

前几篇博客分享了STM32MP157实现串口接收数据上云,实现了STM32MP157的串口在接收到数据时能上传至服务器,让用户可以随时随地查看一个设备的实时信息。

本篇要分享的是如何在之前的基础上更进一步,实现云数据库存储多设备数据以及界面显示


准备工作:

一.软件安装

整个过程的实现大体思路是:
数据–>STM32MP157–>云平台–>NODE-RED–>MYSQL

为了实现多设备数据存储云数据库并实现界面显示,这里需要在服务器安装两个必要的软件:MYSQL、NODE-RED用于实现数据存储和界面显示,并且推荐安装宝塔Linux面板和phpMyAdmin数据库可视化操作软件,这里四个软件都用到了,所以推荐都安装,网上有很多安装教程,这里就不赘述了。

  • 必要安装:MYSQL(存储数据)、NODE-RED(连接阿里云和数据库&界面显示)
  • 推荐安装:宝塔Linux面板(安装软件方便,可一键安装MYSQL和phpMyAdmin)、phpMyAdmin(云端数据库可视化操作)

安装完软件后记得在服务器的 安全组规则中添加需要使用的端口号

  • 路径:控制台-云服务器ECS-蓝色示例名称-配置安全组规则-配置规则-添加安全组规则
  • 操作:如宝塔面板的端口范围输入9696/9696、授权对象输入0.0.0.0/0即可;NODE-RED的端口号为1880
  • 另外,在宝塔面板的安全里面同样也要放行端口(两边都要)
  • 安装软件后输入ip+端口发现页面无法打开就检查下安全组规则有没有配置

改进工作:

二.代码改进

现在将串口接收的数据也规定为JSON格式(如:{“id”:“1”,“2_CurrentVoltage”:“90”}),并解析该数据,得到所需数据进行上传。

1.串口接收

​串口则要实现一次性接收PC端串口调试助手发送的全部数据,再去进行解析
​这时,原来写的串口接收代码就无法满足要求了,接收数据时会出现如下问题:

STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第1张图片
可以看到,每当串口接收到8位数据时FD_ISSET函数就能检测到设备为可读状态,而id和电压数据可能为一位数也可能为两位数,则不可能使用接收字符个数去判断,用接收次数判断的话后续添加数据时还需要计算发送的字符个数再对次数进行更改,以上两种方法均不太可取。

​这里使用的方法则是再增加一个串口接收线程保存接收的数据并且增加两个变量rece_byte_new和rece_byte_old,当接收到数据时rece_byte_new++。在主循环中则判断rece_byte_new>0时进入一个循环,等待数据接收完,在循环体内将rece_byte_new赋值给rece_byte_old,循环延时的时间设置为比串口接收8位数据稍大的时间(这个时间很重要,不能太大也不能太小,太小接收不完8位数据就去判断old和new是否相等会导致提前退出循环,太大会降低接收效率消耗不必要的时间,根据波特率115200计算,串口接收8位数据约为520us,这里设置为650us),这样无论数据多长这里都不需要进行更改,直到rece_byte_new和rece_byte_old相等时退出循环,继续执行后续的数据解析。代码如下:

/*相关头文件*/
#include 
#include 

/*全局变量*/
char rece_data[256];

/*创建进程*/
pthread_t id2;
pthread_create(&id2,NULL,serial_lsd2,&serportfd_PC);//创建线程

/*串口接收外部数据线程*/
void *serial_lsd2(void *d)
{
    int tfd=*(int *)d;
    char rec_data[64];
    fd_set rd;
    
    while (1)
    {
        FD_ZERO(&rd);//清空rd
        FD_SET(tfd,&rd);//将tfd添加进rd中
        if(select(tfd+1,&rd,NULL,NULL,NULL)<0)//检查设备是否可读
            perror("select");
        if(FD_ISSET(tfd,&rd))//如果可读则读取并打印数据
        {
            rece_byte_new++;//为1时表示刚接收到数据
            while(read(tfd,rec_data,1)>0)
            {
                strcat(rece_data,rec_data); //字符串拼接
            }  
        }
    }
}

/*主循环相应代码*/
if(rece_byte_new > 0)//大于0即为接收到数据
{
    while(rece_byte_new != rece_byte_old)//只要串口还有数据接收这两个变量就不会相等
    {
        rece_byte_old = rece_byte_new;//将new赋值给old
        usleep(650);//等待串口接收数据,当串口不再接收数据时,old==new,循环结束
    }
    rece_byte_new = 0;//清零
    rece_byte_old = 0;//清零
    printf("Successfully received data!\n");//成功接收数据提示
    //后续代码-数据解析
}

2.JSON数据解析

​当接收到JSON格式的数据后该如何对数据进行解析,提取出AT指令(发送消息到云平台)所需的数据呢?

​这里我先是使用了cJSON第三方库进行解决,解决步骤就是将接收到的字符串转化成JSON对象,再调用cJSON_GetObjectItem对相应字段后的数据进行提取,提取后再用cJSON_Print函数将其转为字符串。但由于提取出的字符串自带引号,串口又不能直接发送引号,这里又需要用到sscanf函数对字符串进行提取,稍微有点麻烦……

​所以,我直接使用了sscanf函数对数据进行提取……

while(1)
{
    //代码-等待数据接收完成
    sscanf(rece_data,"{\"id\":\"%d\",\"%d_CurrentVoltage\":\"%d\"}",&int_id,&int_identifier,&int_CurrentVoltage);
    send=1;//数据发送标志位置1
    if(int_id <= 0 || int_CurrentVoltage <= 0 || (int_id != int_identifier))//检测接收数据是否有误
    {   
        printf("data error\n");
        send=0;//有误则不发送
    } 
    if(send==1)//数据无误则向云平台发送数据
    {
        sprintf(send_data,"AT+MPUB=\"/sys/a1cdabcdRA0/863412344279453/thing/event/property/post\",1,0,\"{\\22id\\22:%d,\\22params\\22:{\\22%d_CurrentVoltage\\22:%d},\\22version\\22:\\221.0\\22,\\22method\\22:\\22thing.event.property.post\\22}\"\r",int_id,int_identifier,int_CurrentVoltage);
        write(serportfd_4G,send_data,strlen(send_data));//向4G模块发送AT指令
    }
    memset(rece_data,0,sizeof(rece_data));//清空rece_data
}

转发工作:

三.云产品流转

1.作用

在设备接收到数据后,将该数据转发至NODE-RED

2.自定义产品功能&添加设备

​在上面代码中出现了%d_CurrentVoltage是因为我在阿里云对产品新增了两个功能,用于显示两台设备的数据,标识符分别为1_CurrentVoltage2_CurrentVoltage。另外,为了后续连接云数据库还需要增加一个NODE-RED设备用于MQTT通讯。

​添加产品功能和设备的方法之前讲过了,这里就简述下:

  • 添加自定义功能:产品-Air724(产品名)-功能定义-编辑草稿-添加自定义功能-发布上线。
  • 添加设备:设备-添加设备,产品选同类型即可,DeviceName 我这里设置为NODE-RED
    STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第2张图片

3.创建数据传输规则

​接着,需要进行数据传输规则的创建,在规则引型中找到云产品流转。

STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第3张图片
点击回到旧版,旧版使用较方便(新版还没用过:_)

STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第4张图片
点击创建规则数据格式选JSON,其他可以自己定义。

STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第5张图片
STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第6张图片
点击编写SQL,字段输入*(即转发接收到的所有数据),Topic选择物模型数据上报,设备选择接收板子上传数据的那个设备,再选择我们AT指令中发送的Topic:thing/event/propert/post,点击确认。

STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第7张图片
再点击添加操作。

STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第8张图片
操作选择发布到另一个Topic,Topic选择NODE-RED的user/get,点击确认。

STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第9张图片
返回到云产品流转界面,点击启动即可。

STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第10张图片
存储工作:

四.MYSQL操作

这里讲一下MYSQL可视化的操作(终端操作直接调到下方根据表结构建表即可),安装完宝塔面板后,在软件商店中安装MYSQLphpMyAdmin
STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第11张图片
安装完后,在数据库中找到phpMyAdmin,点击通过面板访问。

STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第12张图片
登录需要输入MYSQL的用户名和密码,安装完的MYSQL有默认用户名和密码,网上有查询教程。之前安装过的,就输入数据库登录的用户名和密码即可。

​点击新建一个数据库。

STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第13张图片
新建两个数据表存储不同设备数据(一张表存储一个设备数据,多个设备就建多张表)。

STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第14张图片
输入字段名,可以添加一个id的字段让其自增作为主键,这样后续就可以对数据表进行删除和编辑等操作。

STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第15张图片创建完成后继续在左边选择新建数据表,再新建一个表device_2,结构和上表相同即可。

STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第16张图片
连接&显示工作:

五.NODE-RED操作

1.总体思路

NODE-RED这边的总体思路就是接收云平台发送的数据,将数据发送至函数处理,在函数节点将数据进行提取处理成SQL语句后发送至MQSQL节点实现数据的存储;另外用switch节点(功能类似c语言中的switch),根据id去决定更新界面中的设备1电压表还是设备2电压表数据。

2.安装节点

​安装好NODE-RED后输入服务器ip:1880打开NODE-RED,可以看到左边为NODE-RED节点栏,这里可以找到需要的节点并直接拖出到中间即可配置使用(中文设置在右上角三条横杠的设置中)。

​这里需要用到的MYSQL节点dashboard节点原本都没有,需要自行下载。点击右上角三条横杆-节点管理-安装,搜索node-red-dashboardnode-red-node-mysql安装即可,想用table的节点的话需要另外安装node-red-node-ui-table(之前一直奇怪为什么我的dashboard没有table这个节点)

STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第17张图片

3.节点配置

  • mqtt in节点

    mqtt in节点的作用是实现NRED-RED与云平台的MQTT通讯。在节点栏里找到网络下面的mqtt in节点并拖出,双击节点,点击服务端后面的编辑图标。

    STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第18张图片
    点开后,需要配置的有连接中的服务端和客户端ID安全中的用户名和密码,如何获取这些参数可以看下之前4G设备向云发送数据中的2.连接阿里云操作,名称自定义即可,设置好后返回上图这个界面再将主题补充完整(填云产品流转的转发数据中设置的那个Topic)。配置完后点击完成,再点击NODE-RED右上角的部署,部署完后看到mqtt in节点下方出现已连接即为成功

  • mysql节点

    mysql节点的作用是,实现NODE-RED与MYSQL的连接。安装完MYSQL节点后,在左侧节点栏存储中找到mysql节点并拖出,双击mysql节点,点击编辑,配置MYSQL的Host(MYSQL和NODE-RED安装在同一服务器下输入服务器ip或127.0.0.1均可)、端口号(MYSQL默认端口号)、登录用户名密码以及要连接的数据库名称配置好后点击部署,部署完后mysql节点下方出现connected即为成功

    STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第19张图片

  • function节点

    function节点的作用主要是对数据的处理。在左侧节点栏功能中找到function节点并拖出,双击function节点,可以在函数的文本编辑框中用JS语言编写代码,这部分代码主要要实现的功能是对从阿里云发送的数据进行提取,再组合成一条SQL语句,再发送至MYSQL数据库进行执行,从而达到数据存储的目的。

    STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第20张图片
    具体代码如下所示:

/*定义插入数据SQL语句*/
var find = "INSERT INTO `db_devices2`.`device_%s` (`CurrentVoltage`) VALUES ('%s')"

/*根据设备补充SQL语句*/
if (msg.payload.requestId == 1)//如果设备id为1
{
    var newMsg = {
        // @ts-ignore
        "topic": util.format(find, msg.payload.requestId, msg.payload.items["1_CurrentVoltage"].value )//用format函数将接收到的数据对SQL语句进行补充(如果对JSON不熟悉,可以用debug得到数据所在路径,下面在debug节点中介绍)
    }
}
else if (msg.payload.requestId == 2)//如果设备id为2
{
    var newMsg = {
        // @ts-ignore
        "topic": util.format(find, msg.payload.requestId, msg.payload.items["2_CurrentVoltage"].value )
    }
}

/*赋值并返回*/
msg.topic = newMsg.topic
return msg;
  • debug节点

    debug节点在左侧节点栏的共通中,其作用是接收前面节点输出的数据并在调试窗口进行显示

    在完成mqtt in、function、mysql三个节点的配置后,可以在mqtt in以及function节点后连接一个debug节点,方便用户查看接收的数据是否准确。

    这里连接好点击部署,并运行开发板程序向云平台发送数据,测试数据是否可以正常插入数据库。

    STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第21张图片
    可以看到在数据发送成功后,NODE-RED右侧的调试窗口打印出了相关信息,这些就是NODE-RED接收到云平台转发的数据。

    STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第22张图片
    这时候,可以看到debug3正确打印了SQL语句,查看MYSQL数据库,发现数据已成功存储。

    STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第23张图片
    在function函数内不知该如何写数据路径时,可以使用debug得到,比如需要value的路径,方式如下图所示。

    复制得到的结果为payload.items[“1_CurrentVoltage”].value,然后==在payload前加上msg.==即可。

    STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第24张图片

  • switch节点

    switch节点在左侧节点栏的功能中,作用类似于c语言当中的switch-case,配置方法就是在属性处输入想要判断的变量,在下方输入具体的值即可。

      ![在这里插入图片描述](https://img-blog.csdnimg.cn/bcf2a6f2416a41b3b379fdeac429313b.png#pic_center)
    

    每增加一个项switch节点后都会多出一个数据输出口,将光标放在上面可以看到该输出口具体信息。

    STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第25张图片

  • gauge节点

    gauge节点在左侧节点栏的dashboard中,部署后可以在ui界面显示一个表盘,将想要展示的数据以表盘形式展示
    同样的,路径在右侧复制后前面加上msg.,粘贴至Value format处并在两端加上两个大括号(如下图)。
    Units处输入想要的单位即可。
    Label即为该表盘的名称。
    Group点击旁边的编辑按钮,NameTab自定义即可。

    STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第26张图片
    配置完成后点击部署,在浏览器中新建一个标签页,在网址栏中输入ip:1880/ui即可访问NODE-RED的ui界面,设备1的数据为刚刚上传的电压数据。

    STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第27张图片

4.页面布局

​页面的自动布局默认为“Z”字型布局,当横着放不下两个表的时候,会自动移动至下行的行首。
如果不想让其自动布局,可以点击这个layout进行布局

STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第28张图片
Width处可以更改页面宽度,将gauge上锁后表盘的位置可以自行拖动调节,布局成自己想要的效果。

STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第29张图片
Theme中也可以对页面风格进行调节,将页面调成自己想要的风格。

STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现_第30张图片


结语

经测试,MP157串口在接收到正确数据后,将数据上传实现云存储,并且用户可以在界面查看多个设备的实时数据;串口接收到错误数据时也会给予相应提示并且本次数据将不会上传。

至此,云数据库存储多设备数据&界面显示已成功实现。

以上就是全部内容,如有错误请批评指正。

你可能感兴趣的:(STM32MP157,stm32,单片机,数据库,物联网,嵌入式硬件)