1
votes

I am trying to interface with a temperature controller using Modbus RTU. I am not very familar with the topic, but I have been able to write code that can read the temperature of my three temperature controllers, but when I try to write to the three temperature controllers in sequence I get an error. The code I have been running is :

import minimalmodbus
import time
import serial
from datetime import datetime

minimalmodbus.BAUDRATE= 9600
minimalmodbus.PARITY = serial.PARITY_EVEN
Left = minimalmodbus.Instrument('COM3', 1,)
Middle = minimalmodbus.Instrument('COM3', 2) 
Right = minimalmodbus.Instrument('COM3', 3)  

print(Left.read_register(4096, 1))
print(Middle.read_register(4096, 1))
print(Right.read_register(4096, 1))

newTemp = 65
Ltemp = newTemp
Left.write_register(4097, Ltemp, 1)
time.sleep(.04)
Mtemp = newTemp
Middle.write_register(4097, Mtemp, 1)
time.sleep(.04)
Rtemp = newTemp
Right.write_register(4097, Rtemp, 1)

Again when I print the current tempearture the code does not give an error, and if I write to only one of the registers at a time (comment out the others and run them) it changes the setpoint temperature and does not throw an error.

More interestingly to me, when I do run this code, the first time I run it the setpoint of the "Left" temperature controller is changed and then an error is thrown. The next time I run the code the setpoint of the "Middle" temperature controller is changed and then an error is thrown. The last time I run the code the set point of the right temperature controller is changed with no error thown.

I tend to get different errors and I cannot really disern a pattern. They include:

Checksum error in rtu mode: '\x10\x01' instead of '\x01ì' . The response 
is: '\x01\x10\x10\x01' (plain response: '\x01\x10\x10\x01')

builtins.ValueError: Too short Modbus RTU response (minimum length 4 
bytes). Response: '\x02'

builtins.OSError: No communication with the instrument (no answer)

I have tried changing the baud rate to 4800, nothing worked when I did this. I also got similar errors changing from Modbus RTU to ascii. I was also getting the same erros when the parity was set at the defualt none. I also tried to sleep the code and change the timeout, which I think helped with the last error.

Any suggestions of what to try to stop getting these errors would be much appreciated.

Thank you

Edit

I tried deleting the number of decimals but still get the same error, the set point now updates so that 80 turns into 8.0, not that that's a big deal.

this is the full response I get when I run the code, now without the number of decimals:

19.1
19.1
21.1
Traceback (most recent call last):
  File "C:/Users/matth/Desktop/tempController.py", line 26, in <module>
    Left.write_register(4097, Ltemp)
  File "c:\Users\matth\AppData\Local\Programs\Python\Python36-32\Lib\site-packages\minimalmodbus.py", line 296, in write_register
    self._genericCommand(functioncode, registeraddress, value, numberOfDecimals, signed=signed)
  File "c:\Users\matth\AppData\Local\Programs\Python\Python36-32\Lib\site-packages\minimalmodbus.py", line 697, in _genericCommand
    payloadFromSlave = self._performCommand(functioncode, payloadToSlave)
  File "c:\Users\matth\AppData\Local\Programs\Python\Python36-32\Lib\site-packages\minimalmodbus.py", line 798, in _performCommand
    payloadFromSlave = _extractPayload(response, self.address, self.mode, functioncode)
  File "c:\Users\matth\AppData\Local\Programs\Python\Python36-32\Lib\site-packages\minimalmodbus.py", line 1032, in _extractPayload
    response))
builtins.ValueError: Too short Modbus RTU response (minimum length 4 bytes). Response: '\x01'

Left's temperature does change though. I still also get the instrument timeout occasionally error, but the error above seems to be the most common one. I think I will check how I wired the interface though, as I am wondering if that is the issue.

Edit II

I think I figured it out, I just had to increase the timeout time (I thought I already had but I guess not enough) minimalmodbus.TIMEOUT = 3 seems to make everything work.

Thanks for the help!

1
So what is the output of print()? After you read the values - grapes

1 Answers

1
votes

If you are doing read before write, and read succeeds, then you definately have chosen right speed and parity and don't have to change it.

Without seeing the log of exchange, it would be difficult to guess, but I am 99% sure, the problem is numberOfDecimals parameter of write_register. It is not the number of registers, as you probably expect, it is a way to round floating number to integer.

So, change to

Left.write_register(4097, Ltemp)
Middle.write_register(4097, Mtemp)
Right.write_register(4097, Rtemp)