适配Android手机的串口通信套件设计

2020-03-20 10:38王明辉雷卫延黄海谭晗凌
广东气象 2020年1期
关键词:套件缓冲区控件

王明辉,雷卫延,黄海,谭晗凌

(广东省气象探测数据中心,广东广州 510640)

在自动气象观测领域,有大量观测设备和通信设施通过串口配置参数或输出气象报文,需要借助电脑才能准确检查串口通信是否正常[1-3]。由于笔记本电脑配备成本高、携带不方便,因此,很多维保人员在维修现场无电脑可用,对串口通信故障束手无策,难以准确定位故障点。

Android是Google公司主导开发的一种基于Linux的开源操作系统,广泛应用于通信、物流、互联网行业,基于Android系统的智能手机在全球智能手机市场占有率已经超过Apple公司搭载ios系统的iphone,排名第1。近年来,气象行业已经基于Android智能手机开展了一些应用,显著地提高了效率[4-9]。本研究基于Android手机的USB-OTG功能研发了一套便携的串口通信套件,实现Android手机APP与气象观测设备串口双向通信,使维保人员在维修现场能够通过Android手机方便、高效、准确地检查设备的串口工况,具有很高的业务应用价值。

1 套件架构

套件架构如图1所示。

图1 套件架构示意图

USB协议是一种用于计算机与外设方便连接的数据总线,建立连接的2个USB设备分为主设备 host和从设备 device(又称 slave),仅当host与device连接时才能传输数据。OTG是对USB 2.0协议的补充,其最重要的扩展是更节能的电源管理和允许设备以host和device两种形式工作[10-12]。目前绝大部分Android手机支持OTG协议,当该种手机通过USB连接电脑时,电脑为host,手机为device。在本方案中,串口通信套件包含硬件转换模块和运行在Android手机上的APP软件,Android手机工作形式为host,硬件转换模块为device。转换模块拥有一个Micro-USB接口和一个RS232串口,当模块的Micro-USB接口与Android手机相连时,APP软件自动启动,再将RS232串口与自动气象站等设备的串口连接,即可建立手机到设备的RS232串口通信。

2 转换模块设计

2.1 功能性设计

常用的 USB转串口芯片有 CH340、FT232、PL2303等系列[13-15],这些芯片的最新版本多已加入对 Android系统的支持。PL2303HXD是Prolific公司PL2303系列第5代USB转TTL电平串口芯片,支持Android系统,因性价比最高而广泛商用。该芯片自带12 MHz晶振,支持75~12 Mbp波特率,完全满足自动气象观测设备常采用的1 200、9 600波特率。芯片支持以5、6、7、8位数据位和1、2位停止位收发,校验方式可选奇校验、偶校验或无校验,满足自动气象观测设备常用的串口配置,如7位数据位、1位停止位、偶校验,或8位数据位、1位停止位、无校验。芯片具有可配置的512 Byte双向数据缓冲器,本套件将输入和输出缓冲区分别配置为256 Byte,通过编程循环读取、写入缓冲区实现串口读取、发送。由于自动气象站等设备的串口为RS232电平,在与PL2303HXD通信时还需要做RS232-TTL电平的转换。该套件采用了 NI公司的MAX202芯片与PL2303HXD配合,实现RS232电平和TTL电平的相互转换。硬件转换模块在物理上实现了USB-RS232信号转换。

2.2 电路设计

硬件转换模块设计通过Micro-USB型接口与手机建立OTG连接,该接口为5线制,依次定义为 VBUS、DM、DP、ID、GND。PL2303HXD和MAX202芯片工作电压均为+5 V,典型电流分别为20和8 mA,满足手机OTG接口的带负载能力,故设计转换模块通过VBUS、GND从手机的Micro-USB接口获取+5 V供电。为防止芯片经电源线从手机引入干扰,或转换模块传输数据时产生高频信号通过电源线传入手机,在VBUS、GND传输线上各设计一个80μH的电感抑制高频信号。根据OTG协议,手机USB端口内部ID线上拉,默认工作在device状态。转换模块设计ID线与GND短接,与手机连接后将手机USB端口的ID线下拉,使手机进入host状态。

DM、DP是一对传输数据的差分信号线,在手机USB端口内部,DM和DP各连接一个15 kΩ的下拉电阻,设计转换模块的DP接口连接一个1.5 kΩ的上拉电阻,两者连接时手机的DP电平被拉高,从而将 PL2303HXD识别为全速USB。为防止数据传输过程中的高速信号在端口附近产生反射,模块在尽量靠近PL2303HXD芯片的DM和DP上各串联一个22Ω的匹配电阻。在数据传输时,芯片U1、U2间TTL电平的TXD、RXD信号线会发生高速的高低电平翻转,模块在VBUS和TXD、RXD之间设计了LED用于显示数据传输情况。当TXD、RXD信号线为低电平时,利用1 kΩ的限流电阻使得通过LED的电流<3 mA,LED导通发光。转换模块核心电路如图2所示。

图2 转换模块核心电路示意图

3 软件设计

为实现Android手机的OTG通信,需要开发与转换模块匹配的APP软件。PL2303HXD芯片原厂提供了JAR驱动库,支持系统版本3.2(API Level 13)以上的Android手机,不需要root即可实现OTG通信。本研究搭建了Eclipse+ADT+Android SDK开发环境,基于JAVA语言和驱动库pl2303multilib.jar开发了APP软件,软件可运行在Android 3.2及以上版本的Android手机上。软件测试平台为魅族牌Android手机,Android版本7.1.2。

软件设计为单Activity窗体,包含串口参数设置、串口读取显示、串口发送3个功能区,如图3所示。串口参数包括波特率、校验位、数据位、停止位,均采用Spinner控件进行选择。Android手机检测到转换模块插入后自动启动软件,设置串口参数后点击“打开”Button打开串口,软件自动读取串口信息并显示在TextView控件中,当收到下一条信息时自动刷新显示。发送时,将待发送信息输入EditText控件,点击“发送”Button实现信息发送。

图3 APP软件界面

3.1 打开串口

软件打开是Activity窗体进入Running状态的过程,Activity需要依次经过onCreate()-->onStart()-->onResume()3个生命周期。在onCreate()方法中对窗体界面进行渲染,将控件初始化并设置事件监听,一旦触发则执行相应方法。在Spinner控件初始化时设置选择条目监听setOnItemSelectedListener,当选择串口参数时,触发执行MyOnItemSelectedListener类的onItem-Selected()方法,实现串口参数修改。

//渲染窗体

setContentView(R.layout.activity_main);//波特率选择控件初始化

spBaudRate1=(Spinner)findViewById(R.id.DevSpinner1);

ArrayAdapter<CharSequence>adapter=ArrayAdapter.createFromResource(this,R.array.BaudRateList,android.R.layout.simple_spinner_item);

adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

spBaudRate1.setAdapter(adapter);

spBaudRate1.setOnItemSelectedListener(new MyOnItemSelectedListener());

APP软件的串口参数缺省设置为9 600、N、8、1。以波特率为例,9 600在Spinner下拉列表中排序第5,在初始化时,需通过setSelection()方法将第5项设置为缺省。

//缺省波特率设置为9 600

spBaudRate1.setSelection(5);

spBaudRate1.setEnabled(false);

在 Button、CheckBox、EditText等控件初始化时,设置点击事件监听setOnClickListener。在点击“打开”Button时,触发执行 OpenUARTDevice()方法。

//设置“打开”Button的点击事件监听

btOpen1 = (Button)findViewById(R.id.OpenButton1);

btOpen1.setOnClickListener(new Button.On-ClickListener(){

public void onClick(View v){

OpenUARTDevice(DeviceIndex1);

});

在OpenUARTDevice()方法中,根据onItem-Selected()方法设置的串口参数或缺省串口参数打开串口,其中boolean型返回值res如为true,表明串口打开成功。

//按照预设串口参数打开串口

res=mSerialMulti.PL2303OpenDevByUARTSetting (index, info.mBaudrate,info.mDataBits,info.mStopBits,info.mParity,info.mFlowControl);

在串口打开后,依然可以在onItemSelected()方法中修改串口参数,并重新建立串口连接。

//重设串口参数

res=mSerialMulti.PL2303SetupCOMPort(iSelected,info.mBaudrate,info.mDataBits,info.mStopBits,info.mParity,info.mFlowControl);

3.2 串口读取

APP软件在读取串口信息时,并不知道信息何时发送,也不知道信息的长度,需要定时检查是否有信息传来。本研究建立了一个单独的串口读取子线程,在子线程中持续访问PL2303HXD芯片输出缓冲区,以便在溢出或覆盖前及时将串口发来的信息取出,流程如图4所示。

图4 串口读取流程示意图

利用Runnable接口创建子线程是Android系统中常用的技术,通过重写其run()方法来实现程序功能。本研究基于此建立了串口读取子线程ReadLoop1,在其run()方法中通过for循环不断读取串口输出缓冲区。子线程在主线程中通过Thread实例创建并运行,直至软件退出才结束。

//启动串口读取子线程

new Thread(ReadLoop1).start();

……

//子线程的实现

private Runnable ReadLoop1=new Runnable(){

public void run(){

for(;;){

//延时 50ms

DelayTime(50);

……

};

驱动库pl2303multilib.jar提供了串口的读取方法PL2303Read(),本研究在每个for循环中读取一次输出缓冲区,读取的信息保存在字节型数组ReadBuf1中,int型返回值ReadLen1为本次读取信息的长度。缓冲区内的数据为Byte格式,读出后转换为字符串并追加到ReadBufOrig中,多次读取的数据长度累加为ReadLen。for循环需要在PL2303HXD芯片输出缓冲区写满之前将数据读出,并将缓冲区清空,以便后续信息从缓冲区的开始位置继续写入。在for循环中检测到某次读取为空时,表明一次数据传输完毕,整条数据已完全存放于字符串ReadBufOrig中,总长度为ReadLen。

//读取PL2303HXD芯片输出缓冲区

ReadLen1=mSerialMulti.PL2303Read(DeviceIndex1,ReadBuf1);

for(int j=0;j<ReadLen1;j++){

sbHex.append((char) (ReadBuf1[j]&0x000000FF));

ReadBufOrig=ReadBufOrig+sbHex.toString();

ReadLen+=ReadLen1;

在Android系统中,主线程只负责初始化和界面显示等任务,费时的操作全部放到子线程执行,在子线程完成运算需要显示时,必须将要显示的信息传递给主线程,通过主线程完成显示。一次数据传输完毕后,需要将读取到的信息显示到软件窗体的TextView控件上。本研究利用Handler.post(Runnable)方法将读取完整的字符串格式信息传递到主线程,在主线程更新Text-View显示控件tvRead1,实现读取数据的显示。在接收到下一条串口信息时,tvRead1刷新显示新接收的信息。DZZ1-2新型自动气象站在开机时通过串口输出一系列中文编码的系统说明[16],为兼容显示,字符串在显示前转换为GBK字符集编码。

//在主线程中创建Handler

HandlermHandler1=new Handler();……

//在子线程中通过 Handler.post(Runnable)方法更新主线程UI

mHandler1.post(new Runnable(){public void run(){

//转换为GBK字符集编码ReadBuf=new String(ReadBufOrig.getBytes(“ISO-8859-1”),“GBK”);

//更新 TextView显示

tvRead1.setText(ReadBuf);

……}

});

3.3 串口发送

软件的串口发送功能需要人工输入待发送内容,通过点击“发送”按键完成串口发送。程序初始化时对串口“发送”Button控件设置了点击事件监听 setOnClickListener,重写其 WriteT-oUARTDevice()方法,利用驱动库pl2303multilib.jar提供的串口发送方法PL2303Write()将要发送的信息按字节写入PL2303HXD芯片输入缓冲区,通过串口发送出去。由于要发送的信息长度可能超过输入缓冲区容量,本研究将待发送信息打断,逐64 Byte发送,剩余长度不足64 Byte时则一次性发送。

while(strWrite.length()/64! =0){

String tmp=new String(strWrite.substring(0,64));

//串口逐64 Byte发送

res = mSerialMulti.PL2303Write(index,tmp.getBytes(“GBK”));

strWrite=strWrite.substring(64);

DelayTime(50);

//不足64 Byte则一次性发送

res=mSerialMulti.PL2303Write(index,str-Write.getBytes(“GBK”));

根据中国气象局综合观测司的要求,新型自动气象(气候)站的指令以<回车> <换行>(“\r\n”)结尾[17,18]。在 PC的串口助手中,只需要敲击键盘的“回车”键即可输入<回车><换行>,但在Android系统的输入法中,“回车”键只能输入 <换行 >(“\n”),而无 <回车 >(“\r”)。为此,软件设计了“指令”CheckBox控件,勾选后自动在待发送字符串末尾追加字符串“\r\n”,实现正常的指令下发。

4 应用介绍

4.1 串口测试

套件支持Android手机与电脑串口通信,能够对DZZ1-2新型自动气象站、WP3103区域自动气象站、EWOS-1生态气象自动观测系统、PTB330气压传感器、Belfort6000能见度仪等设备的串口输出检查,也可应用于其他通用串口设备。利用转换模块连接DZZ1-2新型自动气象站数据采集器和手机,在Android手机上运行APP软件,勾选“指令”,向数据采集器发送“dmgd”即可调取分钟观测数据,如图5所示。

图5 向DZZ1-2型数据采集器发送指令

4.2 打环测试

利用套件可以对光电转换器、串口服务器、通信电缆等通信传输设备做打环测试。将套件的RS232串口与光电转换器RS232串口连接,用光纤回路器连接光电转换器的光纤收发接口,在APP软件发送测试信息,如光电转换器工作正常,则软件串口读取显示区将显示发出的测试信息,如图6所示。

图6 打环测试界面

自动气象站、气压传感器、超声风传感器、能见度仪、串口服务器、光电转换器等多种设备均使用了串口通信,以往只能通过电脑串口来检查设备串口状态或设置设备参数。本研究利用PL2303HXD芯片开发了运行在Android手机的串口通信套件,实现Android手机与设备间的串口通信,为自动气象观测设备串口通信故障现场排查提供了一个方便、可靠、低成本的工具。由于Android手机广泛普及,本套件的经济成本极低,也更加便携,适合在自动气象观测维保一线推广应用。

猜你喜欢
套件缓冲区控件
基于维修费用的关键部套件分析
基于.net的用户定义验证控件的应用分析
“龙吟套件”创作感悟
关于.net控件数组的探讨
部署前的准备工作
工业照明超频三天棚灯套件改造工程
一类装配支线缓冲区配置的两阶段求解方法研究
关键链技术缓冲区的确定方法研究
初涉缓冲区
多目标缓冲区生成算法