项目描述
远程数据采集控制系统是通过CC2530模块进行数据采集,并且将数据传送至Linux系统中进行处理,用户通过web就可以远程查看数据并且控制设备和视频监控
涉及技术
MCU、C/C++、进程和线程、CGI、共享内存、消息队列、视频流服务器移植、信号量、互斥锁、zigbee、SQLite、Makefile
硬件
- usb接口摄像头
- cc2530
- pc
- 协调器
- 终端节点
软件
乌邦图上软件
- boa
- mjepg-streamer
- 主控程序
- 摄像头驱动
- 串口驱动
cc2530上软件
- Zigbee
- 数据采集
项目框架
- web UI
- Linux主控
- 感知层
数据采集节点
cc2530
- CC2530 单片机是一款完全兼容 8051 内核,同时支持 IEEE802.15.4 协议的无线射频单片机。
- CC2530微控制器采用QFN40封装,有40 个引脚。
- 其中,有21个数字I/O端口,其中P0和P1是8 位端口,P2仅有5位可以使用。
- 这21个端口均可以通过编程进行配置。
- 实际上,在P2端口的5个引脚中,有2个需要用作仿真,有2个需要用作晶振,在CC2530的开发中真正能够使用的只有17个引脚。
- 使用时需引入头文件“ioCC2530.h”
USART
通用同步异步收发器(Universal Synchronous Asynchronous Receiverand Transmitter) 是一个串行通信设备,可以灵活地与外部设备进行全双工数据交换。
同步通信
• 在发送数据信号的时候,会同时送出一根同步时钟信号, 用来同步发送方和接收方的数据采样频率。
异步通信
• 数据发送方和数据接收方没有同步时钟,只有数据信号线,只不
过发送端和接收端会按照协商好的协议(固定频率)来进行数据采样。
串行通信:利用一条传输线将资料一位位地顺序传送
并行通信:一排横队,齐头并进同时传输
USB转UART
使用CH340(南京沁恒)芯片
帧格式
起始位:先发出一个逻辑“0”信号,表示传输字符的开始;
数据位:可以是5~8位逻辑“0”或“1”,如ASCII码(7位),扩展BCD码(8位),小端传输;
校验位:数据位加上这一位后,使得“1”的位数应为偶数(偶校验)或奇数(奇校验) ;
停止位:它是一个字符数据的结束标志。可以是1位、1.5位、2位的高电平;
空闲位:处于逻辑“1”状态,表示当前线路上没有资料传送。
CC2530-USART
• CC2530 包括 2 个串行通信接口 USART0 与 USART1,
• 每个串口包括两个模式:
• UART(异步)模式、 SPI(同步)模式,
• 两个 USART 具有同样的功能,可以设置在单独的 I/O 引脚。
寄存器
• 1. UxCSR:
• USARTx 控制状态寄存器
• 2. UxUCR:
• USARTx UART控制寄存器
• 3. UxGCR:
• USARTx 通用控制寄存器
• 4. UxBUF:
• USARTx UART接受/发送数据缓冲区
• 5. UxBAUD:
• USARTx 波特率控制寄存器
zigbee
• ZigBee 是一种开放式的基于IEEE 802.15.4协定的无线个人局域网(Wireless PersonalArea Networks)标准。
• IEEE 802.15.4定义了物理层和媒体接入控制层
• 而ZigBee则定义了更高层如网路层及应用层等。
ZigBee技术特点
•
- 低功耗
由于ZigBee的传输速率低,发射功率仅为 1mW,而且采用了休眠模式功耗低,因此ZigBee设备非常省电。
•
据估算,ZigBee设备仅靠两节5号电池就可以维持长达6个月到2年右的使用时间。
• - 低成本
由于ZigBee模块的复杂度不高,ZigBee协议免专利费,再加之使的频段无需付费,所以它的成本较低。
• - 时延短
通信时延和从休眠状态激活的时延都非常短,典型的搜索设备时30ms,休眠激活的时延是15ms, 活动设备信道接入的时延为15ms。
• - 网络容量大
一个星型结构的ZigBee网络最多可以容纳254个从设备和一个主备, 一个区域内可以同时存在最多100个ZigBee网络,而且网络组成灵活。网状结构的ZigBee网络中可有65000多个点。
• - 可靠
采取了碰撞避免策略,同时为需要固定带宽的通信业务预留了专用隙,避开了发送数据的竞争和冲突。MAC层采用了完全确认的数据传输模式, 每个发送的数据包都必须等待接收方的确认息。如果传输过程中出现问题可进行重发。
• - 安全
ZigBee提供了基于循环冗余校验(CRC)的数据包完整性检查功能,持鉴权和认证, 采用了AES-128的加密算法,各个应用可以灵活确定其安全属性。
Zigbee设备类型
-
协调器
• 它包含所有的网络信息,是3种设备中最复杂的,存储容量大、计算能力最强。
• 它主要用于发送网络信标、建立一个网络、管理网络节点、存储网络节点信息、寻找一对节点间的路由信息并且不断的接收信息。
• 一旦网络建立完成,这个协调器的作用就像路由器节点。 -
路由器
它执行的功能包括允许其它设备加入这个网络,跳跃路由,辅助子树下电池供电终端的通信。
-
终端节点
• 一个终端设备对于维护这个网络设备没有具体的责任,所以它可以睡眠和唤配,看它自己的选择。
• 因此它能作为电池供电节点。
ZigBee网络拓扑
- 星型
- 簇状型
- 网状型
ZigBee网状(MESH)网络
- MESH网状网络拓扑结构的网络具有强大的功能,
网络可以通过多级跳的方式来通信;
该拓扑结构还可以组成极为复杂的网络;
网络还具备自组织、自愈功能
ZigBee网络建立-协调器建立一个新网络的流程
1) 检测协调器
- 节点必须具备两个条件:
1)具有ZigBee协调器功能,
2)没有加入到其它网络中。 - 任何不满足这两个条件的节点发起建立一个新网络的进程都会被网络层管理实体终止
2)信道扫描
- 信道扫描包括能量扫描和主动扫描两个过程。
3) 配置网络参数
- 网络层管理实体将为新网络选择一个PAN描述符,必须满足PAN描述符小于或等于0x3fff,不等于0xffff,并且在所选信道内是唯一的PAN描述符
4) 运行新网络
5) 允许设备加入网络
- 只有ZigBee协调器或路由器才能通过NLME_PERMIT_JOINING.request原语来设置节点处于允许设备加入网络的状态。
ZigBee网络建立-节点加入网络
1) 通过MAC层关联加入网络
- • 1、子节点发起信道扫描
• 2、 子节点存储各PAN信息
• 3、 子节点选择PAN
• 4、 子节点选择父节点
• 5、 子节点请求MAC关联
• 6、 父节点响应MAC关联
• 7、 子节点响应连接成功
• 8、 父节点响应连接成功
2) 通过与先前指定父节点连接加入网络
Zigbee协议栈
• ZigBee 的协议分为两部分:
• ZigBee 联盟定义了网络层、安全层和应用层技术规范,
• IEEE802.15.4 定义了物理层和 MAC 层技术规范,
• ZigBee 协议栈就是将各个层定义的协议都集合在一起,以函数的形式实现,并给用户提供一些应用层 API,供用户调用。
• ZigBee 协议栈具有很多版本,不同厂商提供的 ZigBee协议栈有一定的区别。
Zigbee协议栈使用
使用 ZigBee 协议栈进行开发的基本思路可以概括为如下三点:
• 1、用户对于 ZigBee 无线网络的开发就简化为应用层的 c 语言程序开发,不需要深入研究复杂的 ZigBee 协议栈;
• 2、 ZigBee 无线传感器网络中数据采集,只需用户在应用层加入传感器的读取函数即可;
• 3、如果考虑节能,可以根据数据采集周期进行定时,定时时间到就唤醒 ZigBee 的终端节点,终端节点唤醒后,自动采集传感器数据,然后将数据发送给路由器或者直接发给协调器。
Zigbee协议栈函数
AF_DataRequest函数
- 无线发送函数
• 向zigbee网络发送函数都调用该函数
• 其中cID对应的就是函数
GenericApp_MessageMSGCB()接收
到的数据pkt->clusterId
GenericApp_MessageMSGCB()
- • 接收数据函数
• 无线信道接收到的数据都会调用到该函数
添加定时器功能
我们希望终端节点可以定时上传传感器数据,这就需要定时器操作。
• 1. ZDO层更改网络状态后就启动定时器
• 2. 主任务处理函数
GenericApp_ProcessEvent()中,增加超时事件处理逻辑,上传传感器数据
• 3. 通过函数osal_start_timerEx()重新启动定时器
上位机与无线节点通信函数调用流程
1.上位机通过串口发送数据给协调器;
2.触发协调器串口回调函数rxCB()
,通过HalUARTRead()
从串口提取出数据;
3.协调器通过AF_DataRequest()
将数据发送给网络中其他设备,通过id:GENERICAPP_CLUSTERID
,表明改数据是协调器发送;
4.触发终端节点回调函数GenericApp_MessageMSGCB(),协调器id存放在pkt->clusterId
中,发送的数据存放在pkt->cmd.data
中;
5.终端节点可以采集传感器数据,发送数据在缓冲区data
中,然后通过函数AF_DataRequest()
发送数据,填充id:GENERICAPP_CLUSTERID2
,表示数据是节点2发送;
6.触发协调器的回调函数GenericApp_MessageMSGCB()
;
7.协调器提取出终端节点发送的数据pkt->cmd.data
,通HalUARTWrite()
发送给上位机。
linux主控程序
链表的操作
使用到链表操作的位置:在zigbee数据采集线程和zigbee命令发送线程中使用到了链表的操作
链表的使用是为了防止发送命令太多,不让主线程一直等待串口发送数据(发送时需要延时,所以影响效率),而是先存到链表里面然后让其他线程来处理串口发送数据
为什么不使用顺序表而用链表?主要是ARM架构下的程序内存资源相对较为重要,顺序表空间大小需要按照最大需求来分配,容易造成内存的浪费
-
链表都使用的是单链表
-
主要操作为插入节点和读取节点
• 1.创建链表
• linklist CreateEmptyLinklist()
• 2.插入节点
• int InsertLinknode (link_datatype x)
• 3.提取一个节点
• linklist GetLinknode (linklist h)
I/O操作
使用到I/O操作的位置:
- 本项目中协调器通过串口与上位机 通信
- 串口设备被模拟成
• /dev/ttyUSB0、/dev/ttyUSB1、 /dev/ttyS0、
/dev/ttyS1 - 应用程序只需要通过系统调用操作设备文件
• open()/read()/write()/close()…
文件I/O介绍
open():调用open()函数可以打开或者创建一个文件。
close():调用close()函数可以关闭一个打开的文件。
read():调用read()函数可以从一个已打开的可读文件中读取数据。
write():调用write()函数可以向一个已打开的可写文件中写入数据。
lseek():调用 lseek()函数可以显示的定位一个已打开的文件,使用lseek后继续使用read和write将会定位到lseek定位的位置后继续读取或者写入
串口操作
串口操作结构体:termios(/usr/include/asm-generic/termbits.h)
tcgetattr函数:取得终端(fd)相关的参数,提供异步通讯接口
tcsetattr函数:设置与终端相关的参数
cfsetispeed和cfsetospeed函数:设置 termios 结构中存储的输入/出波特率为 speed
tcflush函数:清空终端未完成的输入/输出请求和数据
文件I/O进阶、错误码、库与系统调用
文件描述符(0、1、2被占用)
①顺序分配的非负整数
②内核用以标识一个特定进程正在访问的文件
③其他资源(socket、pipe等)的访问标识
文件描述符0、1、2的用途:标准输入、标准输出和标准出错
查看所有进程允许打开的最大 fd 数量
cat /proc/sys/fs/file-max
查看所有进程已经打开的 fd 数量以及允许的最大数量
cat /proc/sys/fs/file-nr
查看单个进程允许打开的最大 fd 数量.
ulimit