Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何将十六进制字符串转换为可读数字/十进制表示(来自RS485串行设备的压力读数响应)_Javascript_Serial Port_Hex_Ascii_Rs485 - Fatal编程技术网

Javascript 如何将十六进制字符串转换为可读数字/十进制表示(来自RS485串行设备的压力读数响应)

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

所以我正在将这个离子计(设备读取腔室内部的压力)从ASCII协议切换到二进制协议(尽管它实际上通过十六进制进行通信)。该设备通过RS485串行通信与我们的PC接口。我目前正在使用javascript发送和接收ASCII协议命令

发送的命令和从设备接收的响应都有一种格式。
发送到设备的命令长度=返回的响应长度

向装置发送命令:

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('');
    
    将数组转换为从第一个数组项开始的十六进制字符对字符串

  • 需要它们吗?

    这个答案最初描述了二进制协议消息被转换成十六进制数字对流,以便通过RS-485通信链路进行传输。这是基于报告(某种)终端上显示了压力表的十六进制输出的问题,以及手册第59页的附加说明

  • 发送至装置和从装置接收的信息以十六进制形式发送
  • 对此答案的评论指出,二进制协议“消息”记录在手册的其他地方,如同直接通过RS485链路作为二进制字节发送,不转换为十六进制

    我同意“以十六进制发送”可能就是这种情况,意思是“以二进制字节发送”,上面的二进制/十六进制转换仅供参考

    有关二进制协议的更多信息

  • 二进制消息是由8个二进制位字节(或“八位字节”)组成的序列,以从前面的消息字节计算出的8位循环冗余校验字节结尾。(CRC值的一个特性是,如果未发生传输错误,则将CRC计算应用于整个消息(包括末尾的CRC8字节),将产生零结果。)

  • 回车似乎是ASCII协议的一部分,我在手册中没有发现在二进制消息中提到回车(请在实践中重新检查)

  • 回复的预期长度与发送的长度相同

  • 如果二进制字节表示ASCII字符,则其数值为该字符的ASCII字符代码。例如

    '*'.charCodeAt(0)
    
    将星号转换为数字42(十进制),然后

    将数字42转换为星号

  • 转换浮点更为棘手。我在代码段中使用的方法是将4个浮点字节值放入
    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)