明博一维扫描头调试Review

明德的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拉高就可以了,否则接受会出问题

请求发送
  1. public static void reqToSend(){
  2.                 EMgpio.SetGpioOutput(PIN_BARCODE_POWER);
  3.                 EMgpio.SetGpioOutput(PIN_BARCODE_CTS);

  4.                 EMgpio.SetGpioDataHigh(PIN_BARCODE_POWER);
  5.                 EMgpio.SetGpioDataLow(PIN_BARCODE_CTS);

  6.         }
复制代码
结束发送
  1. public static void clrToSend(){
  2.                 EMgpio.SetGpioOutput(PIN_BARCODE_POWER);
  3.                 EMgpio.SetGpioOutput(PIN_BARCODE_CTS);

  4.                 EMgpio.SetGpioDataHigh(PIN_BARCODE_POWER);
  5.                 EMgpio.SetGpioDataHigh(PIN_BARCODE_CTS);

  6.         }
复制代码

前面讲到检验和是除了检验和以外的信息的和的补码,其算法如下:
  1. public static byte[] addChecksum(byte cmd[],int len) {
  2.                 int sum = 0;
  3.                 byte check[]=new byte[len+2];
  4.                 for(int i=0;i<len;i++){
  5.                         sum += (cmd[i]&0xff);//先得到临时指令的和
  6.                 }
  7.                 int checksum = ~sum + 1;//计算补码,即反码加1 
  8.                 System.arraycopy(cmd, 0, check, 0, len);//复制cmd数组到check
  9.                 check[len] = (byte) ((checksum>>8)&0xff);//右移运算符得到检验和高位
  10.                 check[len+1] = (byte) (checksum&0xff);//检验和低位
  11.                 String str ="";//用来打印完整指令
  12.                 for(int i=0;i<len+2;i++){
  13.                         str +=Integer.toHexString(check[i]&0xff);
  14.                         str += ',';
  15.                 }
  16.                 Log.d(TAG, str);
  17.                 return check;
  18.                 
  19.         }
复制代码
连接好指定串口后,把指令写入串口
  1. public static void sendData(byte cmd[],int len) {
  2. try {
  3. if(!connect.isOpen()){
  4. connect.open();//打开串口连接
  5. }
  6. connect.write(cmd, 0, len);//数据写入串口
  7. } catch (FalconException e) {
  8. // TODO Auto-generated catch block
  9. e.printStackTrace();
  10. } catch (IOException e) {
  11. // TODO Auto-generated catch block
  12. try {
  13. connect.close();
  14. } catch (FalconException e1) {
  15. // TODO Auto-generated catch block
  16. e1.printStackTrace();
  17. }
  18. e.printStackTrace();
  19. }        
  20. }
复制代码


发送指令时要注意,由于条码头可能是睡眠模式,一般要先发送唤醒指令,不然条码头会把指令的前一位当作唤醒,再计算后面的信息就会误认为你的检验和错误
  1. public void paramSend(byte[] cmd, int len) {
  2.                 Platform.reqToSend();//拉低cts
  3.                 mServiceAdapter.sendData(wakeup);
  4.                 try {
  5.                         Thread.sleep(4);
  6.                 } catch (InterruptedException e) {
  7.                         // TODO Auto-generated catch block
  8.                         e.printStackTrace();
  9.                 }
  10. byte[] buffer = IoServiceAdapter.addChecksum(cmd, len);//添加检验和
  11.                 IoServiceAdapter.sendData(buffer, len);
  12.                 Platform.clrToSend();//拉高cts
  13.         }
复制代码
最后,写好指令发送即可
byte cmd[] = {0x07,(byte) 0xc6, 0x04, 0x00, (byte) 0xff,(byte) 0x8a,0x04};

paramSend(cmd, cmd.length);

注:

波特率最好设置成9600,这样可以一次传输多个字节

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值