您的位置:首页 > 其它

明博一维扫描头调试Review

2016-12-21 11:34 120 查看
明德的UE966说白了就是抄袭的zebra的SE955

通过阅读SE955 Datasheet可以知道,设置条码头参数有两种方法:

1.通过扫描手册里的设置条码来设置条码头参数。
2.通过串口给条码头发送指令来配置条码头。
这里主要讲第二种方法
要想与条码头通信,必须通过硬件接口线并遵循SSI协议
SSI全称为Simple Serial Interface,它的作用有:
1.维持与条码头的双向接口
2.使主体设备能给条码头发送能控制条码头的指令
3.传递条码头传来的SSI格式的数据包或直接解码的信息给主体设备

SSI支持的指令如下:


 
AIM_OFF/ AIM_ON  是激活和关闭aim pattern,不过我们的条码头没有aim pattern。
BEEP 是发声,经测试我们的条码头不支持。
CMD_ACK /CMD_NAK 分别表示设置成功和失败后的回应。
DECODE_DATA 表示设置条码头解码的数据是SSI信息格式的。
EVENT 是设置指定事件是否有响应,其中包括DECODE EVENT(成功解码后条码头是否生成信息发给设备),BOOT UP EVENT(系统供电是否发信息给设备),Parameter Event(参数设置后是否通知设备)。
LED_OFF/LED_ON 是激活和关闭led灯,我们的不支持
PARAM_DEFAULTS 是将所有参数设置成初始化的值
PARAM_REQUEST 是查看某个或某些参数的值
PARAM_SEND 是设置所指定的参数的值
REQUEST_REVISION/REPLY_REVISION 是查看条码头版本号和条码头回复版本号
SCAN_DISABLE/SCAN_ENABLE 设置条码头能否扫描
SLEEP/WAKEUP 设置条码头休眠和唤醒
START_DECODE/STOP_DECODE    开始和停止扫码,必须在host trigger mode下才能用
CUSTOM_DEFAULTS  将当前的参数值写入初始化值或者恢复初始化值

SSI 信息格式:


 
length是长度,是除了校验和以外的长度,占一个字节
opcode是指令的类型,对应表10-1,占一个字节
message source是消息来源,0代表条码头,04代表HOST,占一个字节
status是状态码,一般写0,占一个字节
data是数据,可有可无,可以是多项,根据指令类型要求来写
checksum是校验和,是除了校验和以外的信息的和的补码,占两字节,高位在前低位在后
Java里指令的组成必须是字节数组

下面是根据手册描述列出一些固定指令例子
CMD_ACK  :{0x04,0xD0,0x00,0x00,0xFF,0x2C}
CMD_NAK :{0x05,0xD1,0x00,0x00,0x01,0xFF,0x29}
第五个01表示校验和错误
PARAM_DEFAULT :{0x04,0xC8,0x04,0x00,0xFF,0x30}
REQUEST_REVISION :{0x04,0xA3,0x4,0x00,0xFF,0x55}
SCAN_DISABLE :{0x04,0xEA,0x04,0x00,0xFF,0x0E}
SCAN_ENABLE :{0x04,0xE9,0x04,0x00,0xFF,0x0F}
START_DECODE :{0x04,0xE4,0x04,0x00,0xFF,0x14}
STOP_DECODE :{0x04,0xE5,0x04,0x00,0xFF,0x13}
SLEEP : {0x04,0xEB,0x04,0x00,0xFF,0x0D}
WAKEUP :{0x00} 唤醒比较特殊,只要发送一个NULL(0x00)这里校验和是直接计算给出的,运用到代码里时最好是通过算法自动算出并补齐

当我们发送REQUEST_REVISION
:{0x04,0xA3,0x4,0x00,0xFF,0x55}指令后,条码头会返回REPLY_REVISION指令
在我们机器上测试返回的是{0x19,0xA4,0x00,0x00,0x4E,0x42,0x52,0x53,0x59,0x50,0x41,0x4E,0x20,0x46,0x20,0x98,0x20,0x00,0x00,0xFB,0x98}
其中0x4E,0x42,0x52,0x53,0x59,0x50,0x41,0x4E,0x20,0x46,0x20,0x98,0x20,0x00,0x00是对应的版本号,是ASCII码的
查看手册格式可知空格是分界,而空格对应的ascii码表里十六进制是20,所以S/W_REVISION:0x4E,0x42,0x52,0x53,0x59,0x50,0x41,0x4E   BOARD_TYPE:0x46     SCANNER_ID:0x98   PGM_CHKSUM:
0x00,0x00
转化后为:S/W_REVISION:NBRSYPAN ,BOARD_TYPE:F ,SCANNER_ID:0x98


 
SCANNER_ID:0x98对应的是SE-955 IEC825 Class 1


 

然后具体讲下设置参数的指令 PARAM_SEND和查看参数值的指令 PARAM_REQUEST
要设置参数,还需结合手册中parameter menus


 
参数有 电源模式、触发模式、各种条码类型的设置、条码数据前后缀设置以及数据显示格式等等
例如triggering mode,手册中可查到0x8A就代表是它


 
然后它的值的选项有level(0x00),pulse(0x02),continues(0x04),Blinking(0x07),host(0x08)五种,默认是带*号的


 
如果我们要设置条码头连续扫描,就要先选择好参数和值,0x8A 0x04
然后看PARAM_SEND的格式


 
可以看到它的格式中data有beep code和params data,声音代码可到beep里查,不过我们的没有声音,所以直接设置为0xFF
params data的格式如下,即0x8A 0x04


 
写成没有校验和的指令数组就是{0x07,0xC6,0x04,0x00,0xFF,0x8A,0x04},因为检验和在代码里自动加上,所以发送的指令省去后两位

如果要查看某参数的值就用PARAM_REQUEST,其格式:


 
可以看到,格式中的data是参数的代码,而且可以指定查询多个参数
要查看当前触发模式的值,写成没有校验和的指令数组就是{0x05,0xC7,0x04,0x00,0x8A}
如果通信成功的话,条码头就会回应一串PARAM_SEND格式的指令

不过手册里有些参数的值没有给定,比如Time-out Between Same Symbol


 
这个是在连续触发模式时的扫描间隔,手册里只给了个范围0.0-9.9
这时PARAM_REQUEST就派上用场了,默认为1秒,查看回馈的值是0x0A,又看了默认为3秒的参数的值为0x1E
可以得出1.0s对应十进制的10,十六进制的A,2.0s对应十进制的20,十六进制的14,以此类推就是将时间乘以10再转为十六进制
如设为1.5s,指令数组写为{0x07,0xC6,0x04,0x00,0xFF,0x89,0x0F}
要设置其他参数只要查找参数的编号和值换上即可

有的指令必须在指定模式里发送才能作用,比如控制条码头扫码,必须在Host triggering mode下才能用
所以要先发送指令{0x07,0xC6,0x04,0x00,0xFF,0x8A,0x08},然后再发送START_DECODE指令
:{0x04,0xE4,0x04,0x00,0xFF,0x14}
这样就能通过指令控制条码头扫码了

了解了指令的规则后,要想跟条码头通信还要对GPIO进行控制
从手册中可以看出,当主机要发送数据给条码头时,要接上Host RTS ,这时条码头端就会CTS,然后条码头端就不能发送数据,直到主机接Host CTS,条码头才能发送数据


 

 
不过我们的机器只有CTS一条线,所以当主机要发送数据时,只要拉低CTS即可,发送完再拉高就可等待条码头回应了

如果你的硬件不需要硬件流控,直接把CTS拉高就可以了,否则接受会出问题

请求发送

public static void reqToSend(){

                EMgpio.SetGpioOutput(PIN_BARCODE_POWER);

                EMgpio.SetGpioOutput(PIN_BARCODE_CTS);

                EMgpio.SetGpioDataHigh(PIN_BARCODE_POWER);

                EMgpio.SetGpioDataLow(PIN_BARCODE_CTS);

        }

复制代码
结束发送

public static void clrToSend(){

                EMgpio.SetGpioOutput(PIN_BARCODE_POWER);

                EMgpio.SetGpioOutput(PIN_BARCODE_CTS);

                EMgpio.SetGpioDataHigh(PIN_BARCODE_POWER);

                EMgpio.SetGpioDataHigh(PIN_BARCODE_CTS);

        }

复制代码

前面讲到检验和是除了检验和以外的信息的和的补码,其算法如下:

public static byte[] addChecksum(byte cmd[],int len) {

                int sum = 0;

                byte check[]=new byte[len+2];

                for(int i=0;i<len;i++){

                        sum += (cmd[i]&0xff);//先得到临时指令的和

                }

                int checksum = ~sum + 1;//计算补码,即反码加1 

                System.arraycopy(cmd, 0, check, 0, len);//复制cmd数组到check

                check[len] = (byte) ((checksum>>8)&0xff);//右移运算符得到检验和高位

                check[len+1] = (byte) (checksum&0xff);//检验和低位

                String str ="";//用来打印完整指令

                for(int i=0;i<len+2;i++){

                        str +=Integer.toHexString(check[i]&0xff);

                        str += ',';

                }

                Log.d(TAG, str);

                return check;

                

        }

复制代码
连接好指定串口后,把指令写入串口

public static void sendData(byte cmd[],int len) {

try {

if(!connect.isOpen()){

connect.open();//打开串口连接

}

connect.write(cmd, 0, len);//数据写入串口

} catch (FalconException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

try {

connect.close();

} catch (FalconException e1) {

// TODO Auto-generated catch block

e1.printStackTrace();

}

e.printStackTrace();

}        

}

复制代码

发送指令时要注意,由于条码头可能是睡眠模式,一般要先发送唤醒指令,不然条码头会把指令的前一位当作唤醒,再计算后面的信息就会误认为你的检验和错误

public void paramSend(byte[] cmd, int len) {

                Platform.reqToSend();//拉低cts

                mServiceAdapter.sendData(wakeup);

                try {

                        Thread.sleep(4);

                } catch (InterruptedException e) {

                        // TODO Auto-generated catch block

                        e.printStackTrace();

                }

byte[] buffer = IoServiceAdapter.addChecksum(cmd, len);//添加检验和

                IoServiceAdapter.sendData(buffer, len);

                Platform.clrToSend();//拉高cts

        }

复制代码
最后,写好指令发送即可
byte cmd[] = {0x07,(byte) 0xc6, 0x04, 0x00, (byte) 0xff,(byte) 0x8a,0x04};
paramSend(cmd, cmd.length);

注:

波特率最好设置成9600,这样可以一次传输多个字节
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: