一、硬件环境分析

安防监控 —— 软硬件环境分析与通信协议制定-风君雪科技博客

要有分层意识数据流意识

 二、软件环境分析·

安防监控 —— 软硬件环境分析与通信协议制定-风君雪科技博客

 根据数据流向分析软件框架

软件框架也分为三部分:数据采集部分、A9数据采集与处理部分、Web显示部分

数据上行

  Zigbee —— > A9    : Zigbee采集数据 ——> 填充到结构体 ——> 数据采集线程   

  A9       —— > Web  :数据刷新线程 ——> 共享内存、信号量 ——> cgi进程 ——> html    (cgi进程完成C语言和html语言的交互)

数据下行

  Web ——> A9 : html ——> cgi进程 ——> 消息队列 ——> 主线程 __接收用户请求线程  |——>LED线程

                                             |——>蜂鸣器线程

                                                                  |——>GPRS线程

  A9 ——> Zigbee:主线程 __接收用户请求线程  |——>Zigbee线程

三、通信协议制定

 分层分析:

web网页端显示部分: 
        环境信息 === 实时刷新环境数据
        摄像头采集图像  ===  采集监控信息
        硬件控制 === 下发要去控制的命令
A9数据处理部分
        创建进程、线程
        每条线程做自己的事情
        涉及到进程间通信
        数据处理===>分发(上行数据 or 下行数据)        
A9-ZigBee数据采集部分
        A9采集部分
        ZigBee采集部分
        (STM32平台)

数据流分析·:

        数据上传:
        数据下发:
                    
    制定通信的协议(结构体):
    数据要怎么上传,上传的目的是为了什么?
    数据要怎么下发,下发的目的又是为了什么?
    
        数据的上传: ====> 共享内存上传数据 ====> 显示并交给用户查看环境信息
        数据的下发用于控制硬件:====> 消息队列下发数据 ===> 控制硬件改变环境
    

更具体的分层分析:

web网页端显示部分: 
        环境信息:          adc电压数据
                            mpu6050的六轴数据
                            温度
                            湿度
        摄像头采集图像:
                            
        硬件控制:            风扇
                            LED灯
                            蜂鸣器
                            GPRS ==== 发短信或打电话

A9数据处理部分
    数据流向分析:
        1、ZigBee(采集终端)-->A9(处理平台)
        2、A9(处理平台)-->网页(显示平台)
        3、网页(显示平台)-->A9(处理平台)
        4、A9(处理平台)--->ZigBee(采集终端)
    
A9-ZigBee采集部分
            外设驱动 --------在应用层去获取外设的状态或数据
A9--------- 蜂鸣器  ------------------蜂鸣器报警
            LED灯   ------------------卧室-厕所-楼道-公共照明 --------LED2-LED3-LED4-LED5
            按键    ------------------按键触发中断---控制卧室和厕所灯-----LED2-LED3 
            ADC      -----------------获取ADC的采样数据
            mpu6050 ------------------获取MPU6050的六轴数据

zigbee------adc     ------主---协调器
            风扇    ------从---终端节点   下发命令控制风扇
            温湿度    ------从---终端节点   上传温湿度数据
            (光敏)
            
小结:   |            |             |             |
        |    ZigBee  |   A9        |      web    |
        |            |             |             |
        |   adc      |   蜂鸣器     |  环境信息:-----------------adc电压数据
        |   风扇      |   LED灯     |  摄像头采集:-----usb摄像头   mpu6050的六轴数据
        |   温湿度    |   按键       |  硬件控制:  |------风扇    温度
        | (光敏)    |   ADC       |             |      LED灯   湿度
                         mpu6050                        蜂鸣器
                         四路led灯模拟数码管               GPRS
                                                        四路led灯模拟数码管    
                        

具体数据流分析:

数据流分析:
    数据上传: 
        ZigBee                 | 
            温湿度数据           |
        A9                     |
            ADC采集             |-----------上传这些数据
            加速计数据           |
            陀螺仪数据           |
        摄像头                  |
            视频流图像           |
            
    数据下发:                    
        ZigBee:                      |
            风扇                      |
        A9:                          |
            蜂鸣器                     |-----打开设备节点控制硬件
            LED灯                     |
            四路LED灯模拟的数码管        |
        GPRS:                        |
            3G通信模块                 |

宏定义设备文件:

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

制定通信协议结构体:

1、数据的上传:

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

        //考虑到内存对齐的问题
        struct makeru_zigbee_info{
                uint8_t head[3]; //标识位: 'm' 's' 'm'  makeru-security-monitor  
                uint8_t type;     //数据类型  'z'---zigbee  'a'---a9
                ------------->crc ...加密算法 <--------------
                float temperature; //温度
                float humidity;  //湿度
                float tempMIN;//温度下限
                float tempMAX;//温度上限 
                float humidityMIN;   //湿度下限
                float humidityMAX;   //湿度上限
                uint32_t reserved[2]; //保留扩展位,默认填充0
                //void *data;  内核预留的扩展接口  参考版
        };

        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;   //陀螺仪数据,16位精度
            short gyroy;
            short gyroz;
            short  aacx;  //加速计数据,16位精度
            short  aacy;
            short  aacz;
            uint32_t reserved[2]; //保留扩展位,默认填充0
            //void *data;  内核预留的扩展接口  参考版
        };
        
        //将A9-info结构体和Zigbee-info结构体进行再次封装
        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];    //数组  老家---新家
        };
        

2、数据的下发:(采用消息队列的方式下发数据到下位机上) 

        数据的下发用于控制硬件: 
        
        man msgsnd 
       #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/msg.h>

       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 = t;   //具体的消息类型
            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;
        }
        

3、控制命令的制定:

        消息队列接收消息:
            msgrcv (msgid, &msgbuf, sizeof (msgbuf) - sizeof (long), 1L, 0);
        解析buf中的数据:
            printf ("Get %ldL msg
", msgbuf.msgtype);
            printf ("text[0] = %#x
", msgbuf.text[0]);
        
        
        A9-ZIGBEE通用指令
        命令格式:一个字节,unsigned char 对应消息队列中正文的类型: 
            (unsigned char 每两位只能表示4种设备,若要增加可用unsigned int)
        8位
        ----------------------------------------
        7    6    |  5    4    |    3    2    1    0
        平台编号   |   设备编号   |    操作设备
        ----------------------------------------
         位数     7654 3210
         0   0 0x0000 0000
         0   1 0x0100 0000
         1   0 0x1000 0000
         1   1 0x1100 0000
         
        平台编号    
        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代表低位数据
                    short  c
                    unsigned char a ,b;
                    c = a | b;
                    c = a + b;
    上行:封装的结构体====共享内存和信号量 ===>交给CGI(C语言和HTML语言之间的转化接口)===>交给HTML
    下行:封装的命令字====消息队列 ====>msgbuf msgsnd===>控制命令字封装在msgsnd的msgbuf中 ===>A9端解析==>向下控制硬件