Sign in to follow this  
mse3000

Timeout Errors

Recommended Posts

Usually when the system can poll devices individually, but not in a chain, the issue is the timing between devices. It seems that many devices don't release their 485 transceiver as fast as one would like, sometimes taking as much as 100ms to do so. Because this is actually somewhat common, there is a function in DAQFactory to introduce an automatic delay after any query:

device.mydevice.setDelay(100)

where 100 in this case means 100 milliseconds. So...:

1) make sure all your channels having the same timing / offset. Set timeout to something like 1000.

2) in a sequence marked auto-start, call the function above with a nice large number like 100. Note that with 26 devices, even with one call each device, its going to take a minimum of 2.6 seconds (100ms * 26), so make sure the Timing of your channels is something large like 10.

3) this should probably work. If it doesn't increase the setDelay(). If it does, you can start lowering the setDelay() value until it stops working, then set it slightly higher. Then you can adjust your timing values.

Of course if you are polling in script, you can introduce this delay manually in the script without using the setDelay() function. Use this method if you need to tweak the system to get the maximum update rates. setDelay() applies a delay to every block call, so if you are reading non-consecutive values from a single device, the delay will be applied with each call. Using the script / manual delay method allows you to apply the delay where you want.

Share this post


Link to post
Share on other sites

Excellent! I think you have got me 90% of the way there. This has stopped all timeout errors and in the end I have finally settled for a 2 second poll with a 2ms delay and a 2500ms timeout on the device.

My only problem is now, whenever I try to set a register value in one of the inverters, I recieve the 0013 Port Locked error. Whilst tuning the polling rate and delay function for the device I have tried at each step of the way to set a register value but without success. Any clues as to what is now causing this problem? I have tried setting the device timeout quite large, up to 10seconds in one case but still port locked.

As a side note, could you also please explain how DAQ Factory takes vales from 4-20mA devices. I see the registers trend between -65535 and +65535. Why is this and is there a standard conversion I should be applying?

Many thanks again!

Regards,

Mark

Share this post


Link to post
Share on other sites

OK further to my last reply, I have been playing with the system all day, the balance between polling interval, device delay and timeout seems almost impossible to achieve. While I can now get the system stable, reading from all registers etc, including setting registers manually as required without any errors. As soon as a periodic setting is applied from any script, the balance is upset and I am faced with timeout and port locked errors again.

I have currently settled on a polling time of 5 seconds, a device delay of 10ms and a timeout of 2500ms. From the comms monitor the time to query and recieve from all devices is about 2.2 seconds. Am I right in thinking the sum of the timeout time and the time to query all devices need to be less than the poll time? If so, once introducing a "set to register" every 5 seconds, am i then overloading the system?

I have tried setting the timeout as high as 3000ms but still with timeout errors.

Is there a procedure to try and eliminate these errors because I am just finding it so difficult to balance these timing functions.

Regards,

Mark

Share this post


Link to post
Share on other sites

Changing the Timeout value does little to help with port locked errors. What you are seeing happens because polling all the channels takes a huge block of time. If even one read time's out, you are really going to be out of balance.

So, a couple things:

1) consider getting a second serial port and splitting the devices so half are on one, and half on the other. This will double the speed DAQFactory can poll because it can poll both ports at the same time

2) consider using script instead of channels, this will give you finer control over the timing

3) Although I normally recommend putting all channels going to the same serial port on the same Timing / Offset, if you have too many channels, you get big blocks of polling with no breaks for output. In this case, once you have figured out how long it actually takes to poll the devices, you can split the channels into 2, even 4 groups. So, for example, you are going to use a polling time of 5 seconds, and it takes about 2.2 seconds to poll everything, so you have the space, but its all at the end of the 2.2 seconds. So, instead of making everything Timing 5, Offset 0, put half your devices (assuming even channel distribution) at Timing 5, Offset 0, and half at Timing 5, Offset 2.5. Better yet, split it into 4's and do: 5/0, 5/1.25, 5/2.5 and 5/3.75.

4) Set your timing back to 1000. Time out really should longer than your biggest polling block, but not huge. Huge timeouts will throw the system if a timeout actually occurs, because the port will stay locked during the entire timeout interval.

Share this post


Link to post
Share on other sites

BTW: you asked about procedure and you did the first half already, namely figuring out how long it actually takes to poll everything, and what sort of setdelay() value you need. You have characterized the system. Now you can optimize for speed and to get outputs working.

As for your other question: DAQFactory knows nothing about what sensor is attached to your device when using Modbus. You'll have to convert from the raw Modbus values to your engineering values. I'd just skip the 4-20mA stage and convert all the way to your final units. The Modbus range will never be -65535 to +65535. It'll either be -32767 to +32767 (S16) or 0-65535 (U16), or something much larger for the 32 and float types. How this converts depends on the device you are communicating with. Use a Conversion once you figure it out.

Share this post


Link to post
Share on other sites

Support, regarding your comment in 1) above. When polling using scripting and two ports can you actually poll two channels at the same time? I thought the script was sequential and one read/write command wouldn

Share this post


Link to post
Share on other sites

Yes, and yes. If you have a single script, it executes commands sequentially. Same if you have channels with the same Timing / Offset. However, if you have a second script polling the other port, or you put all your channels for the second port on a different Timing/Offset combination, then the polling will occur simultaneously.

Share this post


Link to post
Share on other sites

Hello,

sorry for my bad english, I trie to explain my problem:

I have application (rev 5.79A build 1574) running in one plant OK since 2 years.

1 month ago, problems began reading some device in modbus. I have discarded hardware problem.

I have some device slow then I use "device.namedevice.SetDelay(3)" good from begining

But after meticulous debug I have seen that, randomly, DF not wait the 3ms set in "setdelay"

i.e. with ofsset 300 I read 3 device 0f,10 and 11 (hex) , well, you will can see that between first read "Rx (01:54:35.326):" and second write "Tx (01:54:35.326)" DF doesn't wait 3ms

Share this post


Link to post
Share on other sites

Yes.

When I change the time in setdelay,the time between Rx and Tx consecutive changes near the time I set in setdelay (I cannot increment to large times because the port will be locked).

I understand that the time between Rx,Tx was bigger than "time-setdelay", but not lower.

I.e. setting 5, 6ms , the problem persist. randomly, Df not wait time(setdelay)

Thanks in advance

Jose R. Blanco

Share this post


Link to post
Share on other sites

The way the code is currently written, it does a regular Windows Sleep() call (unlike delay() in DAQFactory which will actually always pause for at least the specified amount). The windows sleep() function will return early if it has nothing better to do, and very often when the value is less than 20 (its normal slice time) it will return immediately.

Are you doing all this from script or channel Timing?

Share this post


Link to post
Share on other sites

I have "channel timing" for read my devices (because I use device.namedev.setdelay()) , and another scripts to controll the plant

With your answer I understand what happens, if the other scripts are running hard, no problem, but if not, then the channel timing read not work properly.

to workaround this, I think that I could put one "delay(0.003)

Share this post


Link to post
Share on other sites

Actually, adding delay(0.003) probably would work, but you only want to put it into one channel per block. So if you are reading tags 3, 4 and 5 with the same I/O type on the same device, DAQFactory will use a single query. If you put delay(0.003) in the event for all three channels, you'll end up with a 0.009 second delay, so just add it to one of the channels. It doesn't matter which.

Yes, we'll look to adding that to the next version. If you could please post it in the feature request forum, others might add to it.

Share this post


Link to post
Share on other sites

I have justed test to put delay in the prior channel to the slow device (offset 00).

Tx (00:57:11.000): \x10\x03\x01\xCA\x00\x01\xA6\x89

Rx (00:57:11.024): \x10\x03\x02\x02\x60\x45\x0F -> event: "delay(0.003)" does not work...

Tx (00:57:11.025): \x11\x03\x01\xCA\x00\x01\xA7\x58

Tx (00:57:11.072): \x28\x03\x21\x9B\x00\x02\xB8\x21

The problem persist, I think that the event channel does not stop the reading of the next channels until the script's event end

Correct read:

Tx (01:08:49.000): \x10\x03\x01\xCA\x00\x01\xA6\x89

Rx (01:08:49.023): \x10\x03\x02\x02\x60\x45\x0F

Tx (01:08:49.026): \x11\x03\x01\xCA\x00\x01\xA7\x58

Rx (01:08:49.050): \x11\x03\x02\x02\x60\x78\xCF

I have test that my device need at least 3ms from last tx to respond one request (but I cannot put 20ms because I have too much devices and I need the slot's time for the other devices

Please could you help me to solve it?

Thanks in advance

Share this post


Link to post
Share on other sites

Thank you very much . All goes fine with this library.

Please, let me tell 2 issues about:

-The units in device.name.setdelay() are now in seconds (I put device.modbus1.setdelay(0.003) )

-I have 2 serial ports "modbus1" (19200 b/s) , "modbus2"(115200 b/s),

If i apply device.modbu1.setdelay(0.003) also affects to "modbus2" (it is not posible set independent delays)

Thanks again, your support is excellent.

Kind regards

Jose R. Blanco

Share this post


Link to post
Share on other sites

Thanks for pointing that out. It should be milliseconds to be consistent with older versions, so we've changed that. Use the attached file instead.

As for the different devices, yes, it is currently global across the protocol. You can trick it into thinking they are different protocols by:

1) copying the dll to another name (say pModbusRTU2.dll)

2) copying the corresponding .dds file to the same thing, say pModbusRTU2.dds

3) opening the .dds file in notepad and changing the first line from:

P,ModbusRTU,PModbusRTU.dll

to, say:

P,ModbusRTU2,PModbusRTU2.dll

Restart DAQFactory and you'll now see 2 RTU protocols, and you can assign one to each device. Each will then have its own delay.

Share this post


Link to post
Share on other sites

Hello,

I use DaqFactory to connect to Regard Gas Monitoring system that monitor hazardeous gases and emulate modbus multi-drop connection to several racks.

I faced similar issues that resulted in timeout and lack of data during the apparent retry time.

After long tests, isolating with opto-isolators the network, grounding recheck, cables replacement - I went nowhere.

I decided to do a check with another brand HMI for the purpose to trace and

evaluate if it is a modbus driver related issue. The same errors resulted with the other HMI.

What I did that eventually solved the problem is setting the poll time to less then a second and the retry to very short time of few msec. Like magic - all errors disapeared. The reason in my case is that quick retry

after error resulted in the smooth flow of data. Probably the fast poll time allowed those retries to make the errors undetected.

I also tried for long period of time to go with the apparent logic that time out require longer scan times, but

the solution was shorting the timeout and poll time.

Maybe that will have your issue solved.

Share this post


Link to post
Share on other sites

Do you mean the SetDelay()? That's just a single line of script that you can put in a sequence marked Auto Start. For example:

device.myDevice.setDelay(30)

Note that this will apply across all devices using the protocol (though ModbusTCP and ModbusRTU are separate protocols) unless you use the duplication of protocols described above as well. The delay applies until you change it or restart DAQFactory.

Share this post


Link to post
Share on other sites

Hello, 

 

I am upgrading from 5.79a (with "the PModbusRTU.dll", atached in MB.zip in  this topic ) to 5.87-a.

 

Since 3 years ago without problems, the read channels are  fine.

 

Now upgrading to 5.87-a the read channels not work good. (I have  timeout errors),  

 

I find that the units of setdelay now are "ms" instead "seconds". ( i use "ms" now)

 

But I think that  in the  "PModbusRTU.dll 5.87-a",  are not the code modified about this.

 

I have  tried to replace  with  PModbusRTU.dll-atached in MB.zip , and the channels read ok.  

 

But I am not sure that I am doing correct, because  perhaps with old dll, some functions are not available or could be different sintaxis.

 

Please, could you help me?

 

I have Another cuestion, 

 

I have two DF running in diferents pc, connected by system.connect (since 3 years all goes fine), now I have   gotten  this error aleatory:

 

"Crypt error:Unable to acquire Crypt context, 8009000F" ¿? The connect was already made, but minutes later this error appears...

 

Thank you very much in advance.

Share this post


Link to post
Share on other sites

There was no attachment?

 

There were certainly some minor code changes between 5.79 and 5.87.  If your system was close to the limits with the timing, it is entirely possible that these code changes pushed it over the edge and caused your errors, though I'm surprised they are timeout errors.  Really I need to see your application to address it.

 

As for your second question, the crypt context is used for encrypting traffic between two copies of DAQFactory.  To comply with US export regulations, we do not do the encryption ourselves, but rather let the customer's Window's OS do the encryption.  For some reason on your system it could not encrypt the traffic, probably because your version of Windows doesn't support it.  If everything works, you can probably ignore the error.  Otherwise, simply rename sockete.dll to something else on both sides to disable encryption.

Share this post


Link to post
Share on other sites

Thanks for your  answer.

 

About second question,  I rename the dll in both pc's, and all goes fine (I do not need encryption).

 

About the first, I debug the comm port  monitor and  I think the library PModbusRTU.dll in 5.87a, not executes setdelay correctly, is identical to explained  in this post on  3 january 2011 .

 

I workaround it, using the dll attached in that post.

 

if possible, I think is important fix this, and then "setdelay" works exactly

 

Now I will upgrade to 5.90 and I don't know if in the new version this is ok.

 

Regards,

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this