AzeoTech

Administrators
  • Content Count

    5,664
  • Joined

  • Last visited

Everything posted by AzeoTech

  1. AzeoTech

    Current Component Name

    You just need to clear the flag in the code that is processing it. So, set the flag to 1 in the screen component, then when the sequence processes that flag, set it back to 0. Yes, private variables are automatically "flushed" from memory when the sequence ends. When an object is created using new() you will always assign it to a variable. If you don't the object is destroyed as soon as that line of script is complete. But the object isn't really stored in the variable, just a reference to the object, sort of like the objects phone #. If you then do: myNewVar = myObjectVar or you pass that variable reference to your object to a function, you aren't actually copying the object, you are simply passing the reference to the object, the phone # in my example. Script can then use that phone number to actually get to the object and do things with it. Well, as variables go out of scope, or you assign new values to variables, the phone # of a particular object may get lost. If all the references to the object are lost, the object is automatically destroyed since there is no way for any script to access it anymore. There are really two ways these object references are lost: 1) a variable goes out of scope (private variable being destroyed at the end of the sequence, local variable in object destroyed with the object, and 2) when you assign a new value over top of the existing reference.
  2. AzeoTech

    Pump control using analog input

    OK, here is a working sample. You have to convert the Excel file to a simple CSV file. I've attached the one you gave. If your data is always this simple you might want to skip Excel and just edit it in Notepad. Put that file in c:\daqfactory, though you can change the path in the controlPump sequence. That sequence will read the file, then change a channel called "output" based on those values and the time. Change the output channel to point to the LabJack output. chris.csv filePlayback.ctl
  3. AzeoTech

    Switching Window from one ctl to another

    How are you switching between instances now? Are you using some low level windows calls from within DAQFactory?
  4. AzeoTech

    Write and read in permanent memory

    1. No you can't do it with V channels. That's why I don't use V channels ever. Its almost always better to just create a Test channel instead. 2. Then you really should chase down why the file gets corrupted. It sounds like you have some hard drive troubles.
  5. AzeoTech

    DAQFactory Stops Responding

    Which DAQFactory release?
  6. AzeoTech

    DAQFactory Stops Responding

    That module handles the graphing, so it has something to do with your graphs. Does it do it on its own or when you try and do something with the graph?
  7. AzeoTech

    Enable/Disable Graph Traces

    You can actually easily do this using flags. Let's say you have an variable called "displayMyTrace". You could then set this to 0 or 1 using a checkbox, then for the trace it corresponds to, change the expression from: MyYExpression to: iif(displayMyTrace, MyYExpression, Nan()) There are other ways too, but we'll still look at adding a "visible" variable for each trace.
  8. AzeoTech

    need to show VALUE at plot lines in graph

    You can't really do that without using the MouseMove event for the graph. This will give you pixels and then you'll have to use some math to convert the pixel position into a value.
  9. AzeoTech

    Write and read in permanent memory

    Use Persist in Channels to save values outside of the DAQFactory document and outside the logging set. However, you should figure out why your .ctl document is getting corrupted. Are you using the Auto-Persist timer or doing system.saveDocument() anywhere?
  10. AzeoTech

    Download a Table of data

    Your usual DAQConnect contact.
  11. AzeoTech

    maximum no of channels

    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.
  12. AzeoTech

    Current Component Name

    You set Timer to 4 in the sequence function. I think you want to replace that first line with: function relay_timer4(timer) and then call from the component using: relay_timer4(timer) (the two "timer"s in my code are only because you named the variable the same. The value isn't passed because both "timer" was used in both places, but rather because of how I declared the function relay_timer4) That said, you wouldn't want to call Relay_timer4 from within a user interface component because it has a loop and will hang DAQFactory. Things inside component events, or actions have to be fast as the entire user interface blocks while that script runs. This means basically that DAQFactory appears hung until it is complete. As to your other questions: The # of threads in DAQFactory is PC limited, not DAQFactory limited. 80 threads is not a problem. It may not be terribly efficient as task switching is expensive, but that probably doesn't matter in your case. You don't need execute or evaluate to set the first StartThread() parameter. That's a string, so you can build that dynamically. As for the name of the thread, I would just make it so you can stop the thread from within the sequence itself. For example, you could have an array that contains a running status: global myThreadRunning = fill(0, 80) Then right before starting the thread, set the appropriate array element to 1, then pass the index for that array element to the function. Then, inside the loop inside the function you started in its own thread, just check the appropriate element and return() if it goes to 0. That all said, be careful with StartThread(). If you mess up you could easily end up making thousands of threads instead of 80, especially when first debugging. I personally only use StartThread() inside of objects using the StartLocalThread() function. This function is just like StartThread(), except can only be called within a user object / class. The thing about it is that once the object is destroyed, any running threads it created are also destroyed. Since objects are automatically destroyed once there are no longer any references to them, they clean up a lot nicer than threads started with StartThread(). Your application really sounds like one for object oriented programming anyway... Anywhere where you have lots of things that are essentially the same should be in objects.
  13. AzeoTech

    Read from Siemens PLC through profinet protocol

    As I said, you should subtract one. One thing though: DAQFactory tries to automatically figure out whether you are using 0 indexed addressing, or 40001 addressing. Both 40,001 and 0 refer to the same PLC address. They are just two different ways of describing that address. Technically 0 is the one actually used in the Modbus query, so I prefer it over 40,001 as it is actually used in the frame. 40,001 is much more arbitrary and has no real meaning other than the spec and just gets converted to 0 by the software on both ends. Now as I said, DAQFactory tries to figure out which you are using. It does this by assuming you are using 0 indexed addressing until you try and read an address in the 30,000 to 49,999 range. Once you do that, it will assume all addresses are in 40,001 type notation and will strip the 10,000's place and subtract 1. So if it was working for a while then stopped, it's likely that during your testing you tried a register in the 40,001 range which told DAQFactory to start subtracting one, and then when you went back to 0 indexed, everything was off. This would get reset on restart as long as you didn't leave any channels or other reads in that 30,001-49,999 range. BTW: you can force it into 0 indexed notation by reading a register in the 50,000+ range, even if that register doesn't exist. The simple act of trying tells DAQFactory to stay in 0 indexed mode.
  14. AzeoTech

    The workspace window tree is missing

    Please see this topic: This occurs when you accidentally drag one of the docking windows off the side of the screen. It remembers this, and so you can't really get it back without resetting to the defaults.
  15. AzeoTech

    Read from Siemens PLC through profinet protocol

    A couple points here: 1) it is possible with floating point values to get a number that is close if you are one off and reversed from how the PLC has it. So it is possible you just missed one of the combinations. If the registers in ModScan show 40001, 40003, 40005, etc, and you want to use 0 indexed channel #'s, you have to subtract one. So, 40017 for example should be 16 in DAQFactory if you want to 0 index in DAQFactory. 2) remember also that except for integers (in the 32 bit floating range with no exponent), no non-integer number can be represented exactly using floating point values. For this reason you will see rounding which can cause differences between programs in the least sig fig due to how they round. Personally I'd say your problem is probably #1. You probably want register 16, without the R words.
  16. AzeoTech

    No Modbus RTU serial communication

    That is a typical address for a coil. But if you are not reading any holding or input registers, then you probably need to read 8192. If you do start reading registers above 30001 you will need to change your coil status back to 8193. It has to do with the fact that some manufacturers use 0 indexed notation, and others use 40001 notation (which is offset by 1). DAQFactory tries to figure out which you are using, but can only really tell if you start using registers instead of coils.
  17. AzeoTech

    No Modbus RTU serial communication

    Did you setup Port #2 on the Click to be Modbus? Use their software to verify their comm port settings, then set yours to match. Finally, go to the comm monitor in DAQFactory and see if you are getting any Rx traffic from your Tx queries.
  18. AzeoTech

    Reading SPI data with a T7

    We are looking to add these functions immediately. Please contact us directly and we'll get you a beta. They will probably be added next week.
  19. AzeoTech

    Variable Resolution Index

    Yup, basically what you did, but you need to declare X too. You probably want something like: global resolutionIndex = 11 using("device.LabJack.") include("c:\program files\labjack\drivers\labjackud.h") AddRequest(0,LJ_ioPUT_CONFIG, LJ_chAIN_RESOLUTION, resolutionIndex ,0,0) GoOne(0)
  20. AzeoTech

    Button Visibility

    Yes, but you have to do it in script by changing the button's "visible" property. Give the button a name, then use: component.myButton.visible = 0 to make it invisible, and = 1 to make it visible. Replace 0 and 1 with whatever expression you would like that evaluates to true or false.
  21. AzeoTech

    maximum no of channels

    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.
  22. AzeoTech

    need to show VALUE at plot lines in graph

    If I understand you correctly, you can use the Markers. Right click on the graph near where you want to see the value, and select Marker A or Marker B and Add.
  23. You can't use fromJson() globally. That expects a class type (in the "_ClassName" field) so it can create the class for you. That is more for when you do toJson() to create a json representation of your object, then want to recreate the object. To do it from a raw json file, you need to create a blank class, instantiate it as an object, then call fromJson() on it. Something like this: private handle = file.Open("c:\robbudge.json",1,0,0,0) private string datain = file.Read(handle, file.GetLength(handle)) file.Close(handle) class myClass endclass global xml = new(myClass) xml.fromJson(datain)
  24. I don't know that it has been done, but DAQFactory does have a built in JSON parser, so I would use a tool to convert XML to JSON (I found one in about 3 minutes that was able to convert your file once you remove the first line), then you can write some script to load the json and parse it into a DAQFactory object tree. Then you can just use script to parse through the objects and add channels. Should be pretty easy for someone with scripting experience like yourself.
  25. For a bit, you can use TestBit(). For a group of bits (say D7-D4 of A15), you would have to mask and shift: (value >> 4) & 0x07. This is basic bitwise boolean math that is covered in basic old-school computer science texts if you want to read more.