idrdot / simple-modbus

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

Illegal data address <01><83> #25

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Raspberry with master work perfect
2. Arduino Uno with simple-modbus slave library ID 1 ( problem )
3. Arduino Due with simple-modbus slave library ID 4 work perfect
4. PIC 18f4685 slave ID 2 work perfect
5. modbus rtu over rs485

What is the expected output? What do you see instead?
At the start, everything works perfectly.
After a few hours arduino one stops responding properly.
Rasperry performs the request correctly.
(Arduino-two) and (pic) answered correctly, but (Arduino-one) is not responding 
correctly.
Under the request and the response when the error occurs:
[01][03][00][00][00][27][05][D0]
Waiting for a confirmation...
<01><83><02><C0><F1>
ERROR Illegal data address

Under the request and response when all ok:
[01][03][00][00][00][27][05][D0]
Waiting for a confirmation...
<01><03><4E><00><00><00><00><00><00><00><00><00><00><00><00><00><00><00><00><00>
<00><00><00><00><00><00><2E><00><50><0C><9E><0A><FA><00><07><00><00><00><00><00>
<00><00><00><00><00><00><00><00><00><00><00><00><00><00><00><00><00><00><00><00>
<00><00><00><00><00><00><00><00><00><00><00><00><00><00><00><00><00><00><00><00>
<00><4B><F8>
This problem occurs after hours of proper operation.
To fix I reset (Arduino-Uno) and everything works fine for other hours.
It would appear that the internal register address request <03> be corrupted.

Under certain parts of code of interest Modbus on Arduino-Uno:

#include <SimpleModbusSlave.h> 
....
unsigned int holdingRegs[41]; // function 3 and 16 register array
....
    modbus_configure(&Serial, 19200, SERIAL_8N1, ID_SLAVE, TxEnablePin, 40, holdingRegs);  
...

valore = 2.35;
val_sensore = 150;
TempDHT22= 23.43;
UmiDHT22 = 6.25;
holdingRegs[11] = int(valore * 100);
holdingRegs[12] = val_sensore;  
holdingRegs[13] = int(TempDHT22 *100);
holdingRegs[14] = int(UmiDHT22 *100);
holdingRegs[15] = StatoIOSala;  

Original issue reported on code.google.com by max.bene...@gmail.com on 26 Dec 2013 at 11:05

GoogleCodeExporter commented 8 years ago
In order for the Illegal data address to be set by the slave the starting 
address must be equal or larger than the holding register array size. You have 
a constant of 40 which means the slave will occupy 40 unsigned int registers. 
From your code snippet it seems you are requesting 27 registers starting from 
address 0. This is normal and should work perfectly (as you mentioned). The 
arduino core keeps changing, they have changed the hardwareSerial core library 
ring buffer size from 128 bytes to 64 bytes which means you can only request 29 
unsigned int registers, but you are requesting only 27 which is ok. I can only 
see that the Illegal data address error code is generated because of a buffer 
overrun and/or garbled data in the frame buffer array. As mentioned the 
starting address has to be equal or larger for the error code 2 to be set. This 
means the third and/or fourth byte of the frame contains erroneous data bigger 
or equal to 40.

Just to verify:
Does your slave go offline permanently?
What is the retry value of your master?
How does your RS485 driver circuit look like? Pull ups, pull downs, Rx tied 
high.

Send me your slave example sketch..

Original comment by bester.j...@gmail.com on 8 Jan 2014 at 7:30

GoogleCodeExporter commented 8 years ago
The request is 27 in HEX which then corresponds to 39 DEC think could be the 
problem now if the buffersize is 64 corresponding to 29 unsigned int.
I use Arduino IDE 1.0.5 is confident that the buffersize is 64? Can I verify 
this ?
Answering questions:
1 Yes the slave go off permanently until I perform a soft reset. Answers always 
<01>       <83> ...
2 The return value is always <01> <83>
3 I have the pull ups and pull dows rx is pulled up

Original comment by max.bene...@gmail.com on 8 Jan 2014 at 8:52

GoogleCodeExporter commented 8 years ago
There will definitely be a buffer overrun in the HardwareSerial core library. 
They changed the core lib in version 1.05. This is easy to change by altering 
the define constant 64 to "SERIAL_BUFFER_SIZE 128" on line 59 in the 
HardwareSerial.cpp file. Located at  C:\Documents and Settings\USER\My 
Documents\arduino-1.0.5\hardware\arduino\cores\arduino\HardwareSerial.cpp

Original comment by bester.j...@gmail.com on 10 Jan 2014 at 7:49

GoogleCodeExporter commented 8 years ago
Ok Thanks.

Original comment by max.bene...@gmail.com on 10 Jan 2014 at 10:47