Ok This was another test and this is where it gets weird. I thought, why not flip this around? I also have the modbus master simulator so I configured channel 0 to be a modbus slave
...
Now this really doesn't make sense now. Why would it not be able to read data back when requested?
Agreed, that makes no sense at all. If you read the Modbus RTU spec, there are timing issues i.e. there have to be so many character-times (3.5 or 1.5, IIRC) of delay between transmissions, and maybe that is not well-implemented on the Windows side.
But I can see your weird, and raise you a wacko:
I have been doing something similar. Here is the code of a Python script I am running:
try : serial.Serial
except: import serial
a=serial.Serial(port='COM3',baudrate=38400,parity='N',stopbits=1,timeout=4.0)
while True:
s=a.read(21) ### Read up to 21 bytes of a Modbus 16 (0x10) Write Holding Registers
L=len(s) ### Check the length of what was read
if 21!=L: print((L,s,)) ; continue ### If the length was not 21, print out the length and the bytes read and start another read
if b'\x01\x10\x00\x00\x00\x06'==s[:6]: ### If the 21 bytes were as expected ...
n=a.write(b'\x01\x10\x00\x00\x00\x06\x40\x0b') ### ... then reply with the appropriate response
What is happening there is that the MicroLogix 1100 is a Modbus Master, and the PC is listening on RS232 COM3 using the Python script above.
The 1100 is sending to Slave ID 1 (
\x01) Modbus Write Holding Registers (
\x10), starting at PDU address 0 (
\x00\x00; i.e. Modbus "Address" [4]0001* for 6 registers (
\x00\x06) messages at about 50Hz. This Python script is returning the correct response for Write Holding Registers, which response does not change because those four parameters do not change.
So while that script is far from an implementation of a Modbus Slave, the Modbus Master on the MicroLogix 1100 does not know the difference because the response is always the same.
I have been running that script for over two hours connected to the Modbus Master on the 1100, and it has been faultless: there was not a single request where the Python "Modbus Slave" script did not read exactly 21 bytes, and there was not a single case where the Modbus Master did not receive, and parse, a valid response (I have separate counters on the rising edges of the MGx:y/DN and MGx:1/ER bits).
* N.B. the [4] prefix is a convention and has nothing to do with the actual offset of the target address
So that is great, it is working as expected. Admittedly I am not checking the CRC, but I am consistently getting 21 bytes that start with that \x01\x10\x00\x00\x00\x06.
However, here is my wacko result: when I run pyModSlave on the PC listening to that same COM3, and leave the 1100 configured exactly as above, I get about
- one in ten successful request/response transaction pairs, and
- nine in ten that are
- missing one complete request byte out of the 21,
- and also typically have some flipped bits.
For those nine in ten, the CRC does not match and pyModSlave on the PC raises an error flag and does not send a response.
I dropped the baudrate from 38.4kbaud to 2400baud and got the same result.
I don't know what to make of all of this (@mikeexplorer's and my results), but I think another possible culprit is pyModSlave's and/or Windows 10's handling of the serial data. Pyinstaller did not work for me to make pyModSlave.exe, and I had to make some fixes just to get it to work under Windows 10 Python.
The attached files are
- an annotated section of the pyModSlave Bus Monitor dump,
- a screenshot of the MicroLogix code and a Bus Monitor dump from pyModSlave,
- The MicroLogix Channel 0 configuration,
- the pyModSlave Bus Monitor dump text file.