明博一维扫描头调试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,这样可以一次传输多个字节
通过阅读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,这样可以一次传输多个字节
相关文章推荐
- Windows Phone 7开发技巧【2】——使用ZXing库实现一维/二维条码扫描
- 用手机QQ扫描二维码可显示网址,方便调试
- 如何在代码里区分条码扫描扫描到是是一维码还二维码
- 74HC595扩展按键扫描---调试笔记
- 使用ZXing库实现一维/二维条码扫描
- 搞定一维条码扫描
- Camera驱动预调试 Review
- 关于如何在代码里区分条码扫描扫描到是是一维码还二维码
- S5PV210串口驱动——一维激光扫描模块(motorola symbol SE955)
- 【一维dp_线性扫描】Word Break 、Best time to Buy and Sell Stocks |||、max subarray、jump game |||
- 调试扫描头
- 【LeetCode】Jump Game (一维动态规划 + 线性扫描)
- JSF调试小志1-恢复视图阶段(RestoreViewExecutor)
- Web安全漏洞之:JDK1.5环境下扫描远程调试端口导致JVM崩溃【JDWP exit error JVMTI_ERROR_NONE(0)】
- 【LeetCode】Jump Game (一维动态规划 + 线性扫描)
- 推荐FLASH调试工具-AdminTool
- [原]Bug Report,已提交给微软。平台调用调试时,无法对非托管函数进行单步的错误
- vs2005调试时,弹出“没有可用于当前位置的源代码”
- QT 4 设定按钮大小,设定wigdet 大小例子(调试通过)
- Eclipse+CDT+GDB调试android NDK程序