安防监控项目---通信结构体设计


前言

书接上次项目概要,本期和大家主要分享的此项目中通信结构体的设计,那么这部分是非常重要的,可以说,在了解清楚了项目需求之后,接下来软件设计中通信结构体的设计是非常重要的一环!本期只介绍关于结构体的设计,后期各个模块的具体实现中再带大家来看具体结构体在软件中的巧妙用处!


一、分层意识

1.web网页显示
环境信息:实时刷新
(1)ADC电压数据
(2)MPU6050的六轴数据
(3)温度和湿度
摄像头:实时刷新视频流
硬件控制:web指令下发至A9
(1)风扇
(2)蜂鸣器
(3)LED
(4)GPRS
2.A9数据处理
在主进程中创建各个线程,比如zigbee、LED、蜂鸣器、姿态传感器、ADC等硬件设备的具体处理线程,也包括数据刷新线程和客户端请求线程;
3.zigbee采集部分
这里主要是通过A9平台上传ADC,姿态传感器,以及zigbee平台的温湿度信息,这里大家也可以自主进行扩展;

二、数据流

数据上传:共享内存
指令下发:消息队列

三、应用场景

此项目可以应用于家庭的安防监控,工业工厂监控,校园环境监控等多个监控场所;

3.1 A9平台:


蜂鸣器:蜂鸣器报警
LED灯:卧室-厕所-楼道-公共照明-----LED2-LED3-LED4-LED5
按键:按键触发中断—控制卧室和厕所灯-----LED2-LED3
ADC:获取ADC的采样数据
mpu6050:获取MPU6050的六轴数据

#define		GPRS_DEV   		 "/dev/ttyUSB0"
#define		ZIGBEE_DEV 		 "/dev/ttyUSB1"
#define		BEEPER_DEV 		 "/dev/fsbeeper0"
#define		LED_DEV    		 "/dev/fsled0"

3.2 zigbee


adc:协调器
风扇:终端节点 下发命令控制风扇
温湿度:终端节点 上传温湿度数据

四、通信结构体具体设计及分析

4.1 数据上传

	数据类型定义: 	
		typedef uint8_t  unsigned char;
		typedef uint16_t unsigned short;
		typedef uint32_t unsigned int;

		//考虑到内存对齐的问题,zigbee平台的相关数据
		struct makeru_zigbee_info{
				uint8_t head[3]; //标识位: 'm' 's' 'm'  makeru-security-monitor  
				uint8_t type;	 //数据类型  'z'---zigbee  'a'---a9

				float temperature; //温度
				float humidity;  //湿度
				float tempMIN;//温度下限
				float tempMAX;//温度上限 
				float humidityMIN;   //湿度下限
				float humidityMAX;   //湿度上限
				uint32_t reserved[2]; //保留扩展位,默认填充0
				//void *data;  内核预留的扩展接口  参考版
		};
		
		//A9平台的相关数据
		struct makeru_a9_info{
			uint8_t head[3]; //标识位: 'm' 's' 'm'  makeru-security-monitor  
			uint8_t type;	 //数据类型  'z'---zigbee  'a'---a9
			uint32_t adc;
			short gyrox;   //陀螺仪数据
			short gyroy;
			short gyroz;
			short  aacx;  //加速计数据
			short  aacy;
			short  aacz;
			uint32_t reserved[2]; //保留扩展位,默认填充0
			//void *data;  内核预留的扩展接口  参考版
		};
		
		struct makeru_env_data{
			struct makeru_a9_info       a9_info;    
			struct makeru_zigbee_info   zigbee_info;
		};
		
		//所有监控区域的信息结构体
		struct env_info_client_addr
		{
			struct makeru_env_data  monitor_no[MONITOR_NUM];	//数组  老家---新家 MONITOR_NUM表示家的数量,此项目只有一个家,所以不存在家的切换
		};
		

4.2 数据下发

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
		//消息队列用于通信的结构体: 包括数据类型和数据
		
将消息队列封装成函数,直接通过参数传递的方式来发送信息: 
int send_msg_queue(long type,unsigned char text)
{
	struct msg msgbuf;
	msgbuf.type = 1L;
	msgbuf.msgtype = type;   //具体的消息类型
	msgbuf.text[0] = text;   //控制命令字 
	if(msgsnd(msgid,&msgbuf,sizeof(msgbuf) - sizeof(long),0) == -1){
		perror("fail to msgsnd type2");
		exit(1);
	}
	return 0;
}
		
struct msgbuf {
       long mtype;       /* message type, must be > 0 */
       char mtext[1];    /* message data */
};

//消息队列结构体
#define QUEUE_MSG_LEN 32                 
struct msg
{
	long type;   //从消息队列接收消息时用于判断的消息类型  ==== 暂时不用 1L===home1  2L===home2 ... 
	long msgtype;//具体的消息类型 === 指代控制的设备,是什么类型的设备
	unsigned char text[QUEUE_MSG_LEN];//消息正文  ====> CMD 控制指定的设备
};
		
		long msgtype;//具体的消息类型
		消息类型的分配:
			1L: 		LED控制
			2L:			蜂鸣器控制
			3L:			四路LED灯模拟的数码管
			4L:			风扇
			5L:			温湿度最值设置
			6L-7L-8L-9L,用于个人的扩展
			10L: 		3G通信模块-GPRS 
		switch(msgbuf.msgtype){
			case 1L: ...  break;
			....
			default ....  break;
		}

4.3 控制命令字的制定

消息队列接收消息:
			msgrcv (msgid, &msgbuf, sizeof (msgbuf) - sizeof (long), 1L, 0);
解析buf中的数据:
			printf ("Get %ldL msg\n", msgbuf.msgtype);
			printf ("text[0] = %#x\n", msgbuf.text[0]);

A9-ZIGBEE通用指令
		命令格式:一个字节,unsigned char 
		对应消息队列中正文的类型:unsigned int 
		----------------------------------------
		7	6	|  5	4	|	3	2	1	0
		平台编号|  设备编号 |	操作设备
		----------------------------------------
		 
		平台编号	
		0x00		0-ZigBee平台 
		0x40		1-A9/A53平台
		0x80		2-STM32平台(可以自己扩展)
		0xc0		3-avr arduino....保留
		(如果平台继续增多的话可以采用2个字节或多个字节来对设备进行唯一的编号,
		比如A9类下的1号平台,2号平台,先分类,然后再具体标识设备)
		
		----------------------------------------		
		设备编号		操作掩码	
		0x00	LED		0x00	全部关闭
						0x01	全部打开
						0x02	打开LED2
						0x03	打开LED3
						0X04	打开LED4
						0x05	打开LED5
						0X10	打开流水灯
		----------------------------------------
		0x10	蜂鸣器	0x00	关闭
						0x01	打开
						0x02	自动报警关闭
						0x03	自动报警打开
		----------------------------------------
		0x20	风扇	0x00	关闭风扇
						0x01	打开风扇
		----------------------------------------			
		0x30	数码管	0x0~0xF	    显示0~F数字(四盏灯,对应0000-表示0,0001-表示1....1110-表示14)
						0x0f		关闭数码管				led2-3-4-5
		----------------------------------------
		
		控制命令:		
			平台编号 + 设备编号 + 操作掩码 = 命令 (命令的封装)
			例如:
					0x00 + 0x20 + 0x01 = 0x21   风扇打开
 
					0x40 + 0x10 + 0x01 = 0x51   蜂鸣器打开
					0x40 + 0x30 + 0x08 = 0x78   数码管显示8
					0x40 + 0x30 + 0x0f = 0x7f   关闭数码管
					
					a 高位数据,b代表低位数据

上行:封装的结构体----共享内存和信号量 —交给CGI(C语言和HTML语言之间的转化接口)—交给HTML
下行:封装的命令字----消息队列 ----msgbuf msgsnd----控制命令字封装在msgsnd的msgbuf中 —A9端解析—向下控制硬件


总结

到此为止呢所有的通信结构体就已经设计完成了,最终呢很显然将A9所有的数据对象成了一个以家为单位的结构体,而这个结构体又包括了A9平台和zigbee采集数据的两个结构体,那么这两个结构体又仔细划分就是具体的数据对象了,比如ADC电压数据,温湿度数据;数据的下发是通过消息队列下发的,也定义了消息队列的结构体,这里需要注意的是结构体中第一个类型是必须有的,此项目中这个类型既作为消息队列的发送消息类型,也作为哪一个家(当然此项目只涉及到一个家,所以一直是类型1L,当有两个家时那么消息队列的类型就可以创建一个2L类型的);最后呢是控制命令字的设计,这个也是我在这个项目中学习到的一个非常好的设计思想,极大的提高了效率,可扩展、也可高效管理多个平台以及多个平台下的具体设备;这写呢时很好的设计思想,将采集对象在软件设计中模块化,从而提高开发效率,便于管理和代码编写,是良好的项目代码风格!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值