idrdot / simple-modbus

Automatically exported from code.google.com/p/simple-modbus
0 stars 0 forks source link

Modbus Master - Failed requests #10

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
Arduino Master -> 1 PC slave
Reading 22 Registers (PACKET 1 - READ_HOLDING_REGISTERS)
Writing 23 Registers (PACKET 2 - PRESET_MULTIPLE_REGISTERS)
Same array.
WORKING.

Arduino Master -> 2 devices slaves (NOT PC)
Reading 2 Registers (PACKET 3 - READ_HOLDING_REGISTERS)
Writing 2 Registers (PACKET 4 - PRESET_MULTIPLE_REGISTERS)
Reading 2 Registers (PACKET 5 - READ_HOLDING_REGISTERS)
Writing 2 Registers (PACKET 6 - PRESET_MULTIPLE_REGISTERS)
4 arrays.
WORKING.

Arduino Master -> 3 devices slaves (1 PC, 2 devices) / or 2 devices slaves (1 
PC, 1 device)
As above.
NOT WORKING.

At the first run all the packets all successfully transmitted. Then PACKET 1 
starts the failed requests. All the other PACKETS are successful.

baud 19200
timeout 500
polling 250

Using:
SimpleModbusMasterV7.zip // WIN7 64-bit // PC as slave using LabView 2011 and 
NI MODBUS Library for LabVIEW (nimodbus121.zip)

Original issue reported on code.google.com by toli...@gmail.com on 15 May 2013 at 10:23

GoogleCodeExporter commented 8 years ago
It seems you are using RS485, are you using 120ohm termination resistors and 
680ohm pull up and pull down resistors? What converter are you using for the pc 
interface. Does it also contain pull up and pull down resistor or the 
termination resistor. If so you must not use pull up and pull downs on master 
side only termination resistor. Also try to increase timeout to 1000ms. PC 
simulated slaves are tricky things because exact character timing can not be 
achieved. Are you using arduino V1.04?

Send me your sketch...

Original comment by bester.j...@gmail.com on 16 May 2013 at 8:50

GoogleCodeExporter commented 8 years ago
On the PC there is a PCI RS232 card. I'm converting the RS232 to RS485 using 
the 485SD9RJ. I have used this converter before on a PLC (as a master) with ten 
arduino slaves, successfully (using the SimpleModbusSlave library). In my 
configuration, a custom shield is attached to an Arduino MEGA2560. There is an 
LTC485 chip for the MODBUS communication.
I'm using 390ohm termination resistor on the master side. I do not have pull 
up/down resistors but I managed to stick two 680ohm resistors on the LTC485 
chip. There was no difference. I increased the timeout to 1000ms. Some times 
adding a delay at the end of the program and increasing the scan rate seems to 
work. But it is random and not permanent.
I have to mention also that the slave devices have EVEN parity, and this 
setting is not configurable. So I'm forced to use EVEN parity. I manage to 
communicate with the device using the following settings:
First I use Serial3 on Arduino MEGA2560, so I changed the Serial port to 
Serial3.
Then at the end of the Setup() on my program I added the following:

  //clear parity, stop bits, word length
  UCSR3C = UCSR3C & B11000001;
  UCSR3B = UCSR3B & B11111011; 

  UCSR3C = UCSR3C | B00100000;  // Parity EVEN
  UCSR3C = UCSR3C | B00000110;  // Word length 8 
  UCSR3C = UCSR3C | B00000100;  // Stop Bit 1

With these settings, I'm able to communicate with the devices which have EVEN 
parity without errors. (Well, if this is right then you can add it as a feature 
at your library)
I'm using using arduino V1.04 and the library version is 6,  not 7 as mentioned 
in my first post.
I'm attaching the sketch and the modified libraries (Serial. to Serial3.)

Original comment by toli...@gmail.com on 16 May 2013 at 9:46

Attachments:

GoogleCodeExporter commented 8 years ago
The 485SD9RJ does have 4.7K pull up and pull down resistors. It does not
have a termination resistor. The master must have a 120ohm termination
resistor not 390ohm. This will cause reflection on the communication lines.
Use the PC (485SD9RJ converter) as the end of line unit with a 120ohm
resistor on its terminals. As the converter does have pull up and pull down
resistors it should not be necessary for the 680ohm (you might have to use
it though). All other slaves must not have any resistors on the A and B
lines.

In your sketch you commented that you are not using the TxRxEnable pin, how
are you toggling the RE and DE pins on the LTC485 then?

Using V7 clears up code cause you don't have to explicitly use pointers to
setup packets.

Original comment by bester.j...@gmail.com on 16 May 2013 at 10:58

GoogleCodeExporter commented 8 years ago
I replaced the 390 Ohm resistor on the master with 120 Ohm and placed
another one at the PC terminals.
The situation is the same. The first 2 packet are successful and then fails
occur, only at packets 1&2 (PC). I got some random successfully transmitted
packets to/from the PC from time to time...
The TX3 is handling both the RE and DE pins on the LTC485 (
https://docs.google.com/file/d/0B57pZiPtc2kQM21hU0RDaW1VZXc/edit?usp=sharing
).

Original comment by toli...@gmail.com on 16 May 2013 at 2:50

GoogleCodeExporter commented 8 years ago
This is very strange. My guess is some where there is character(s) being
lost. This might be due to how you toggle the RE and DE enable pins. There
must be some delay after the last character is transmitted to allow the
data to reach its destination. Using your circuit does not allow for any
delay, as soon as the master stops transmitting the driver is disabled. The
library was tested using an extra pin to toggle the RE & DE pins.

Before version 5 I used a delay of 3ms before I switched off the MAX485
driver. This worked when no pull up and pull down was used, but I found
that some slaves did not like this so I removed the delay but then I had to
use pull up and pull down resistors otherwise the communication lines were
floating and random errors would occur. You can insert the delay again and
see if this will help but you will have to use another pin to toggle RE &
DE. Insert the delay(1) after Serial.flush() in the sendPacket() function.

It is still strange why the PC worked at point to point communication and
not now. I know PC serial ports does not have tight control over the
character timeout especially if you are using usb to rs232 converters. I
have struggled allot with this when I created the ModbusMaster library for
Processing. It is still temperamental because I cant get rid of the inter
character timeout between character transmissions.

Original comment by bester.j...@gmail.com on 16 May 2013 at 3:24

GoogleCodeExporter commented 8 years ago
One more thing. You mentioned you use SimpleModbusSlave with the converter and 
PLC as master. The arduino serial library does not allow accurate inter 
character timing. This is a limitation in the hardware serial library. This 
means true character timing cannot be implemented with SimpleModbusSlave 
(actually this is true for most modbus libraries which does not use a timer 
interrupt to check this). As a result of this SimpleModbusSlave is much more 
relax on this standard. This is only true when receiving. Transmitting of 
characters is sequential without any delay from the hardware both for 
SimpleModbusSlave and SimpleModbusMaster.

Original comment by bester.j...@gmail.com on 16 May 2013 at 3:34

GoogleCodeExporter commented 8 years ago
One more thing ;)

Try a baud rate of 9600.

Original comment by bester.j...@gmail.com on 16 May 2013 at 3:36

GoogleCodeExporter commented 8 years ago
Any success?

Original comment by bester.j...@gmail.com on 21 May 2013 at 8:20

GoogleCodeExporter commented 8 years ago
I was just about to reply! :)
I cut the trace to DE/RE pins and tied them to pin 25. Now it is software 
driven.
I tried adding the delay you mentioned above at the sendPacket() function, but 
I didn't see any change.
But baud rate of 9600 seems to stand better than 19200.
While at 19200 the communicate with the PC AND the other 2 devices is very rare 
(the PC is not responding to requests), at 9600 there is significant 
improvement. The communication is not seamlessly though, I get timeouts from 
the PC slave from time to time.

@ 9600
======

Right now I'm probing the circuit with an oscilloscope.
There was something strange. While the communication is working fine, I found 
out that when I tried to scope the RX3 pin, I started to get timeout errors at 
the PC side. I tied a 10K from RX3 @ 5V. This solved the problem.

LAST UPDATE (while writing this post)
-------------------------------------

As I mentioned above, I use Labview to create a modbus slave at the PC.
I'm setting the Serial port timeout in Labview at 100 ms, same as the 
turnaround delay of the other two salve devices.

The timeout at the master side is set at 125ms.
The scan rate is set at 100 ms.

The communication seems to be perfect. I can see that at the oscilloscope 
screen, too.
Right now I have removed all the termination resistors and the bias.

I'll consider the situation SOLVED! (for the time being...!)

Summarizing:
The arduino master has been set at 9600 bps, 125 ms timeout, 100 ms polling.
The PC serial port timeout has been set to 100 ms through Labview, the same 
timeout as the other 2 slave devices. Arduino master has been set up for even 
parity.
A 10k resistor between RX3 and 5V(??).

Thank you very much for the support! Keep up!

P.S I'm leaving a wish list below :)

I would really like to see at future versions of your libraries the following 
features:
1) the ability to choose any UART you want
2) support for 8EN setup

Original comment by toli...@gmail.com on 21 May 2013 at 11:08

GoogleCodeExporter commented 8 years ago
It seems this strange behavior is linked to the RX3 pin. How did the pulse look 
on the the RX3 pin? The lower baud rate and pull up resistor might be pointing 
to the same thing?

Do you have a schematic of your custom RS485 shield?

Original comment by bester.j...@gmail.com on 21 May 2013 at 11:38

GoogleCodeExporter commented 8 years ago
I'm posting some photos from the oscilloscope.
The yellow line is the TXenable/disable pin (driven by the library).
The blue line is the TX3 pin, the master request.
The pink line is the RX3 pin, the slave answer.
In the attached images you can see the transmitted and received packets.
In the "with resistor 500ms.jpg" you can identify the 6 packets. The first 
yellow rising edge indicates the start of transmission of the first packet.
As you can see in the "with resistor 200ms.jpg" and "with resistor 500ms.jpg" 
images, the sequence is as expected: While the master TX/~RX is enabled (yellow 
line), the master transmits the data (blue line) and there is no activity at 
the RX3 pin (pink line).
In the "without resistor 200ms.jpg" you can see that there is activity at the 
RX3 pin while the master is transmitting.
Notice that this is happening only when I try to monitor the RX pin and the 1k 
pullup resistor is absent. I've noticed it because I started to get failed 
requests when I touched the RX3 pin with oscilloscope probe. 
About the RS485 schematics, check comment #4.

Original comment by toli...@gmail.com on 26 May 2013 at 11:10

Attachments:

GoogleCodeExporter commented 8 years ago
I have a suspicion that the RO pin from the driver goes into high impedance 
state when RE is high, this was confirmed from the LTC485 and the MAX485 
datasheet. This would mean that theoretically the RX3 pin (which is interrupt 
base) could pickup a stray signal (noise) since the pin is not referenced to a 
specific logic level. I must say I did not expect this and have never 
experienced this with the MAX485/487 family. By tying the interrupt pin high 
with a 4.7k or 10k will solve this since the pin is referenced at a known logic 
level. Why it only affects the first two packets of the PC is still a mystery 
to me..

Original comment by bester.j...@gmail.com on 27 May 2013 at 6:27

GoogleCodeExporter commented 8 years ago
By the way, I have tested the auto switching circuit(in comment #4)of the RS485 
and it works flawlessly at any baud rate.

Original comment by bester.j...@gmail.com on 3 Jun 2013 at 7:19

GoogleCodeExporter commented 8 years ago
I'm glad to hear that. :)
 On Jun 3, 2013 10:20 PM, <simple-modbus@googlecode.com> wrote:

Original comment by toli...@gmail.com on 3 Jun 2013 at 7:24