AzeoTech

Administrators
  • Posts

    6,436
  • Joined

Posts posted by AzeoTech

  1. There are lots of ways.  First, you can always do Alarm.paused = 1 to stop DAQFactory from processing alarms.  In fact, this is a good thing if you have lots of alarms.  Set paused to 1, then use alarm.checkAlarms() to trigger alarm checking from a simple sequence.  This is more efficient.

    Alternatively, you can modify all your alarm expressions and add:

    && !isempty(alarmsStarted)

    to the end, so it might be:

    pressure[0] > 100 && !isempty(alarmsStarted)

    Then, just declare alarmsStarted when you are ready for DAQFactory to start processing alarms:

    global alarmsStarted = 1

    There are plenty of other ways too.

  2. If you are going to use DAQFactory networking (meaning creating a "Connection") then you'll have to put the data in a channel.  Just use a test D/A channel on the main system and set it to the desired value like you would a variable.

    Now as to addressing, you can always use 127.0.0.1, which is defined (universally, even in other programs) as the current system.  Just remember that you need to enable broadcasting.  It is disabled by default for security reasons.  Go to File - Document Settings to enable.  It should only be enabled on the server application, not the client. 

  3. What you are seeing is actually a limitation of your device, not DAQFactory.  It apparently only likes one connection at a time.  So, the only way to share that data between two DAQFactory instances is to have one instance retrieve the data from the device and have the other instance retrieve the data from the first instance.  You can do that with DAQFactory networking if you are using Pro.  Alternatively, on the same machine, you could rig something up where that first instance writes the data to a file and the other instance reads it.

  4. Probably.  You just need to find a 32 bit ODBC connector for PostgreSQL.  DAQFactory connects to all databases via ODBC and really doesn't know exactly which database you are working with.  ODBC makes this transparent.

  5. Sounds like a bug.  I've noted it so it is looked at and fixed in a future release.  I tested with this simple sequence and it looks like continue inside of a catch() doesn't just break out of the while, but ends the sequence:

    while(1)
       delay(0.1)
       try
          ? 'a'
          ? b
       catch()
          ? 'c'
          continue
       endcatch
       ? 'd'
    endwhile
    ? 'e'
       

     

  6. File handles are used when you are using low level file access, basically functions that start with "File.".  You do not need it if you are using an export set.  

    You say the sequence will not run.  Have you checked the command/alert for an error message?  Can you post the entire sequence?

     

  7. AddressType is not something you should change.  I don't remember why it is in there, probably for a very specific use case.  It actually refers to the socket itself, not the protocol.  It is ethernet port specific and won't appear if you have a serial port selected, as you probably did for RTU.  It has nothing to do with the protocol.

  8. But, to answer your original question, you can change the device of a channel:

    myChannel.strDevice = "Test Device"

    When done, do:

    channel.restart()

    which probably isn't needed but is required if you change timing. Still it is a good thing to do.

    I would use channel.listAll("myGroupName") to get a list of all the channels in a particular group, then cycle through to update the device.  Something like:

    private string clist = channel.ListAll("myGroupName")
    for (private i = 0, i < numrows(clist), i++)
       execute(clist + ".strDevice = 'myNewDevice'")
    endfor
    channel.restart()

    This same pattern can be used to change any parameter of a channel, Timing being the most common.

     

  9. Actually, the easier way is to use a single device and change which port and protocol it points to. Then you don't have to mess with the channels.  You'll need to precreate both a TCP and a serial port, setting the address / port # to 0 for the inactive one.  Then to change the port for a device, do:

    device.myDevice.PortName = "mySerialPort"

    Don't forget to disable the old port by setting its port # to 0 and calling initcomm() before doing this, and then enabling the new port by giving the correct port # to the new port and calling initcomm() on that.  So, something like:

    device.myDevice.port = 0
    device.myDevice.initcomm()
    device.myDevice.portName = "mySerialPort"
    device.myDevice.port = 3
    device.myDevice.initComm()

    Next, to change the protocol:

    device.myDevice.ProtocolName = "ModbusRTU"

     

  10. I haven't heard of NPort so just assumed it was for your USB->Serial converter.  If you are using an Ethernet -> serial converter you should use one like the ones from SeaLevel that offer a Raw port connection and thus do not require a local driver.  With the NPort you are still at the mercy of the 3rd party virtual comm port driver and whatever limitations it may have.  By using a the raw port, DAQFactory is connecting via its own internal Ethernet driver directly to the converter and then on to the device.  In this case you are only relying on DAQFactory's Ethernet driver and the software inside the converter device.

  11. You have the right idea, but the problem is that systime() - expStartTime1 is a scalar and you can't plot a single data point.  You need an array of times, and the best place for that is in your Y data.  So if your Y Expression is "MyChannel", your X expression would be "MyChannel.time - expStartTime1".

  12. So the issue is that the legend doesn't clear out until new traces are added with data?  You'd probably have to trick it by adding a trace that doesn't have a legend, waiting for a paint cycle, then deleting that trace.  Basically since there is no valid data to plot, it isn't redrawing the graph.  Once you give it some valid data it redraws.

    Why not just leave the traces in place?  Or create some fixed number and only use some of them, clearing out the legend of the rest?

    Or just create your own legend and don't use the one built into the graph control.

  13. The mostly like issue is lack of an end of line character.  Terminal programs typically generate either a carriage return (ascii 13), or line feed (ascii 10) or both when you hit the enter key.  Because DAQFactory works with both ASCII protocols and binary (which terminal programs can't handle), it does not automatically add any characters.  To add a carriage return in the monitor, add \013, or for line feed \010.  That will tell your device that the line is done and that it should respond.  Note that in script you will typically use chr(13) and chr(10) instead, i.e.:

    device.mydevice.write("some string" + chr(13))

     

  14. There are a number of ways to do this.  Here is one:

    1) create a start button.  

    2) in the Start Button, select a Quick Sequence Action, with code like this:

    global expStartTime = systime()
    global expStopTime = 0
    beginLogging(myLog) // to start logging.  Replace myLog with the name of your logging set.

    3) create a Stop button, select a Quick Sequence Action with code like this:
    expStopTime = systime()
    endLogging(myLog)  // again, replace myLog with the name of your logging set

    4) create a Variable Value component.  The expression would be:

    formatDateTime("%H:%M:%S", iif (expStopTime, expStopTime - expStartTime, systime() - expStartTime))

    That is it.  The script in the start button initializes two variables holding the start and stop time of the experiment.  Stop time is set to 0 while the experiment is running since it isn't over yet.  The stop button then sets the stop time to the current system time.

    The expression in the variable value component has two parts.  The first, formatDateTime() takes a time stamp and displays it in human readable format based on specifiers.  In this case %H is hours, %M is minutes, and %S is seconds.  Note that this will only work for up to 24 hours.  If you need longer you'll need the specifier for days, which is %j.  That will work up to 1 year.

    The second part is iif() which stands for inline if.  It has three parameters.  If the first parameter is true (i.e. not 0), then the function returns the second parameter, otherwise it returns the third parameter.  In this case, we are looking to see if the stop time is 0 or not.  If it is not 0 then the experiment is done and we return the difference between the stop and start times, which is the final elapsed time.  If it is 0, then the experiment is running, so we display the difference between the current system time and the start time.  This updates each time the screen is redrawn.

  15. That error comes from the database itself.  First you should try typing in the query directly into your database tool outside DAQFactory.  That will often give you a more detailed error message.  If it is successful, then the issue has to do with how DAQFactory does QueryToClass().  This function is designed for high efficiency acquisition of data from the database.  As such, it first queries for the number of records so it can preallocate the required memory.  It does this by replacing everything in the select with count(*), so:

    select field1, field2 from myTable

    would be replaced with

    select count(*) from myTable

    This works fine in most cases, but some more advanced queries, possibly like yours, it does not work with.  In these cases you are forced to use the older and slower db.Query() function and read records one at a time.

  16. My guess is what you did is declared currX and currY as numerical variables first, i.e.:

    global currX

    then realized your error and fixed it to:

    global string currX

    The problem is that once a variable is declared, you can't redeclare it as a different type.  Thus you get NaN because you are assigning some string to currX and currY that can't be converted to a number, like "x + y".  If you happened to set it to "3" or even "3 + 4", DAQFactory would convert the string into a number, 3 in both cases, since the string isn't evaluated, it is simply converted up to the first invalid character.

    There are three ways around this:
    1) use a different variable name
    2) save, close and reload the doc
    3) do:

    clearGlobals()

    which will erase all global variables and thus require redeclaration of all your globals.

    Note that this behavior is a symptom of DAQFactory being a dynamic language that allows changes on the fly, and certain optimizations that go with it.  A compiled language of course would not have this issue.  That all said, I will admit that this one catches me rather often as I often forget to include the "string" in my declarations :)