最近项目里面要集成一个扫码枪,我来负责对接。不得不说,这个扫码枪属实是我见过最烦的。首先便是硬件,送过来需要自己组装,然后网线需要自己做一根来接入他们的引脚,也没有充电线需要24V电压,得需要电压转换器然后直连。硬件有电气负责搞好,然后就是软件部分。正常一个硬件设备接手的时候,会有一个文档告知通信协议,有些好一点的都有对应的SDK,而这个官网上只有一个116页的英文PPT,问售后说没有中文版本的=====,没办法只能用网易有道词典一个一个截屏翻译看了=====
吐槽归吐槽,我痛苦了不能让广大网友也痛苦。
设备连接配置:
扫码枪安装完上电通过网线与设备直线后,设置IP。
扫码枪的默认IP:192.168.60.101,IP 设置为同一网段即可。
设置完后,不用下载官网的软件,直接可以在网页上对扫码枪的一些配置进行设置与调试。
网页上输入192.168.60.101进入设置网页。
右上角国家国旗标识可以设置语言,不然纯英文属实糟心。
左上角设置操作模式和维修模式,操作模式调节功能无法使用,点击即可切换模式。
设置IP:
配置——》通信,点击TCP/IP激活即可修改。点击以太网接口即可查看并修改IP,修改完后需要断电重启才可完成配置。
调试:
调节——》读取范围,鼠标放在对应的按钮上即可显示对应的功能,使用手册中提供的条形码扫码,数据会在下方显示,表明连接成功。
主要几个通信命令:
* 写入数据,单次执行:
ASCII 是 "+",十六进制是 “2B”,表示开启扫码.只读取一次,读取到数据后会关闭扫码或者几秒内未读到也会关闭
ASCII 是 “-”,十六进制是 "2D",表示关闭扫码。详情参考用户手册最后ASCII码对应表
* 写入数据,持续执行
ASCII 是 "JP+",十六进制是 “4A502B”,表示开启持续扫码.持续读取,读取到的数据后添加在前一条数据后
ASCII 是 “JP-”,十六进制是 "4A502D",表示关闭持续扫码
ASCII 是 “H”,十六进制是 "48",表示重启设备并初始化
使用socket通信,saomaqiang完整代码:
这其中使用了十六进制转byte数组与ASCII码直接相互转换,我在上篇博客有提供工具类。
package com.example.demo.barcodeScanners;
import com.example.demo.utils.HexToASCToBytes;
import java.io.*;
import java.net.Socket;
/**
* @author zhangqianwei
* @date 2021/10/21 16:04
*/
public class saomaqiang {
private static Socket socket;
static {
try {
//通过IP与端口号建立socket连接
socket = new Socket("192.168.60.101",10000);
if (!socket.isConnected()){
System.out.println("连接失败");
}
System.out.println("连接成功");
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
read();
}
/**
* 写入数据,单次执行:
ASCII 是 "+",十六进制是 “2B”,表示开启扫码.只读取一次,读取到数据后会关闭扫码或者几秒内未读到也会关闭
ASCII 是 “-”,十六进制是 "2D",表示关闭扫码。详情参考用户手册最后ASCII码对应表
* 写入数据,持续执行
ASCII 是 "JP+",十六进制是 “4A502B”,表示开启持续扫码.持续读取,读取到的数据后添加在前一条数据后
ASCII 是 “JP-”,十六进制是 "4A502D",表示关闭持续扫码
ASCII 是 “H”,十六进制是 "48",表示重启设备并初始化
**/
public static void read() {
try{
OutputStream os = socket.getOutputStream();
//持续读取输出数据
String sustainOpen = "4A502B";
//hexStringToByteArray(),十六进制字符串转byte数组
byte[] openBytes = HexToASCToBytes.hexStringToByteArray(sustainOpen);
os.write(openBytes);
//读取扫码枪获取到的数据
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
DataInputStream dis = new DataInputStream(bis);
byte[] bytes = new byte[1]; // 一次读取一个byte
String ret = "";
String ASC = "";
while (dis.read(bytes) != -1) {
ret += HexToASCToBytes.ByteArrayToHexString(bytes) + " ";
if (dis.available() == 0) {
//当转换完所有数据后返回转换完的十六进制字符串
System.out.println(socket.getRemoteSocketAddress() + ":" + ret);
//去除前面的状态符,“30 30 30 20 ”
ret = ret.substring(12);
//将转换的十六进制字符串再转为ASC码
String[] hexs = ret.split(" ");
for (String str:hexs){
ASC += HexToASCToBytes.convertHexToASC(str);
}
System.out.println("ASCII码结果是:"+ASC);
//每次扫完码重置,确保每次扫码转换的都是最新的
ret ="";
ASC ="";
}
}
os.close();
}catch (IOException e){
e.printStackTrace();
}finally {
try {
//防止异常,不论如何最后都要关闭socket连接,否则下次无法再次创建
socket.close();
}catch (IOException ioException){
ioException.printStackTrace();
}
}
}
public static void close(){
try {
//关闭持续扫码,“48”是重启设备并初始化
String close = "4A502D";
byte[] closeBytes = HexToASCToBytes.hexStringToByteArray(close);
OutputStream os = socket.getOutputStream();
os.write(closeBytes);
os.close();
}catch (IOException e){
e.printStackTrace();
}finally {
try {
//防止异常,不论如何最后都要关闭socket连接,否则下次无法再次创建
socket.close();
}catch (IOException ioException){
ioException.printStackTrace();
}
}
}
}