如何在pymodbus寄存器中存储带符号的16位值

时间:2016-01-19 07:58:44

标签: python python-2.7 modbus

我正在尝试实现pymodbus服务器。我在ModbusSlaveContext中使用ModbusSparseDataBlocks。这项工作到目前为止。客户端可以从实例化的每个寄存器中写入和读取vales。

但我有负值的问题。客户端需要16位有符号整数格式,他无法解释我的负值。

这是我用寄存器填充值的方法:

public boolean emptyField(String editText, TextInputLayout textInputLayout, String errorMessage){

        if(editText.trim().isEmpty()){

            setLayoutError(textInputLayout, errorMessage);

            return false;

        }else{

            removeError(textInputLayout);
            return true;
        }
    }


private void setLayoutError(TextInputLayout textInputLayout, String error){

    if(!textInputLayout.isErrorEnabled()){
        textInputLayout.setErrorEnabled(true);
        textInputLayout.setError(error);
        textInputLayout.getEditText().setTextColor(context.getResources().getColor(android.R.color.holo_red_dark));
    }
}

private void removeError(TextInputLayout textInputLayout){
    if(textInputLayout.isErrorEnabled()){
        textInputLayout.setErrorEnabled(false);
        textInputLayout.getEditText().setTextColor(context.getResources().getColor(android.R.color.black));
    }
}

如何将有效的16位有符号整数写入寄存器?

(我使用的是python 2.7和pymodbus 1.2.0版本)

3 个答案:

答案 0 :(得分:2)

看起来你的图书馆只能理解无符号的16位数字。如果你在Python中使用0xFFFF(一个16位掩码)对带符号的AND值进行按位,那么你将获得相同的结果:

你在做什么:

>>> import struct
>>> struct.unpack('<H',struct.pack('<h',-100))[0]
65436

按位与:

>>> -100 & 0xFFFF
65436

所以你可以这样做:

context[0x00].setValues(4, 0x10, -100 & 0xFFFF)

正值不受影响,负值导致无符号16位2的补码值。

要将无符号2的补码16位值转换回有符号,请测试符号位(2 15 )并减去2 16 (如果存在) :

value = value-2**16 if value & 2**15 else value

或等效地:

value = value-0x10000 if value & 0x8000 else value

答案 1 :(得分:0)

我发现以下内容适用于我,但我不知道这是否是正确和安全的方式。

import struct

def signed(value):
    packval = struct.pack('<h',value)
    return struct.unpack('<H',packval)[0]

#write positive value (100) to IR[0x10] --> client interprets this correctly
context[0x00].setValues(4, 0x10, signed(100))
#write negative value (-100) to IR[0x10] --> client interprets this correctly
context[0x00].setValues(4, 0x10, signed(-100))

答案 2 :(得分:0)

您也可以手动计算:

if value < 0:
    value = 2**16 + value
context[0x00].setValues(4, 0x10, signed(value))