AzeoTech

Administrators
  • Content Count

    5,729
  • Joined

  • Last visited

Posts posted by AzeoTech


  1. It is in 17.9 of the DAQFactory User's Guide, but basically the T series stuff has a name for just about every parameter and in DAQFactory you can specify the name and the value in channels, so you don't really have to use script (though you can).  The common names are actual I/O types, while uncommon ones can be accessed using the "Special" I/O type and the Quick Note column.  


  2. With the T7, you should just be able to create a channel with the TDAC I/O type, the desired TDAC # in Channel # (i.e. 1 for TDAC1), and treat it like any other analog output channel in DAQFactory (i.e. Timing = 0).

    Note that when scripting for the T7 (or UD devices for that matter), DAQFactory takes care of the Handle.  You always specify the id instead.  


  3. I would start by updating to the latest release.  From the look of it you are running 16.3.

    I would also watch task manager and make sure there are no memory issues, i.e. DAQFactory's memory usage isn't steadily climbing.  If you want to email us your doc, we can take a quick look to make sure there is nothing obviously wrong in script.

     


  4. It worked fine for me when I changed the channels to Test channels.  One thing to note, while the logging set is running, DAQFactory keeps the file open.  Because of the way Windows caches to disk, it can appear that the file is getting no data until Windows writes the cache to disk.  If you quit DAQFactory, or change the logging file name, the file is closed and then the data logged can be viewed.

    I also would not use Auto-Split files.  This is a largely deprecated feature.  If you want to split your files, put date specifiers in your file name.  So for example:

    D:\DAQFactory\TestData_%y%m%d_%H.DAT

    This would create a new file every hour.

     


  5. DAQFactory only has two variable types, numbers and strings.  It uses the declaration you provide in extern() to convert to the appropriate C data type before calling the external function.  This is done internally and you do not need to worry about it.  DAQFactory will complain, however, when you try and pass a regular variable to a parameter that is expecting a pointer, or vice-versa.  


  6. I believe NVarChar is for unicode.  DAQFactory isn't compiled for unicode, and so even if you could read this field type, it wouldn't look right.  Do a search on the web for converting NVARCHAR to VARCHAR inside a query (SELECT).  For example, I quickly found a database forum that shows a CONVERT() function, as well as a CAST() function.  I have not used these, but they, especially the cast() look quite promising.


  7. No, by definition a static library is compiled into a program, while a shared library can be accessed by an existing, already compiled program like DAQFactory.  If you only have a .lib file available, you would have to compile that into a DLL.  This should be relatively easy with just a little wrapper code.


  8. Well, the first problem I see is that these functions all appear to take scalar values, but you are passing pointers.  If you get no errors from your extern() function calls, but get an error when you actually call the imported function, then that is likely the issue.  So, for example, it should be:

    InitStatus = InitDll(PortNo, BaudRate)

    the @ sign returns the pointer to that variable, not the variable contents.  DAQFactory checks to make sure you don't pass a pointer to an imported function that expects a value, and vice-versa.  


  9. Depends on how often you are taking data.  Data at 1 second uses 60 times as much disk space as data at one minute.  But in general, the persist file is 16 bytes per data point.  That's 8 for the time stamp, and 8 for the value.  Assuming 1 minute data, 13 months = about 560,000 data points * 20 traces = about 11 million * 16 = about 176 meg.  This won't bog down DAQFactory on a modern machine, but you should try and avoid bringing in all 176 meg worth of data at once.    

     

    For performance reasons, I often will create a second channel for each channel that has a slower data rate, say 1 hour, that I use for generating long term trends, but that might be overkill in your case.  Of course if you have 1 second data instead of 1 minute, then we are talking 10.5 gig, which is more memory than a 32 bit app like DAQFactory can handle at once (it is limited to 4 gig like all 32 bit apps).  Then you really will need to have a duplicate slower data set if you want the ability to zoom out and see the entire time span.  

    Remember though, that it only matters what data you bring into DAQFactory.  So you can create 1 second data for 13 months on 20 traces as long as you only view, say, at most one week at a time, and scroll it.  It is when you zoom out to 6 months or the full 13 months that you run into problems.


  10. For the HOA: You can't do it this way with a radio.  The radio can only handle a set channel, not an expression (which is why it doesn't show with a red/green background.  I'd consider using a descriptive text or symbol component.  For example, see attached.  Doing it with a radio is more involved.  You would have to calculate the current state based on those two bits, and then break it apart when the radio changes.  That would involve some script.  It would be easier to simply make your own radio, which I also did in the attached using 3 buttons and 3 LED controls.  You could use a wide variety of things for this.

     

    HOA Sample.ctl


  11. No, you should see something like:

    CHANNELS:
       + Group1
       + Input
       + Main
     

    You can click on the plus next to the group and the individual channels in that group will appear.  Then you can get to the channel view with the graph/table.

     

     


  12. That has to do with how Windows sends mouse messages in a touch screen environment, or more to it, how the touchscreen driver does.  Either the MouseUp is coming so quickly after MouseDown that DAQFactory never gets a chance to draw the frame, or it is not sending a MouseDown at all.  More likely the first.  I don't have a good solution for you other than to check the touch screen driver software configuration for some sort of touch feedback.  Often you can get it to display something to confirm a click.  

    You might improve the display by decreasing the Page's refresh rate.  The "box" is drawn as soon as you click, but is not erased until the screen refreshes.

    You could also try using the DAQFactory OnLButtonDown and OnLButtonUp events described in 5.28 of the User's Guide.  You could then create your own feedback.


  13. We received an email with a host of good questions from a new user I thought we should share on the forum.  The answers are a little terse to allow you to explore.  Feel free to ask follow-ups:

    How do I change the default text color?  When working on a black background it’s hard to find black text.

    You can't.  That's why (among other reasons) I don't use black backgrounds.  The best workaround is to create a formatted component, then duplicate or copy/paste it.  Or, you can always create a user component out of it, then it will show up in the component popup (at the bottom).  Usually this is used for groups of components, but there is no reason you couldn't do it for a single component. 
     
    How do I format numbers in order to get a “,” thousands (comma) separator displayed?
     
    Use the Format() function. 
     
    Can a variable value component display numeric data this is right justified?  I want to display numeric data in aligned columns.
     
    Yes, open the Properties docking window (View - Properties).  This gives you access to many of the component's properties.  There is one called Align that only appears here.  Set it to 1 for left, 2 for center, 3 for right, and 0 for auto-size left.  Note that when it is not 0, you have to set the size. 
     
    I’ve figured out the grid but I can’t find a display that tells me the size in pixels and coordinate location of objects.  Example; SF pipe and fittings don’t align and scale precisely before grouping, etc.
     
    Again, use the properties docking window.  It will show you these numbers and let you change them. 
     
    How do you get a pipe network (group of SF pipe and fittings?) to animate or change color as a group?
     
    You can group the components, but you still have to change the colors manually in each control. I suppose you could name all the components the same thing, then in script change the color.  That would work too.
     
    Can grouped components be scaled?
     
    You mean resized?  Yes, if you find the group in the Workspace under the appropriate page, you can select a grouped component without ungrouping and then resize it.   
     
    What is the most efficient way to create channel controlled, multi-colored symbol components (5 state pump, 3 state tank, etc.)?
     
    Use symbols with different color symbols as actual different images.  Again, either duplicate the final component or use the user component feature to make a template so you can reuse. 
     
    How do I create a HOA radio button (auto, off, hand from top to bottom); AUTO would set Modbus 201 high & 202 low, OFF would set both 201 & 202 low, HAND would set 201 low & 202 high?
     
    You would have to use a quick sequence action.  First, let's say you have two channels called mod201 and mod202.  I would of course use better names, but you get the point.  The Expression for the symbol component would be: mod201[0] * 2 + mod202[0].  That way you get 0 for OFF, 2 for AUTO and 1 for HAND.  Then set a quick sequence action for the component.  The script would be something like this:
     
    private curState = mod201[0] * 2 + mod202[0]
    switch
       case(curState == 0) // currently off
          mod202 = 1 // go to hand
       case (curState == 1) // currently hand
          mod201 = 1
          mod202 = 0
       case (curState == 2) // currently auto
          mod201 = 0
          mod202 = 0
    endcase
     
    Can a radio button display button and/or text color based on selection or address?
     
    Not sure what you mean.  Remember you don't have to use the text on the radio button.  You can always use static or variable value components to provide the radio labels. 
     
    Can the vertical spacing on a radio button be modified?
     
    No.  You would have to create your own radio type control using a combination of components.
     
    I created a symbol (background topo map) in SF but it locks up DAQF when I copy and paste it to a page using the WMF option:.  Is there an alternative method to import large BMP or WMF files as backgrounds (typically maps)?
     
    Under the latest (18.1), which you should probably use, there is a Load image button in the symbol component that allows you to load PNG / GIF files directly into the control.  You also don't have to put images into Symbol Factory to use them.  You should only add images that you want to be in that library and reuse.  You can always just copy an image out of Microsoft Paint and paste it into DAQFactory directly.  However, it is better to use the PNG load feature of 18.1 as these are smaller. 
     
    Are there preconfigured, resettable totalizers (gallons, elapsed time meters, etc.) or do I have to create scripts and if so, do you have any examples?
     
    No built in, but easy to implement.  Create a Test D/A channel to hold the total.  Set the Persist and History to the same value, maybe just 1.  In a sequence marked autostart, add this code (assuming the channel was named "total":)
     
    if (isempty(total[0]))
       total = 0
    endif
     
    This just initializes the total channel and only will ever run once if Persist is working.  Finally, in the channel you are trying to totallize, go to it's event and enter script similar to this:
     
    total = myChannel[0] - myChannel[1]
     
    How do I create a graph control to view a previous point in time and width (back 5 days with a trend width of .01 days)?
     
    Use the scale from and scale to expressions in the graph control along with a couple variables to hold the range.  Alternatively, create a name for your graph and then access those parameters directly through component.mygraph.bottomAxis.strScaleFrom / To.  You'll also need to turn "UseTimeWidth" off. 
     
    Data persistence doesn’t seem to work consistently (frequent data loss on DAQF start/stop with same project file)?
     
    Is there a persist folder under c:\DAQFactory\persist and is it writable?  Are you getting any sort of error messages?  Note that persist files are by name, and if you run a second document that has overlap in channel names, it will cause the persist files to change.
     
     
     
     
     

  14. Yes, we have 18.1 ready. 

    The only issue with it is that we had to replace our expired code signing certificate and that apparently resets our "reputation" with Microsoft Smart Screen despite the fact that DAQFactory has been available for download and used around the world for 18+ years.  So, it will likely be listed with 17.1 along with a note that Smart Screen may trigger on Windows 10 machines.  This will go away as more people download it, but right now is quite annoying.

    Thank you for the reminder on the requests.  Don't be afraid to ping us again.


  15. I'm not quite clear what you are trying to do.  You are reading "Level" and want to plot this on the graph.  But if the level is < 473 you want it to display the value 100?  In this case, in your graph, simply enter this expression:

    ((level - 457) * 0.6536) * (level >= 473) + 100 * (level < 473)

    This is using a little boolean math.  "True" is 1 in DAQFactory, and "False" is 0, so when level >= 473, only the first part goes through, and when level < 473 only the second part.  Since all paths use "level" and level has time associated with it, it will plot correctly.  

    You do not need any script.

    The big issue with your script is that level_b = 100 assigns a scalar to level_b and you can't plot a scalar because it is only one point.


  16. Yes, at 0.1 seconds there may not be any space between the queries to allow for an output.  One way to resolve this is, as you said, to pause the reading.  You can do this by moving the timing of the reads into script.  To do this, put all the input channels into their own channel group, say "Input", and set the Timing of them to 0.  Then create a sequence.  The script would simply be:

    while(1)
       channel.readGroup("Input")
       delay(0.1)
    endwhile

    When the sequence is running, it will query the inputs.  When you stop it, it will stop querying the inputs.  Use beginseq() and endseq() from script to do this.