APP下载

低功耗电子号牌在排队系统中的设计与实现

2018-12-13杨东轩

计算机应用与软件 2018年12期
关键词:号牌服务器端低功耗

杨东轩 刘 硕 王 嵩

(北京工商大学网络中心 北京 100048)

0 引 言

目前在一些办事大厅等场景广泛使用排队叫号系统,不少系统仍采用纸质的叫号方式。这种纸质方式既不利于环境保护又在内容显示上无法实时更新。有些手机APP的叫号方式又有许多使用的局限性,包括可能暴露客户信息等情况[1,2]。本文结合物联网技术和基于低功耗Wi-Fi的电子手持号牌设计,给出使用该电子手持号牌较为完整的叫号系统设计与实现方法。

1 系统架构

系统主要由电子号牌和服务器两部分组成,它们同处于一个无线局域网之中。电子号牌以低功耗Wi-Fi芯片CC3200为核心,接收来自服务器端的无线数据,提醒用户当前的业务信息。服务器端由Linux系统及相关软件构成,负责控制电子号牌的发放、叫号信息的数据广播以及与对外提供系统交互接口。系统架构如图1所示。

图1 系统架构图

目前市场较为常见的电子号牌一般都采用315 MHz左右的较低频率无线调频技术,使用数码管显示号码,一般只有一个信号发射端用来手工发号和叫号,不能更改号牌的号码,也不提供二次开发的接口。它们的无线发射端和接收端不具备组网功能,且信号覆盖范围固定,仅适用于快餐业务领域的叫号使用。

本文实现的电子号牌在系统构成方面更加复杂、应用范围也更为广泛。号牌具有文本显示能力,包括显示业务类型、办理进度、时间和电量等信息。而且还有震动功能提醒客户。由于服务器端和客户端是使用Wi-Fi进行通信的,因此系统的覆盖范围可以根据AP的安装位置进行灵活扩展。

2 电子号牌设计

系统设计初期,将电子号牌的外观尺寸限定在普通的银行卡尺寸大小,这就对其内部的电路设计提出了很高的要求。在核心器件低功耗Wi-Fi芯片的选型上,选择了德州仪器的CC3200芯片,与同一应用领域的其他厂家的芯片相比[3-4],它具有外设接口丰富、工作电压范围更宽、开发周期较短等优点,如表1所示。

表1 同类低功耗Wi-Fi芯片对比

2.1 号牌硬件设计

硬件电路包含CC3200最小运行系统、OLED点阵显示屏、振子电机驱动、霍尔效应开关传感器及充电管理模块。CC3200最小系统包含了能使该芯片正常运行的最少电路设计以及能支持其无线通信的天线电路设计。由于该主控芯片集成了一个ARM-Cortex M4内核的处理器和一个Wi-Fi网络处理器[5],因此在电路板的布局和走线方面要严格按照TI公司给出的设计手册进行,其中电源部分和射频链路部分的设计尤为重要。为了满足芯片启动、发射和接收数据时的电流需求,电源相关引脚的走线必须满足表2中的条件。

表2 CC3200引脚通过电流

射频部分的布局则会影响信号的输出功率、误差向量幅度以及频谱掩模。在射频电路中,天线起到了将PCB引线中的导波转换为自由空间中电磁辐射的作用,因此在布局中要尽量把陶瓷天线器件放到PCB板的边缘,确保没有其他信号线穿过天线底部。由于射频部分走线要满足其在2.4 GHz频段工作时的阻抗为50 Ω,因此需要选择适合的传输模型。本文选用具有地面结构的共面波导CPW-G(Coplanar Waveguide With GND)模型,该模型结构如图2所示,其中εr为相对介电常数,W为间隙宽度,S为走线宽度,h为电解质厚度[6]。

图2 CPW-G模型结构

在显示功能方面,选用像素尺寸为128×64的OLED点阵显示屏,该屏幕可以同时显示32个汉字或者64个半角字符,足以容纳叫号业务所需显示的内容。相比目前流行的LCD、QLED和LPD显示技术,OLED具有自发光、厚度极薄、响应时间快、低功耗等优点[7]。该款屏幕在2.8 V供电情况下,全像素点亮时的电流为28 mA,休眠状态时则为1 μA。屏幕与主控芯片之间采用SPI串行总线连接,电路原理如图3所示。

图3 OLED屏幕电路

振子即微型的震动电机,通过将电能转换为机械能起到震动提醒作用,是整个电路系统中最为耗电的部分。号牌采用的振子最大电流为120 mA,为了让CC3200的GPIO口足以驱动该电机,采用NPN型的三极管作为驱动开关。如图4所示,将电机的正负输入端分别接到系统电源与三极管的集电极之间,为了防止电机停止时产生的反电动势对其他电子器件造成损坏,还需要在电机的两端并入一个二极管以作保护。

图4 振动电机驱动电路

电子号牌没有任何可供用户操作的输入设备,因此需要设计一个激活装置来将整个电路系统从关闭状态激活为开启状态。采用A3212型的超灵敏霍尔效应开关传感器,可以在不使用物理触控的条件下,通过磁场变化就可以改变该传感器的输出电压。将该传感器布局在PCB的边缘,有助于更加灵敏地受到磁铁的感应。如图5所示,OUTPUT输出引脚通过上拉电阻连接到主控芯片的GPIO口,该IO口用于将冬眠状态的处理器唤醒为运行状态。当垂直通过该传感器的磁感应强度大于37 T的时候,输出为低电平。

图5 霍尔开关传感器电路

使用一块容量为700 mAH的锂离子电池作为整个电路的供电来源,采用USB Micro接口作为号牌的充电接口,充电管理芯片的型号为TP4056。如图6所示,当电路系统接入5 V的USB充电线后,USB接口的VBUS电源引脚通过限流电阻使NPN三极管CE两端导通,发射极触发主控芯片的GPIO口从而通知系统已经接入充电线。充电管理芯片的STDBY引脚为电池充电状态,当电池充满电后会内部下拉到低电平。

图6 充电管理电路

2.2 低功耗策略实现

设备的主要耗电器件是屏幕、震动电机以及主控芯片,由于前两者在运行期间的功耗基本是恒定不变的,因此为主控芯片制定合适的低功耗策略是关键所在。对于理想化的计算机系统而言降低核心处理器CPU的电压和频率均可以起到降低功耗的作用[8],如果把CPU看作是一个基于电容器的系统,那么它的功耗满足如下物理关系式:

(1)

式中:E为芯片消耗的能量,T为消耗能量所需的时间,U为运行电压,f为芯片的工作频率。

对于CC3200而言,虽然它的工作电压范围在1.76 V至3.6 V之间,但是为了简化硬件设计,通常采用恒定的稳压电源,因此只需要通过改变芯片的运行频率就可以满足功耗的调整了,其物理关系满足下式:

(2)

式中:Ttask为单个任务运行的时间。

而芯片在不同的运行频率下,所处的工作模式也不同。CC3200内部包含两个独立的系统,分别是Cortex-M4应用处理器(MCU)子系统和网络处理器(NWP)子系统,每个子系统都有若干种工作模式。在号牌的软件实现中,分别用到了MCU的激活模式、低功耗深度睡眠模式(LPDS)以及冬眠模式。在激活模式时,它将以80 MHz的频率运行应用代码,此时MCU的功耗最高;在LPDS模式时,只保留特定寄存器的配置,但可以从网络事件中唤醒;在冬眠模式时,功耗最低且仅由频率最低的实时时钟驱动,仅能由时钟定时器或外部事件触发唤醒,唤醒后重新加载串行Flash中的应用代码运行。NWP的工作模式由其自身根据当前的网络状态和MCU的电源策略自动控制,分别在激活模式、LPDS模式和冬眠模式中自主切换[9]。

在号牌的实际使用过程中,针对不同的工作场景切换不同的工作模式,在保障运行效率的情况下使芯片功耗降到最低。表3给出了所有工作场景下芯片对应的电源模式以及电路各主要部分的电流使用情况。在号牌未被发出时,处于冬眠状态,此时功耗最低;当号牌被发出时,需要从冬眠状态被唤醒,由于唤醒时机不确定,因此只能使用外部IO作为唤醒源;号牌在用户手中的大部分时间是保持屏幕画面不变的状态,处于LPDS模式,但是当处于接收广播消息、屏幕时间定时刷新等事件时,便会被唤醒;唤醒状态的号牌处于激活模式,此时进行屏幕刷新、网络数据处理等业务。

表3 电子号牌电源工作模式

2.3 号牌软件设计

电子号牌与服务器之间的通信方案采用无握手机制的UDP协议报文。软件整体结构基于FreeRTOS嵌入式实时操作系统,采用TI官方提供的SimpleLink组件库来实现网络方面的编程,调用内置于芯片ROM的外设驱动库(DriverLib)来对SPI、GPIO、ADC和定时器等外设进行编程。软件的主函数运行流程如图7所示。首先对CC3200的外设及硬件资源进行初始化,如OLED屏幕、外部输入IO等;然后开始SimpleLink的任务调度器,该任务管理主处理器和NWP之间的消息通信;最后创建并执行分别用于事件处理、UDP服务器和UDP客户端的子任务。

图7 号牌软件运行流程

大部分工作时间里号牌处于接收服务器发送UDP广播数据的状态,因此它将主要扮演UDP 服务器的角色,仅在第一次连接到服务器的时候才需要作为UDP 客户端来向服务器发送激活消息。根据发送和接收不同的UDP报文,来驱动号牌在不同状态之间切换。这些状态包括:设备复位状态、等待业务编号状态、等待叫号状态、被叫号状态、过号状态以及充电状态。在大部分状态改变的同时,号牌接收UDP报文的端口号也会随之改变,在等待叫号状态中,不同业务类型的号牌所监听的UDP端口也不同。这样就实现了以端口号划分业务类型的目的,在服务器广播指定端口的UDP报文的同时,其他业务类型的号牌则不会收到该端口的报文。不接收报文意味着硬件不会从LDPS模式中被唤醒,从而节约了不必要的功耗开支。UDP报文与号牌状态之间切换的流程如图8所示。

图8 号牌状态切换流程

号牌软件系统中有三个主要的任务,分别是:Task_MainProcess()(主处理任务),负责系统初始化、外设控制以及网络报文数据处理;Task_UDPServer()(UDP服务器任务),负责接收来自服务器发送的UDP报文;Task_UDPClient()(UDP客户端任务),负责向服务器发送UDP报文。当系统成功连接到指定SSID的AP后,首先会向服务器发送激活消息的数据包。在本次发送的数据中,加入该号牌的MAC地址作为唯一身份识别,用sl_NetCfgGet()获取设备自身的MAC地址。无论是发送还是接收UDP数据包,都需要首先调用sl_Socket()创建UDP套接字,之后通过sl_SendTo()将封装好的数据包发送出去。为了防止网络阻塞、信号不好等意外情况导致目标地址无法正常收到数据,在发送每个UDP报文的时候都连续发送N次同样的数据,一旦接收到服务器返回的数据,则停止发送并执行下一步操作,当第N次还没有收到应答数据,则判断其运行状态异常,系统调用rn_setup_power_policy()进入冬眠模式以备回收处理。当服务器成功接收到号牌发送的激活消息后,会做出相应的回答。号牌系统通过sl_RecvFrom()接收UDP报文,并使用sl_Bind()绑定接收数据的端口。如前文所述,UDP客户端任务根据接收到的报文类型来使号牌切换状态同时改变接收报文的端口号,该任务的运行流程如图9所示。

图9 UDP客户端任务流程

3 服务器端设计

服务器端的软件采用GO语言编写并运行于Linux系统之上。该语言编写的代码在编译后生成一个静态可执行文件,在服务器上部署时完全不需要关心应用所需的各种包和库的依赖关系,大大减轻了维护的负担。

3.1 数据模型设计

系统中主要用到了XML数据模型和关系型数据模型,前者用来存储电子号牌硬件相关的数据,后者用来存储业务相关的运行数据。将每个电子号牌的射频标签EPC编码和MAC地址存储在XML文件中,如果需要更换或新增电子号牌,只需要更新该XML文件即可,该文件的存储格式如下:

F4:B8:5E:45:EB:82

使用如下代码将XML数据读入到程序内存中:

data, err:=ReadFile(CONFIG_XML)

err=xml.Unmarshal(data, &cardslice)

for _, v:=range cardslice.Item

cardmap[v.Epc]=v.Mac

业务数据存储到MySQL数据库中的“system”表中,该表仅存储非冬眠状态即正在使用中的电子号牌的业务数据。每当发出一张新的电子号牌,使用InsertDB()向表中插入一条新数据,并写入EPC、MAC地址等基础数据;当电子号牌状态发生改变后通过UpdateDB()改变该记录的数据;当电子号牌使用完毕并进入冬眠状态后,通过DeleteDB()销毁对应号牌的记录。数据表“system”的结构和描述如表4所示。

表4 系统数据表结构

3.2 业务逻辑

服务器端软件的业务对象主要面向手牌硬件客户端和上层叫号应用的调用,前者通过UDP协议与服务器端通信,后者通过HTTP API控制服务器做出相关动作。软件开始运行后,首先初始化HTTP和UDP等网络相关的监听接口,并通过串口检查硬件发卡设备是否工作正常。服务器端软件的结构如图10所示。

图10 服务器端软件结构

GO语言有众多优秀的Web框架[10],但是本系统的HTTP接口仅面向上层应用之间的调用,不需要复杂的路由配置和HTML模板引擎,因此只使用GO的标准库接口便可以实现功能。使用http.HandleFunc()接口把一个URL路径绑定给相应的函数,然后通过http.ListenAndServe()接口监听8080端口的HTTP请求。当客户的应用调用指定的URL访问服务器后,服务器会调用相应的函数执行业务功能,同时以JSON格式的数据返回给客户应用。以号牌发放流程为例,当HTTP端口收到来自客户应用的发卡请求后会立即返回结果,因为发放操作涉及硬件控制,所以处理结果需要以异步主动查询的方式获取。如果发号机为空闲状态,则通过ttyS设备控制串口做出发号操作,此时客户的应用可以定期调用查询接口以查询操作是否成功。如果以上步骤成功,则号牌会自动激活并向服务器发送相关UDP报文来请求分配业务号码。

服务器在监听号牌上报的UDP报文的同时,还要根据HTTP接口调用的叫号操作向指定业务类型的号牌发送UDP广播报文。使用以下代码开启UDP服务器:

addr, err:=net.ResolveUDPAddr(″udp″, ″:″+port)

conn, err=net.ListenUDP(″udp″, addr)

其中port为UDP服务器需要监听的端口号,然后循环调用以下代码监听并读取客户端发送上来的UDP报文:

n, remoteAddr, err:=conn.ReadFromUDP(data)

与接收UDP报文的操作不同,HTTP接口的并发调用可能会引起多个同时发送UDP报文的操作,为了防止多线程之间在同时发送UDP报文的时候占用发送通道而发生异常,需要定义一个*sync.Mutex类型的互斥锁来保证同时只有一个线程在发送报文,代码如下所示:

broadipport:=fmt.Sprintf(″%s:%s″, ″192.168.1.255″, cardPort)

addr, err:=net.ResolveUDPAddr(″udp″, broadipport)

locker.Lock()

//阻塞其他发送报文的线程

_, err:=conn.WriteToUDP(data, addr)

locker.Unlock()

//释放阻塞

从代码可以看出发送报文并未指定任何目的IP地址而是使用广播地址和指定的端口号来发送,因为系统规定不同的号码业务对应不同的端口号,所以每次的叫号操作并不是把报文发送给特定IP的号牌客户端,而是以端口号为分组的广播发送。

3.3 接口协议

3.3.1 外部HTTP接口

本系统对于外部应用来说相当于一个黑箱,各种应用只需要调用服务器提供的HTTP接口便可以操作整个电子号牌系统。HTTP接口部分说明如表5所示。

表5 HTTP接口

3.3.2 内部UDP协议

服务器与号牌客户端之间处于一个内部网络环境,不需要对第三方提供服务,为了简化通信,直接使用OSI分层中属于传输层的UDP报文进行通信。自定义报文的格式共分为帧头、类型和内容三个段。其中帧头段固定为2个字节的0x55和0xAA;类型段为1个字节,用来区分当前报文的功能,分别有“设置号码业务”类型和“叫号操作”类型;内容段的长度根据类型段来确定,如果类型为设置号码业务,则内容段共15字节,包含需要开启的端口号、业务代码类型、需要设置的号码、当前叫到的号码以及当前的时间戳。如果是叫号操作类型,则内容段共12个字节,包含当前叫到的号码以及该号码的服务窗口名称。

4 结 语

本文介绍了一种基于低功耗Wi-Fi的电子号牌系统的设计和实现方法。通过系统对外提供便捷的HTTP操作接口,可以与大部分目前的排队叫号场景进行对接。系统的电子号牌不仅体积小,还可以在极低功耗的状态下长时间休眠,有较好的使用价值和用户体验。

猜你喜欢

号牌服务器端低功耗
一种高速低功耗比较器设计
复合材料结构的低功耗冲击区域监测方法
Linux环境下基于Socket的数据传输软件设计
拷问 涂改号牌扣12分,重吗? 它可能是违章、违法的前提!
一种宽带低功耗四合一接收机设计
全面推广应用新能源汽车号牌
基于Qt的安全即时通讯软件服务器端设计
一种低功耗温度检测电路的设计
基于Qt的网络聊天软件服务器端设计
夏邑:查获收缴38副虚假临时号牌