Jump to content

drjdpowell

Members
  • Posts

    1,973
  • Joined

  • Last visited

  • Days Won

    178

Everything posted by drjdpowell

  1. Did you wire up the minus as 2-(shift reg), then move the wires around to make it look like (shift reg)-2? Then the shift reg would go 10, -8, 10, -8,… and never be less than -10.
  2. Well, the internals of the framework are not intended to be modified (or at least that would be a very advanced use). Application-specific code is meant to just be simple message-handling loops, with an API for passing messages. No LVOOP beyond copying a template class containing one “actor.vi†method. That those “actor.viâ€s are forced to be shared reentrant, with a resulting learning curve, is a problem. This conversation has lead me to reattempt a way to allow non-reentrant actors and I think I have a solution that works well, with the ability for a CLAD to more easily find his way through the code. I’m going to try it out in my current projects.
  3. Exactly. They seem to me to be much harder for a CLAD to get to grips with than my async-called, shared-reentrant actors (though I am an XNode novice). Poor wording on my part. I don’t mean community standardization; I mean developer or team standardization on using a limited set of ways of doing things, so that one be expert in those techniques, and one can read and understand code quicker. I use my actors extensively, at multiple levels in my code. I don’t use techniques like “Action Engines†or any asynchronous calls of custom VIs, because I’m standardizing on Messenger Library actors. The actor I did just today is a small, one-VI-API “helper†that adds functionality to a WaveformGraph. It is based on the exact same actor template that is used by my “Top Level†main application, and is using the same standard techniques.
  4. Is that how your CLAD programmer learns about your Xnodes? But your right, it is a problem. Even though I could show someone what to do in minutes, it’s easy to have no idea what the first step to do is. Fabiola is fighting that problem by providing several instructional videos for her new Delacor framework. I’ve been trying to develop a way to make my actors easily switched between reentrant and non-reentrant, so I can leave single-instance actors as more “just open and seeâ€. It hard, because I don’t want to give up other simplifying features, like auto-shutdown of actors. As Fab points out, one can also provide a junior developer simplicity via a simple API or set of tools that encapsulates complexity. And personally, I think there is simplicity in standardization, since there is so much effort in learning code structure.
  5. The “Popout Window†actor was a bad example; there are multiple ways to handle UI windows. I meant a more generic “thing running in parallel that receives messagesâ€. The same app with the popout windows has a reconfigurable-on-the-fly chain of analysis actors that pass data messages between them. Actors are selectable from a list of plugins, and actors must be started and stopped as the User makes changes. Another example is a “TCP Connection†actor that is created for each connection made to a "TCP Listener†actor. One can, of course, make custom code for each case, with an asynchronous call and the setup of some kind of communication, but using a well-tested “actor†template gets one up and running quicker and with perhaps fewer bugs. I don’t really understand these benefits. The major point of “actors†is to make async easier to debug, so why do I not want the actual UI to be an actor? Every time I’ve tried making a custom async thing I’ve regretted not using my actor template. And I’ve never found opening and probing async actors difficult (they have a “Show Front Panel†message)**. — James **Haven’t worked with actors on RealTime, so it might be different in that case. No, they are just simple actors with a subpanel to hold a front panel. They allow adding behavior like adding custom right-click menu options, highlighting the window when the User hovered over an icon the represents the window in the main app, notifying a managing actor when the User closes the window, etc. All this could be done with dynamic event registration in a central component, which is why it is a poor example.
  6. All this needs is the ability to specify terminal allowed types, including matching output types to inputs. For example: “A must be a string", "B must be a numeric", “output C must be the same type as input Dâ€, etc. Then it would be extremely useful (and would implement my long-declined idea).
  7. That’s fine. I include the latest dll at time of package release for convenience, but you should be able to use any version. When building the EXE it goes in the “data†directory of the executable, and the “Open†vi looks for it there. This should happen automatically, but if not you can mark it as “Always Include†in the EXE builder.
  8. Have you never had the use case of an arbitrary number of actors? “Restart†works if you want 0 or 1, but what about N, specified at run time? I made a “Popout window†UI actor just today to support an arbitrary number of independent windows in an application. The actors start as needed and shut down whenever the windows are closed.
  9. Would that help you? They use Integers to store UNIX time, which has no partial seconds. I can certainly add a Bind Timestamp (Integer) and make Get Column as Timestamp accept integers. But how common is Julian days since 4714 BC? Not sure if that should override LabVIEW’s definition of a DBL timestamp, especially as this would be a breaking change in the library.
  10. Is that a “bug� I used the LabVIEW time definition, as there is no SQLite Timestamp definition. Not sure why LabVIEW doesn’t match the UNIX definition.
  11. Are you sure you’re not asking for 972x768 pixels from a 768x972 image?
  12. Another line of reasoning would be to ask why you have PID and Logging in the same actor. If a “PID actor†is only handling messages to do with PID control, then there may be advantages to keeping all actions serialized in one loop. BTW, Lewis, the AF group at NI.com is the best place to ask AF questions. More people who use the AF extensively will be watching.
  13. I don’t think there is a major difference between using one or multiple connections. I’ve used either one or a few. And don’t worry about opening and closing connections, just keep them open. The issue to (slightly) worry about is Write Transactions, as these lock the db file. Other operations will block waiting for the db to stop being busy. These will throw a “busy†error after a timeout which is by default 5 seconds. So don’t BEGIN a transaction then wait for something, as you are preventing other processes accessing the db. The worst that can happen on power failure is that the current transaction is reverted (important point: do not delete any extra files the SQLite may leave in the same directory on power failure, as these are the “journal†or “WAL†files that SQLite needs to rollback). Finalize and Close VIs have standard error handling for “cleanupâ€-type VIs (i.e. they cleanup even on error). You do not need to use “clear errorsâ€. Note, btw, that you can Prepare statements once and reuse them. This saves some overhead. Just Finalize them at the end of the app before Closing the connection (I’ve been thinking of making the Finalization automatic on Close, but haven’t yet).
  14. A related LAVA conversation, including multiple examples of different techniques one can use. I did a “cluster of cluster†example.
  15. 1) SQLite isn’t a compression format, and as a flat table won’t necessarily be any smaller on disk than a spreadsheet file. Larger actually, due to the various lookup indexes. However, you have the opportunity to use structured data, avoiding a lot of duplication, which can end up with smaller file sizes (or, at least, the freedom to add much more info at not much larger size). For example, you have “site†and “sending app†strings that repeat often. If you instead saved keys into separate “Site†and “Application†tables, you could store lots of info in them that can be “joined†in with a “VIEWâ€. Similarly you could have an “Errors†table that allowed extended error descriptions instead of just a simple error code (or error severity, etc.). The joining VIEW would look something like: CREATE VIEW Event_VIEW AS SELECT * FROM Application_Events JOIN Errors USING (ErrCode) JOIN Site USING (SiteID) JOIN Application USING (AppID) Your UI would then query this View, and filter on any info in all these table. Find all events whose error description contains the word “testâ€, for example. 2) Look up “LIMIT†and “OFFSETâ€, and study how they are used in the “Cyth SQLite Log Viewerâ€. In that viewer, updating the filtering of a selected UI table takes ms, not seconds. This is because only the visible rows of the UI table are actually selected. When the User moves the scrollbar, the SELECT is repeated multiple times per second, meaning that it looks to the User like a table with thousands of rows. And one is free to use a lot of slow property nodes to do things like text colour, since one is never doing more than a few dozen rows. 3) I wouldn’t bother with VACUUM in a logging application, as the space from any deletion will just get used for later inserts. Use VACUUM if you delete a large amount without intending to reuse the space. 4) You cannot unlock the file if you’ve dropped the pointer to the connection without closing it, I’m afraid. You have to restart LabVIEW to unload the SQLite dll. Your code should always call the Finalize and Close methods, even on error. Hi Rob, You need to wrap multiple INSERTs into a single transaction with “BEGIN†and “COMMITâ€. Each transaction requires verified writing to the disk twice, and a hard disk only spins on the the order of once every 10 ms. You need to buffer your data and do a bulk insert about once a second (place a FOR LOOP between the “Prepare†and “Finalize†subVIs in you code image, and feed in an array of your data clusters). This touches on jollybandit’s question (5): durability against power failure by confirmed writing to disk is time consuming, so you need some kind of tradeoff between immediate saving and delayed buffering. About one save per second is what I do.
  16. OpenG’s Trim Whitespace fails on a string of all whitespace, if set to trim the front only. It returns the last whitespace character.
  17. Attach a zip file of your benchmark code (including a sample dataset) and I can have a look at it. In the meantime, have you studied the documentation on SQLite.org? Also, have you seen the “Cyth SQLite Logger� Would this work as a preexisting solution for your app? You’ve wired your database file to the wrong input.
  18. Right now for me is June 19 at 13:19. If someone asked me what day it is, they wouldn’t expect me to round up to "June 20thâ€.
  19. Yes, I just threw this together as an example. It would need some work to be a robust reusable component, though it does properly shut itself down and close all references as used in the example. The actual code that this example is modeled on is a component called “Metronome" built into Messenger Library**. The point, though, is that one can build such a reusable, easy-to-use component, and use it simplify use of the JKI template. ** See the Messenger Library example "Example of Recurring Event Methodsâ€. It shows both this “trigger†method and an alternative “delayed message to self†method. This is the template I now use, BTW, which will be in the next version of Messenger Library: It uses JKI-like strings, but as a “follow-on action†stack, where there is no ability to call “idleâ€.
  20. I’ve used DAQmx Events multiple times. Also IMAQdx “Frame Done†Events. I wouldn’t worry about the Event Loop overhead.
  21. Beta modifications: Uses Open_v2 to allow Read Only, and search for libsqlite3.so on RT. Please test. drjdpowell_lib_sqlite_labview-1.5.1.42.vip
  22. I’ll look into using sqlite3_open_v2(). I had "sqlite3.*†as one of the search paths, so that must have failed for some reason.
  23. Can you try just using the string “libsqlite3.so†or “libsqlite3.*� /usr/lib may be the default library path, and then I can cover the case where the library default path is another location.
  24. What’s the Target_Type conditional disable symbol on the cRIO?
  25. Questions: — does it work on Windows? — Do the examples work on the cRIO? — Can you attach a sample db so I can inspect it?
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.