Search code examples
pythonpython-3.xmodbusminimalmodbus

how to store MinimalModbus debug response in a variable?


import serial
import minimalmodbus
import time

instrument = minimalmodbus.Instrument('COM8', 127, debug=True)
instrument.serial.port
instrument.serial.baudrate = 19200
instrument.serial.parity = serial.PARITY_NONE
instrument.serial.bytesize = 8
instrument.serial.stopbits = 1
instrument.mode = minimalmodbus.MODE_RTU
instrument.serial.timeout = 0.300

b = instrument._communicate(b'\x7F\x66\x01\x00\x02\x00\x00\x00\x01\x00', 64)

print(b)

instrument.serial.close()

On the terminal, I get the following:

MinimalModbus debug mode. Create serial port COM8
MinimalModbus debug mode. Will write to instrument (expecting 64 bytes back): 7F 66 01 00 02 00 00 00 01 00 (10 bytes)
MinimalModbus debug mode. Clearing serial buffers for port COM8
MinimalModbus debug mode. No sleep required before write. Time since previous read: 1222683890.00 ms, minimum silent period: 2.01 ms.
MinimalModbus debug mode. Response from instrument: 7F 66 01 00 4C 00 00 00 44 54 01 00 20 00 44 54 CB 74 14 43 AD B2 15 43 00 00 FA 44 00 94 9E 41 88 6D 08 00 88 6D 08 00 00 00 00 00 1A AB C3 40 45 A5 70 42 54 60 99 45 CF C4 03 00 00 00 00 00 (64 bytes), roundtrip time: 0.0 ms. Timeout for 
reading: 300.0 ms.

b'\x7ff\x01\x00L\x00\x00\x00DT\x01\x00 \x00DT\xcbt\x14C\xad\xb2\x15C\x00\x00\xfaD\x00\x94\x9eA\x88m\x08\x00\x88m\x08\x00\x00\x00\x00\x00\x1a\xab\xc3@E\xa5pBT`\x99E\xcf\xc4\x03\x00\x00\x00\x00\x00'

When printing b, the data is not the same as the Response from instrument data. I assume it was distorted by some noise. Only the raw data is being stored in b. How can I get the actual data just like the response from instrument stored in variable b?


Solution

  • I assume it was distorted by some noise.

    No - it's just the way you are outputting it; if you don't provide it with a format print outputs the "formal string representation" (see str()). i.e. 7f is unprintable so output \7f, 66 = f so output f, 01 is unprintable so output \01 etc.

    This can be demonstrated with:

    sampleBytes = bytes(bytearray.fromhex('7F 66 01 00 4C 00 00 00 44 54 01 00 20 00 44 54 CB 74 14 43 AD B2 15 43 00 00 FA 44 00 94 9E 41 88 6D 08 00 88 6D 08 00 00 00 00 00 1A AB C3 40 45 A5 70 42 54 60 99 45 CF C4 03 00 00 00 00 00'))
    print(sampleBytes)
    print(" ".join([f"{x:02X}" for x in sampleBytes]) + " ({} bytes)".format(
            len(sampleBytes)
        ))
    

    which will generate:

    b'\x7ff\x01\x00L\x00\x00\x00DT\x01\x00 \x00DT\xcbt\x14C\xad\xb2\x15C\x00\x00\xfaD\x00\x94\x9eA\x88m\x08\x00\x88m\x08\x00\x00\x00\x00\x00\x1a\xab\xc3@E\xa5pBT`\x99E\xcf\xc4\x03\x00\x00\x00\x00\x00'
    7F 66 01 00 4C 00 00 00 44 54 01 00 20 00 44 54 CB 74 14 43 AD B2 15 43 00 00 FA 44 00 94 9E 41 88 6D 08 00 88 6D 08 00 00 00 00 00 1A AB C3 40 45 A5 70 42 54 60 99 45 CF C4 03 00 00 00 00 00 (64 bytes)
    

    So what you are seeing is the expected result and you already have the data you need. Note that the second print above uses the code MinimalModbus uses to output the "Response from instrument"; see here and here.