maximum no of channels


Recommended Posts


Can you let me know the maximum no of channels can be handled by Daqfactory in modbus RTU or TCP if it read once per second in parallel? Because in my system when the no of channels are increasing the data receives very slowly. Sometimes once a 10 seconds. Sometimes still lower. Right now it gets around 70 channels. I meant tags. 

I'm going to add some more channels with modbus TCP and it will be around 300. So please let me know how to do this to get exact ones per second in each channel. 




Link to comment
Share on other sites

That actually depends on your remote device and what it's turn-around time is.  You should, however, be able to increase the speed by connecting to different TCP devices on different threads so that DAQFactory can communicate with them in parallel.  If using Channels the best way to achieve that is to give them different Timing or Offset parameters.  So one device might be Timing 1, Offset 0, while another might be at Timing 1, Offset 0.1.  They both get read once a second, but in parallel.

To figure out your remote device turnaround, use the comm monitor with the time of Tx/Rx display enabled.

Note also that you can get better through-put if you make your tags concurrent.  In other words, instead of reading registers 1, 3, 7 and 10, try and pack those registers inside the PLC, so 1,2,3 and 4.  If you can't pack them, consider reading the in between values in junk channels that you don't use.   DAQFactory can read 1, 3, 7, and 10 in either 4 separate queries, if you only specify those channels, or as 1 query if you specify all the registers between 1 and 10 with the same timing and offset.

Link to comment
Share on other sites


It changed the speed in good scale in Modbus protocol. Still i need to get your guidance to speedup the CANbus connection speed in my Daqfactory. In fact those are on ready by the program and so i don't know the delay comes from where. A sequence used to read the messages is as below. 


while (1)
   private string strIn1 =
   private string in1 = asca(strIn1)
   strIn1 =[1])
   in1 = asca(strIn1)
   ID1.Addvalue(in1 [4])
   If ((ID1 (0) > 87) && (ID1 (0) < 89))
      CCP100.Addvalue(in1 [9])
      CCP101.Addvalue(in1 [10])
      CCP102.Addvalue(in1 [11])
      CCP103.Addvalue(in1 [12])
      CCP104.Addvalue(in1 [13])
      CCP105.Addvalue(in1 [14])
      CCP106.Addvalue(in1 [15])
      CCP107.Addvalue(in1 [16])
      If ((ID1 (0) > 23) && (ID1 (0) < 25))
         IP150.Addvalue(in1 [9])
         IP151.Addvalue(in1 [10])
         IP152.Addvalue(in1 [11])
         IP153.Addvalue(in1 [12])
         IP154.Addvalue(in1 [13])
         IP155.Addvalue(in1 [14])
         IP156.Addvalue(in1 [15])
         IP157.Addvalue(in1 [16])
         If ((ID1 (0) > 31) && (ID1 (0) < 33))
            IP200.Addvalue(in1 [9])
            IP201.Addvalue(in1 [10])
            IP202.Addvalue(in1 [11])
            IP203.Addvalue(in1 [12])
            IP204.Addvalue(in1 [13])
            IP205.Addvalue(in1 [14])
            IP206.Addvalue(in1 [15])
            IP207.Addvalue(in1 [16])
            If ((ID1 (0) > 55) && (ID1 (0) < 57))
               CCP250.Addvalue(in1 [9])
               CCP251.Addvalue(in1 [10])
               CCP252.Addvalue(in1 [11])
               CCP253.Addvalue(in1 [12])
               CCP254.Addvalue(in1 [13])
               CCP255.Addvalue(in1 [14])
               CCP256.Addvalue(in1 [15])
               CCP257.Addvalue(in1 [16])
               If ((ID1 (0) > 103) && (ID1 (0) < 105))
                  IP300.Addvalue(in1 [9])
                  IP301.Addvalue(in1 [10])
                  IP302.Addvalue(in1 [11])
                  IP303.Addvalue(in1 [12])
                  IP304.Addvalue(in1 [13])
                  IP305.Addvalue(in1 [14])
                  IP306.Addvalue(in1 [15])
                  IP307.Addvalue(in1 [16])
                  If ((ID1 (0) > 119) && (ID1 (0) < 121))
                     IP350.Addvalue(in1 [9])
                     IP351.Addvalue(in1 [10])
                     IP352.Addvalue(in1 [11])
                     IP353.Addvalue(in1 [12])
                     IP354.Addvalue(in1 [13])
                     IP355.Addvalue(in1 [14])
                     IP356.Addvalue(in1 [15])
                     IP357.Addvalue(in1 [16])
                     If ((ID1 (0) > 151) && (ID1 (0) < 153))
                        CCP450.Addvalue(in1 [9])
                        CCP451.Addvalue(in1 [10])
                        CCP452.Addvalue(in1 [11])
                        CCP453.Addvalue(in1 [12])
                        CCP454.Addvalue(in1 [13])
                        CCP455.Addvalue(in1 [14])
                        CCP456.Addvalue(in1 [15])
                        CCP457.Addvalue(in1 [16])
                        If ((ID1 (0) > 71) && (ID1 (0) < 73))
                           CCP280.Addvalue(in1 [9])
                           CCP281.Addvalue(in1 [10])
                           CCP282.Addvalue(in1 [11])
                           CCP283.Addvalue(in1 [12])
   delay (0.2)


Best regards,


Link to comment
Share on other sites

You probably don't need the delay(0.2).  Just add a try/catch around everything and put delay(0.1) inside the catch(), then let the read() handle the delay.  Right now, if the data comes faster than 0.2 seconds, you'll get backlogged because you are only reading from the buffer every 0.2 seconds.


Link to comment
Share on other sites

  • 2 weeks later...

First, I'd use a switch/case() in lieu of the many nested ifs.

But I can't figure out what's going on here.  You're doing an asca() on values from your buffer, which implies they're ASCII and you want integer numeric codes instead.  But then you assign the result to a string variable (and then use it in a numeric comparison), so I'm confused.

Is the data coming in as string-encoded  numeric data and you want actual numbers in the channels?  If that's the case, you probably want chra() rather than asca().  Or are you actually pushing ASCII character codes into channels?  If so, what's the application?  Does this all work as expected other than wanting to optimize speed?

Can you give us background on what the encoding is for the incoming stream and what you're doing with the information?

Link to comment
Share on other sites

Assuming the repetitive part under the while() is correct, I'd create a function to do that

function PackChannels(string UnitName, ChanPoint, FloatPoint, count)
    for(private idx = 0, idx < Count, idx++)
        execute(UnitName + format("%03.0f", ChanPoint + idx) + ".Addvalue(in1[" + \
            (FloatPoint + idx)) + "])")

That would reduce that portion of the while() to

    private UnitID = floor(in1[4] + 0.5)
        case(UnitID == 88)
            PackChannels("CCP", 100, 9, 8)
        case(UnitID == 24)
            PackChannels("IP",  150, 9, 8)

which is a lot more compact.


Link to comment
Share on other sites

I suspect (though I don't know what driver you're using or how it works) that doing the purge() immediately before the read() might be an issue.  Will the read() wait till there are characters in the buffer?  I think I might purge(), then delay(), then read(), if read() wants the bytes to already be there.

Also, could you be deleting telegrams from devices other than the one you just read when you do the purge()?  If so, that might explain why it takes a long time to get data from each remote.

Link to comment
Share on other sites

Unless you do read(0) which will return whatever is in the buffer, read() will block (wait) until the specified number of characters is received, or the timeout occurs.  If the timeout does occur then it will throw an error.  ReadUntil() also will block.  For this reason you do not need, nor should you use delay().  That said, you should not be purging inside your loop because that will clear out characters that accumulate between the last read() and the purge().  Instead you really just want to use this pattern:

      read() // or readuntil()
      // process data

Link to comment
Share on other sites


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