边缘采集网关项目可实现家居物联网设备和工业物联网设备的数据采集和控制。整个项目分为三大模块:QT提供了用户界面,向用户展示设备数据,并提供用户控制操作;网关用虚拟机代替,基于Linux系统开发,起到数据中转作用,向上对接QT,向下对接设备;设备分为家居设备和工业设备两种,家居设备使用M0单片机开发板进行模拟,单片机开发板上有各种传感器和外设,工业设备使用modbus slave软件进行模拟。
实现modbus工业采集,主要是接收CGI发送到消息队列的命令,控制设备的开关,把采集到的数据上报到共享内存
代码示例如下:
#include <stdio.h>
#include <modbus.h>
#include <modbus-tcp.h>
#include <string.h>
#include <stdlib.h>
#include "shmem.h"
#include "cJSON.h"
#include "list.h"
#include <log_utils.h>
pthread_t t1, t2;
static struct shm_param para;
struct list_head *pos;
struct list_head head;
struct mb_node *tmp;
//共享内存结构体
union val_t {
int b_val; //bool类型存储空间
int i_val; //整形值存储空间
float f_val; //浮点值存储空间
};
struct std_node
{
int key; //唯一键值
int type; //数据点类型
int dev_type; //数据点属于哪个设备,根据网关支持的设备自行定义
union val_t old_val; //变化上报后需要更新旧值
union val_t new_val; //从共享内存取出最新数据,放到new_val中
int ret; //默认为-1,采集成功后设置为0,采集失败再置-1
};
//消息队列结构体
struct msg
{
long mtype;
char mdata[512];
};
//链表
struct mb_node
{
int key; //唯一键值
char name[128]; //数据点名称
int type; //数据点类型
int addr;
};
struct mb_node_list
{
struct mb_node node;
struct list_head list;
};
//数据采集
void *get_info(void *arg)
{
uint16_t data[4] = {};
uint16_t data1[2] = {};
uint8_t dest[2] = {};
int ret = -1;
ret = shm_init(¶, "main", 1024);
if (ret < 0)
{
return -1;
}
void *addr = shm_getaddr(¶);
if (addr == NULL)
{
return -1;
}
int *p = NULL;
p = addr;
printf("%d\n", p);
int *num=addr;
struct std_node *add = (addr