-
Posts
1,969 -
Joined
-
Last visited
-
Days Won
172
Content Type
Profiles
Forums
Downloads
Gallery
Posts posted by drjdpowell
-
-
I had original made similar probes using an Xcontrol, with the idea that display customization would then be easy (and clean, using right-click menus). But after a lot of head banging I abandoned Xcontrols as unsuitable (lossy if asynchronous; too slow if synchronous) and wrote this package in an afternoon. They are, thus, very 1.0. Haven’t felt much need for a pause option, as I can always just select a different probe for that, and I use these probes in debugging communication between parallel processes; pausing one process while the others continue can be unhelpful.
Adding a “pause the probe” option is very easy, though, and I see that Saphir’s probe has this option (labelled “Freeze display”). I’ll consider that for the next release. Thanks.
-
As an aside, there is also LabbitMQ, a LabVIEW interface to RabbitMQ, to consider.
-
Cyclic Table Probes
A package for creating custom probes with "history"; showing the last N values rather than just the latest. Values are displayed in a cyclic table, which wraps around automatically when it reaches the bottom of the display window. Developed to support messaging systems, where messages can be handled too quickly for the eye to see with a last-value probe. Included are some standard probes, for strings, variants, objects, and some numerics. Also included is a "Text Variant" probe, for messaging using a cluster of such, and a "JKI State Queue" probe for use in designs using the JKI "state machine" template (see image). But the expected use case is for very easily creating custom probes for whatever messages one is using (just modify one of the included probes).
Also includes "Quick Timer" probes to rapidly time execution of portions of code to accuracies of as low as 10 microseconds.
Now hosted on the LabVIEW Tools Network.
JDP Science Tools group on NI.com.
Requires VIPM 2017 or later for install.
-
Submitter
-
Submitted11/16/2013
-
Category
-
LabVIEW Version2013
-
License TypeBSD (Most common)
-
-
Try adding a method to your child classes. That seems to make them stay under “Dependancies>>items in memory”.
-
Anyone get a chance to test the new modifications on a system experiencing 1097 errors? I’ve encountered no issues with the new package, so I’ll release it to the CR soon.
-
I like to think about PID in terms of real units (maybe you do this already too). The Proportional gain is the ratio between a change in input and the corresponding change in output. The integral and derivative times likewise have real meanings - they're not just numbers. You likely know this already, but I'm always surprised at the number of people who have trouble explaining PID because they don't think about the physical meaning of the gains. I found that PID tuning suddenly made more sense to me when I started thinking about it the gains corresponding directly to units in the process, and it doesn't require a detailed mathematical model.
I like to go a step further and try and represent things graphically. For temperature control I plot the "Proportional Band”, the range of temperatures where the heater output would be between zero and 100%, on the same graph as the process variable. Tuning is still by intuition, but with more visual information to go on. You can see the effects of the PID parameters in the twists of the proportional band.
-
Your device likely only has one ADC, with a multiplexed input, that can do 200kS/sec in total on all channels, or 200/16=12.5 kS/sec on each of 16 channelschannel.
-
Yes, Microsoft is a bitch when it comes to protecting precious data. The memory management standards are now insane compared to XP.
Actually, turns out the client was running XP when they had an error. But, my XP is running on a virtual machine under Parallels on a Macbook, so perhaps that changes the memory protection and is why I have never had this error in testing.
-
Attached is a new VIPM package (beta) with modifications to how “Prepare" works to avoid reading outside the allocated memory. I do not know if this will solve the problem, but as an added benefit the new method will give improved performance of “Execute SQL” for multiple SQL statements. Please give this a try and report if it eliminates the 1097 errors.
drjdpowell_lib_sqlite_labview-1.2.0.28.vip
-
Interesting query. Is the -- comment valid SQL syntax?
Could a badly formed query be throwing the exception?
“Badly formed query”? Excuse me?!? Yes, that comment form is valid SQL.
Beta version, seems to be working:
Does the LabVIEW string to C string conversion explicitly, allowing the difference between the two pointers to be used to calculate the number of bytes of remaining SQL.
-
-
I don't know the SQLite code at all, but a quick look at the image (and the docs1) brings up the following question2: if the pointer is supposed to return a pointer to "the rest of the SQL", is it OK that you're giving it the full length of the SQL string as the max length? Won't that cause it to read past the end of the SQL string? Is the SQL string guaranteed to have a NULL terminator? Even if it does, does MoveBlock respect that or will it copy whatever's there even if it is a NULL (I'm assuming it would and that then you're potentially reading someone else's memory, which could explain the exception).
In this code I had the problem that the SQL statement is passed into the “prepare” dll function by pointer, but I don’t have access to that pointer, so I can’t calculate the length of the remaining part of the statement. So I instead copy the maximum amount, including any invalid junk off the end, and then walk the string till I hit the null terminating byte (done inside “pointer to C string”, where the junk bytes are discarded).
Can “reading someone else’s memory” cause an exception? If so, I’m surprised I’ve never had this error myself. If someone can confirm this as the problem, then I can rewrite “Prepare” to convert the LabVIEW string to a pointer first, then do things by pointer.
-
I am receiving the same error on the odd occasion using this library. So far it has only occurred when running a built EXE and not when running from source. I have yet to figure out a reproducible way to trigger it:
I still cannot see what might be causing this error. You should defiantly have a shift register in your code, to guard against the case where the for loop is called zero times (is there any LabVIEW developer out there who didn’t learn this the hard way?). But I can’t see how this could cause the described error.
Here is the code of the “Prepare” method:
The error can only happen if:
1) sqlite3_prepare_v2 dll call runs without error.
2) “Statement” handle is returned greater than zero.
3) “Remaining SQL tail” pointer returns zero or invalid.
I would expect most problems (invalid dll path, for example) to violate (1) or (2).
-
Do you use multiple levels of abstract classes? File.lvclass<— LVfile.lvclass<— VI.lvclass, for example? A HasBlockDiagram method would be defined in the LVfile class (default result FALSE) and would be overridden in VI.lvclass to return TRUE (but not overridden in LVLIB.lvclass).
-
In my case, I am implementing a subscription message system. The system needs to allow for multiple subscriptions and each subscription needs to keep track of all of its subscribers and the last message sent. That allows me to broadcast to all active listeners and for new listeners to request the current value of they subscribe between broadcasts.
Funny, I use variant attributes for much the same thing, and asked about copies in this conversation. I also allow new subscribers to get a copy of the most recent message on subscription (though not always; I distinguish between “State” notifications (save the most recent message) and “Event” notifications (don’t save).
I’ve long been meaning to improve the performance, but haven’t got round to it.
-
Another idea is to keep all data in a single flat structure such as an array, with the index to that structure stored in the variant tree. Lookup the index then index the array in place. Then at least all the copying will be of small integers. Or one could try a tree containing DVR references. But if we are taking very large data sizes then mje’s ultimate solution of a database might be best. I’ve even considered using in-memory SQLite databases in place of variants for small data structures, just to have the increased flexibility of SQL, but the performance is significantly worse than variants when the data size is small.
-
LVOOP objects are just a (nice) wrapper; you still need an underlying storage method.
-
It is not possible to make the first 'get attribute' inplace since I am getting an attribute value by name and replacing it. The IPE only provides access to the node data, not its attributes, as pointed out in the Idea Exchange link you provided in your first comment to the thread.
Oh yeah, duh. I’m working too hard. Liking my original suggestion better.
-
Thanks for the trick. I will try that next.
I just tried the re-factor using the IPE instead of the for loop to preserve the child attributes. The result is a 31% DECREASE in performance. I must admit I am very surprised by this.
update middle variant data using IPE.png
Assuming I did this right, I think your other solution sounds better. I'll post my results once I complete the edits...
I’m confused because I couldn’t get the IPE to work with a variant for the type input (LabVIEW 2011); I have to supply the actual type (which limits its applicability). Using a variant only works on variants inside variants (did you unknowingly do that? would reduce performance).
BTW, the first “Get Attribute” that is copying an entire branch of your tree, so that’s also needs to be inplace (if you can get that solution to work).
-
3. I often extract all child attributes from one of the top attributes and then perform an action on each of those. If the node is now an attribute, I would need to remove that item from the array of attributes before I process them. There are two ways I can think of doing this. The first is to test the attribute name inside the process loop and skip the one named 'NodeContent'. The second is to search the array of attribute names for the element named 'NodeContent' and then delete it from the array before I process the array in a for loop. Any opinion on which solution would be faster?
I believe attributes come out ordered, so name your content attribute a single zero byte (Hex 00) and it will always be the first element (which can be skipped at minimal cost with an array subset).
-
Another thing to look into is the In-Place Structure’s Variant To/From Element structure, which does preserve attributes. But I think it allows one to change the type of the Element.
-
Make sure you’ve kudoed "In Place Element Structure Support for Variant Attributes”. It’s the copy at the first “Get Attribute” that is killing you.
One way around this is to not use the actual value of your storage variants at all; instead keep the "content" of that tree node as a “NodeContent” attribute. Then your above code becomes just a “Set Attribute”.
- 1
-
I thought that you could use the "Default Value" of your get variant attribute node to do the casting for you. However this appears to not work.
Seems to work, at least in LabVIEW 2012.
-
[LVTN] Messenger Library
in End User Support
Posted
For anyone using this package, I’ve uploaded the latest version (should really have updated this more than once a year). I’d like comment on the following new features:
This is one of three asynchronous dialog boxes.
This can be used in a “delayed message to oneself” form of doing a continuously updating process (as opposed to using the “Metronome” helper actor or the (ill advised) timeout case).
Intended for when the reply is uncertain. With this VI, a process can be confident that it will get a message of some kind back, and thus does not wait forever.
Observes an address and triggers a response if that address goes invalid.