Project with more than 4250 variables


apmm80

Recommended Posts

Hello Good morning.

I use DAQFactory usually for 6 years.

Now, I am working on a project with more than 4250 variables.

I worry that with so many varibles the program to crash. These variables are divided into 50 MODBUS TCP devices (36 reading variables and 25 writing variables on each device) The remainder are internal DAQFactory varibles.

I need to communicate with each device every 20-30 seconds to read the 36 reading variables and each time you change any of the writing variables. I have had Timeout and Port Locked experiences when I have many variables. I had thought to put several Ethernet ports, separate networks and improve the data flow in order to make it faster. (I know that in the case of serial ports can be improved as well, but the TCP port I don´t known, the IP range would be different for each network but the port 502, Is the same? or Are there diferents 502 ports, one for each computer local networks)

Can you advise me?

Thank you very much.

Best Regards

Link to comment
Share on other sites

DAQFactory can actually handle this ok, you just aren't going to be able to use Channels. Trying to organize 4250 channels would be challenging. I was actually just about to start a little tutorial series on doing larger, scalable applications. Look for it in the next day or two. I'll probably create a new forum area called "Tutorials" to put it in. In short, if all 50 devices are identical then you are definitely going to want to use a class for the device and instantiate it 50 times. In the class you can dynamically create the Modbus / TCP connection (there's a forum post around here somewhere on that). For speed, you'll also want to dynamically create a thread in each object that does the polling so the polling can occur simultaneously across all 50 devices. To avoid port locked errors, you'll want to do your output from the same thread by utilizing variables to tell the thread when a value needs to be changed.

As for the port 502 question, its port 502 on the destination side. The client (DAQFactory) side will actually be a random port #. Download wireshark and you can see how it works.

You can kind of think of TCP comms as a telephone system in two big organizations where there is a single phone number and lots of extensions. If person A in organization 1 wants to call person B in organization 2, he picks up the phone and dials a phone # for 2 (the IP address), then the extension for B (the port). When he picks up the phone, his phone system gives him a random line out (the port). Where this analogy falls apart is three fold: one, person B receiving the call can, depending on his software, receive calls from multiple people at once at the same extension (i.e. no busy signals), though usually there is some limit, and person A can make calls to multiple people. Two, a person can only receive a phone call if they are setup as a server. In the example I gave, A is a client, B is a server. Three, a person can be both a client and a server at the same time, so if person A was a server as well, he could receive a call on his extension at the same time he's making calls to someone else. The received call would be on his extension (say port 502), but the originated call would be on whatever outgoing line was available.

Link to comment
Share on other sites

Hello. Thanks very much for your response.

Yes, I have 48 identical devices and 2 diferents, but I never used the class device and I dont know how to create the class and asign the Modbus TCP connection or the variables.

Can I help me.

Thank very much

Best regards

Link to comment
Share on other sites

  • 4 weeks later...

Hi; I'm working on a project like "apmm80". i've 15 device and too many registers to read via modbus. i use OOP in this project first time and it works nice just for one device. I'll try that for the orhers too. i wanna ask how many register can DF read via modbus. With "ReadHoldingRegister" command i saw that DF can handle 41 register(float). if i know i won't try too big maps for nohing.

here is my oop code for reading. it's pretty useful i think.


class analizor
local mva
local mw
local mvar
local mwh
local mwhcon
local mwhdel
local mvarhind
local mvarhcap
local ind_direction
local cap_direction
local trend_ind
local trend_cap
local mwhcon_hour
local mwhdel_hour
local mvarhind_hour
local mvarhcap_hour
local ind_rate
local cap_rate
local minus_con
local minus_del
local minus_ind
local minus_cap
endclass
class tm2 parent analizor
function readmb()
data = Device.TM2.ReadHoldingFloat(250,19026,41)
return(data)
endfunction
endclass
global tm[0] = new(tm2)
[/CODE]

note: i defined the "data" variable as global in start squence..

Link to comment
Share on other sites

Actually, the limit on the number of items DAQFactory can read is determined by the Modbus specification, not DAQFactory itself. The limit, I believe is 125 registers, which means 62 floating point values since it takes two registers per floating value.

Now, as to your classes:

1) why the parent / child? Why not just one class?

2) you don't want data to be global, but instead a private variable of the readmb() function.

3) to really take advantage of classes, you shouldn't hardcode the modbus ID into the readHoldingFloat() but instead make it a member variable of the class so you can instantiate the class multiple times for multiple ID's (devices).

Link to comment
Share on other sites

Thanks Guru;

i understood. if i answer;

1) i use parent/child structure cause i have 15 different device to get data and all of them at separate palaces so they have differant IP addresses. I created new serial/ethernet(TCP) devices for each of them. This situation needs parent/child structure as i see. cause ("Device.TM2.ReadHoldingFloat(250,19026,41)") of this function i think i should create parent function classes for each device. if there is a way which i may change the device part of that function it solves like this "Device.mydevice_variable.ReadHoldingFloat(250,19026,41)". So i wanna use really advantages of classes but don't know the paths.

2) i understood this too. i should use private variables each of sequences one for function-class and one for to get and distribute from readings. Distribute to objects. is this true?

3) i think the first one explain why i couldn't use the advantage of classes. I'll instantiate the class multiple times as you say but i've to define parent classes for each of device if you won't canalize me new wys :) thank you again.

Link to comment
Share on other sites

1) yes you can using either evaluate() or execute(). In this case, probably evaluate():

data = evaluate("Device." + mydevice_variable + ".ReadHoldingFloat(250,19026,41)")

2) correct. You are returning "data" from your function, so there is no need to make it global. Plus, it will conflict with the 15 other objects you instantiate if you make it a global.

Link to comment
Share on other sites

  • 2 weeks later...

Hi,

i've stuck in a code execution.


execute("component.mw"+DoubleToStr(x)+".strExpression = "tra["+DoubleToStr(x)+"].mw"
[/CODE]

i gave a name to my "variable value" components. And the names goes incrementaly.

so by this names i'm trying to post expressions to component via scripting. But there is something wrong i think. As you see when i start the sequence execute function assign the value of -- tra["+DoubleToStr(x)+"].mw -- variable. but as you know i need to transfer the string format of -- tra["+DoubleToStr(x)+"].mw -- this variable. what should i do?

thank you so much..

Link to comment
Share on other sites

Hi again :)

i 've an answer after 2 hours.


private string dev
dev = "tra["+DoubleToStr(x)+"].mw"
execute("component.mw"+DoubleToStr(x)+".strExpression ="+"dev" )
[/CODE]

it works like what i need.

Link to comment
Share on other sites

The problem with your first post is quotes. DAQFactory treats ' and " the same, but you have to pair them correctly. You can't do "some string'. In your example, you want to embed " in your string, so you need to enclose that section in single ' instead:

execute("component.mw" + doubleToStr(x) + '.strExpression = "tra[' + DoubletoStr(x) + '].mw"'

or use ' inside the ". Doesn't matter. The syntax coloring should show you your error.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.