Javascript 如何将十六进制字符串转换为可读数字/十进制表示(来自RS485串行设备的压力读数响应)
所以我正在将这个离子计(设备读取腔室内部的压力)从ASCII协议切换到二进制协议(尽管它实际上通过十六进制进行通信)。该设备通过RS485串行通信与我们的PC接口。我目前正在使用javascript发送和接收ASCII协议命令 发送的命令和从设备接收的响应都有一种格式。Javascript 如何将十六进制字符串转换为可读数字/十进制表示(来自RS485串行设备的压力读数响应),javascript,serial-port,hex,ascii,rs485,Javascript,Serial Port,Hex,Ascii,Rs485,所以我正在将这个离子计(设备读取腔室内部的压力)从ASCII协议切换到二进制协议(尽管它实际上通过十六进制进行通信)。该设备通过RS485串行通信与我们的PC接口。我目前正在使用javascript发送和接收ASCII协议命令 发送的命令和从设备接收的响应都有一种格式。 发送到设备的命令长度=返回的响应长度 向装置发送命令: Byte 0: '!' (hex 0x21) <-- start character Byte 1: '1' (hex 0x01) <-- address of
发送到设备的命令长度=返回的响应长度
向装置发送命令:
Byte 0: '!' (hex 0x21) <-- start character
Byte 1: '1' (hex 0x01) <-- address of unit, this is a constant
Byte 2: '2' (hex 0x02) <-- command byte value, this will change as you change commands
Byte 3: '0' (hex 0x00) <-- dont care UNITS
Byte 4: '0' (hex 0x00) <-- dont care data 1
Byte 5: '0' (hex 0x00) <-- dont care data 2
Byte 6: '0' (hex 0x00) <-- dont care data 3
Byte 7: '0' (hex 0x00) <-- dont care data 4
Byte 8: 183 (hex 0xB7) <-- CRC - Carriage return - Not actually typed by user
For testing, this command is physically sent through a serial terminal as:
'0x21 0x01 0x02 0x00 0x00 0x00 0x00 0x00 0xB7'
Byte 0: '*' (hex 0x2A) <-- start character
Byte 1: '1' (hex 0x01) <-- address of unit, this is a constant
Byte 2: '2' (hex 0x02) <-- command byte value, this will change as you change commands
Byte 3: '0' (hex 0x00) <-- UNITS: 0=Torr, 1=Pascals, 2=mBAR
Byte 4: '0' (hex 0x00) <-- floating point byte 1
Byte 5: '0' (hex 0x00) <-- floating point byte 2
Byte 6: '0' (hex 0x00) <-- floating point byte 3
Byte 7: '0' (hex 0x00) <-- floating point byte 4
Byte 8: 148 (hex 0x94) <-- CRC - Carriage return
This response is received as: '2A 01 02 00 00 00 00 00 B7'
or '0x2A 0x01 0x02 0x00 0x00 0x00 0x00 0x00 0xB7'
(not sure if that's how it actually responds, or if my terminal program automatically formats for readability)
如果有人对我如何做到这一点有任何建议,我将非常感激。请参阅下面的手册,了解有关通信工作方式的更多信息
链接到我正在使用的特定设备的操作手册:
https://www.lesker.com/newweb/gauges/pdf/manuals/392usermanual.pdf
*PDF pg. 59: RS485 Serial Communicatoins - Binary Protocol
*PDF pg. 61: Notes when using Binary Protocol
*PDF pg. 62: RS485 Commands Summary
在回答标题中的问题时:
hextstring
是十六进制数字对的字符串
let binArray = hexSring.match(/../g).map( hex=> parseInt(hex,16));
使用反向逻辑将字符串转换为范围为[0-255]的无符号整数数组binArray
是范围为[0-255]的无符号整数数组
let hexString = binArray.map( byte=>byte.toString(16).padStart(2,'0')).join('');
将数组转换为从第一个数组项开始的十六进制字符对字符串'*'.charCodeAt(0)
将星号转换为数字42(十进制),然后
将数字42转换为星号Uint8
类型化数组,然后使用数组缓冲区创建一个Float32
类型化数组,第一个元素可以作为(浮点)数从中检索。正确性取决于fp字节在消息中的顺序(小端或大端),而使用零进行测试并不能揭示这一顺序——您可能需要颠倒JavaScript的字节顺序(希望不是这样)。使用a可能是另一种方法。我还假设插装使用与JavaScript相同的标准提供32位浮点值(它们已经存在了一段时间)2A0102000000094
。CRC8函数已从手册中提供的C版本翻译而来,并已修改为接受字节值数组,并计算调用中提供的所有字节的CRC:
函数计算\u CRC8(uint8Array){
var-CRC_值;
var计数器;
可变比特计数器;
var-XOR_字节;
无功传输;
//初始化局部变量。
CRC_值=0xFF;
//计算CRC。
用于(计数器=0;计数器 CRC_值查看parseInt(str,radix)的基数部分好的,我现在正在检查。看起来是朝着正确的方向迈出的一步,但是我有点像JS noob,并且在学习的过程中仍然在学习,所以仍然有点不清楚应该如何进行。我很擅长在前进的过程中弄清楚事情,我的问题更多的是开始,哈哈“二进制协议(虽然它实际上是通过十六进制进行通信)”--不,它是一个二进制协议,实际上是通过二进制值进行通信。为了方便起见,人类使用十六进制表示二进制。新手也使用“十六进制”指代十六进制数字的ASCII文本,因此您提到的“十六进制字符串”令人倍感困惑。”CRC-回车"--否,CRC
是一个使用多项式计算的值,而回车
是一个固定的代码值。一个用于二进制协议;另一个用于ASCII文本协议。在上面的代码中,我应该在哪里将要发送的命令字符串加载到CRC函数中,以计算所需的CRC以发送t发送给该装置的消息?我是否需要将“0x2A 0x01 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0xB7”加载到“TransmitByte”中?CRC8字节值根据
'*'.charCodeAt(0)
String.fromCharCode( 42)