Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.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
ruby中在自定义协议上实现校验和位的问题_Ruby_Serial Port_Byte_Protocols - Fatal编程技术网

ruby中在自定义协议上实现校验和位的问题

ruby中在自定义协议上实现校验和位的问题,ruby,serial-port,byte,protocols,Ruby,Serial Port,Byte,Protocols,我有以下协议规范,用于将消息发送到我正在集成的设备,按顺序分为字节: 二进制0x02起始字节 ASCII“1”或“2”或“3”或“4”设备地址 ASCII“0”-无更改“1”-更改输出负载输出更改 ASCII“E”-升压电压设置“D”-放电电压设置“T”-温度补偿设置“C”-最大值 ASCII“0”-无更改“-”-所选值向下更改“+” 二进制s=(字节)和(2;5)CRC_H=0b1000_s7_s6_s5_s4校验和高位字节 二进制s=(字节)和(2;5)CRC\u L=0b1000\u s3

我有以下协议规范,用于将消息发送到我正在集成的设备,按顺序分为字节:

  • 二进制0x02起始字节
  • ASCII“1”或“2”或“3”或“4”设备地址
  • ASCII“0”-无更改“1”-更改输出负载输出更改
  • ASCII“E”-升压电压设置“D”-放电电压设置“T”-温度补偿设置“C”-最大值
  • ASCII“0”-无更改“-”-所选值向下更改“+”
  • 二进制s=(字节)和(2;5)CRC_H=0b1000_s7_s6_s5_s4校验和高位字节
  • 二进制s=(字节)和(2;5)CRC\u L=0b1000\u s3\u s2\u s1\u s0校验和低字节
  • 二进制0x03
  • 我无法正确获取字节6和7

    不太清楚如何计算校验和,它说字节6和7是(2;5)的和-2是什么;5是什么意思

    我目前拥有的代码是:

    require 'serialport'
    
    # Open collector serial port
    serial = SerialPort.new('/dev/ttyAMA0', baud: 9600, data_bits: 8, stop_bits: 1,
      parity: SerialPort::NONE)
    
    checksum = '10E0'.unpack("C*").inject(:+).ord
    p serial.write(0x02.chr) # start byte
    p serial.write('10E0') # commands
    p serial.write(checksum + checksum) # checksum byte 1 + 2
    p serial.write(0x03.chr) # End byte
    p serial.read
    
    没有回应的运气。有人知道我做错了什么吗?或者更好地理解这个规范

    非常感谢

    您的“协议规范”令人困惑。对于字节6和7,它同时提到“校验和”和“CRC”。这是两种不同类型的计算。它们不是同义词。当存在多个位错误时,校验和容易出现错误验证。CRC在检测错误方面要好得多

    因此,您需要解决是否需要计算CRC-8校验值或消息字节2到5的校验和(截断为一个字节)的问题。不管怎样,最终都会有一个8位值存储在消息字节6和7中

    您的“协议规范”包括:

    显然,校验和字节的高位半字节(即位“s7_s6_s5_s4”)存储在设置高位(位8)的消息字节6中(如“0b1000_”位字符串所示)。校验和字节的低半字节(即位“s3_s2_s1_s0”)存储在设置了高位(位8)的消息字节7中

    假设设置位8(每个字节中)将防止在校验和结果为0x02或0x03时错误检测消息的开始或结束字节。这将通过使消息框架易于识别和难以错误识别来提高消息的完整性

    我不做ruby,所以只能提供C代码

    unsigned char chksum = mesg[2] + mesg[3] + mesg[4] + mesg[5];
    mesg[6] = 0x80 | ((chksum >> 4) & 0x0f);
    mesg[7] = 0x80 | (chksum & 0x0f);
    

    吃两片阿斯匹林,然后看一看和。谢谢你,我如何把1101和0110写成一个字节我试过1101.ord,但是上面写着'chr':1101超出了字符范围(RangeError)。对不起,我在我的原始评论中犯了一个错误,所以我删除了它,并将在下面添加一个更正的版本。我不熟悉
    SerialPort
    ,因此您必须检查文档以了解如何写入字节
    0x0
    0xD6
    。看起来#5可能是“0”、“-”或“+”的ASCII值,但只有两个描述符(“无更改”和“-选定值向下更改”)。请澄清。我假设“sum of(2;5)”是指#2-#5的字节之和。4个字节的总和可以是需要2个字节的数字;因此,需要#6和#7<代码>t=('1'.ord+'0'.ord+'E'.ord+'0'.ord)#=>214;t、 to#s(16)#=>“D6”给出了#2-#5的四个可能值之和的十六进制表示。由于这是一个单字节,高阶字节是
    0
    ,低阶字节是
    0xD6
    。我基于上述内容尝试了这一点,但仍然没有得到响应:(
    p serial.write(0x02.chr)#start byte
    p serial.write('10E0')#命令
    p serial.write(0x0.chr)#校验和1

    p serial.write(0x03.chr)#结束字节
    p serial.read
    unsigned char chksum = mesg[2] + mesg[3] + mesg[4] + mesg[5];
    mesg[6] = 0x80 | ((chksum >> 4) & 0x0f);
    mesg[7] = 0x80 | (chksum & 0x0f);