Jump to content

ShaunR

Members
  • Posts

    4,850
  • Joined

  • Days Won

    292

Posts posted by ShaunR

  1. QUOTE (Mark Yedinak @ Apr 29 2009, 03:50 PM)

    Actually a deployment license is only $500. Granted, you still have a license cost per installation but they do not have to purchase the entire TestStand license. These deployments work essentially the same as a standalone LabVIEW application with the runtime engine.

    We were talking about a full Labview development environment my comment was aimed at this

    QUOTE

    The
    LV
    development environment is very useful in debugging on the fly if you have live code. NI even supports it with a licensing option.

    Since the OP said he deploys the vi's and anyone can change them (have to have labview on there for that). That is more than $500.

  2. QUOTE (shoneill @ Apr 29 2009, 02:03 PM)

    If you have registered for an event and the event fires one of the parameters passed at the left-side of the event structure is the actual event refnum. In my mind this does not belong there but you could theoretically close this reference and kill all other processes "listening" to the event in other places.

    Shane.

    Ah. Thats not it then. I'm looking for a way to link events from dynamically loaded vi's So that the vi can basically "hook" the existing event mechanism.

  3. QUOTE (manojba @ Apr 29 2009, 08:00 AM)

    Hi, how to create hypertext link in labview i have splash screen for about button, in the splash screen I have my companys website link as of now its a underlined text how to make it a hyperlink so when somebody clicks on it it should open the website thanks in advance...

    Hmm. Got me thinking. This would be a good one for a Coding Challenge.

    Who could write the best URL Label XControl.

    Be nice to be able to just plonk one on the FP.

  4. QUOTE (jzoller @ Apr 13 2009, 09:40 PM)

    The LV development environment is very useful in debugging on the fly if you have live code. NI even supports it with a licensing option.

    ... yes, I know, everything is always tested before it hits the floor, and no one would ever dream of pig testing so that widget can ship by Friday. Right?

    Joe Z. (not my current employer, btw)

    I'm thinking more about the cost of deployment. Exes and dll's are don't require licensing.I'd find it impossible to justify that the customer pays thousands for a full package which he/she never uses just so that they can use my software.

  5. The "Specify path on diagram" is the way forward but I don't think that exists in 7.1 (long time since I used that). So you would have to use the old method of creating an intermediary DLL which you can call from the "Call Library Function node" to pass data too and from other the other DLLs. (2D array in and out always worked best for me). Not elegant, but it works.When you create the plugins, if you make their inputs/outpts are a 2D array then your intermediary dll only needs 2 inputs (the dll name and the 2D array) and one output (2D array).

  6. QUOTE (jbrohan @ Apr 27 2009, 02:30 PM)

    Hello

    I have the need to read MMS without going to a cell phone aggregator company. The approach I offer here is not at all an example of good programming practice and it would be much better to gain access to a cell phone company's database. Maybe this will happen when the system gets going.

    These MMS are sent to a phone number, and then picked out from the picture messaging web page. I used the iMacros product to see if it could be done simpler, but found that there was just not enough control. Th iMacros can click on a position on the screen, but prefers to activate the links inside the HTML.

    The best that can be said for the method is that it works (at least until they change the web site again!)

    The vi's to enter text into a web page and to click the mouse are included.

    If I remember correctly, you can hook IE using active x to get click info. Might solve your positioning problem.

    I'll see what I can dig up if your interested.

  7. QUOTE (PaulG. @ Apr 27 2009, 05:44 PM)

    You can always ignore us (like 90% of the lurkers :P ). Or you could read it during work time when your paid for it...lol.

    QUOTE (jdunham @ Apr 27 2009, 04:09 PM)

    Queues are cool that they can even the load if your data is bursty, but queue or no queue, if you're not processing fast enough, you have a problem that queues couldn't fix.

    Unfortunately my data isn't "bursty". It is multiple continous streams with control on top. No problems either.

    QUOTE (jdunham @ Apr 27 2009, 04:09 PM)

    If I were to adopt the same strategy in the current project I would end up with 87 queues :o

    QUOTE (jdunham @ Apr 27 2009, 04:09 PM)

    OK, I give up trying to convince you. We obviously use queues in very different ways. I find them useful, even indispensable. My team's code doesn't suffer from any of those things you say queues suffer from, and we're doing things that you say are nearly impossible in LabVIEW, and they were pretty easy to code up and have great performance and scalability.

    Ummm. Are you referring to spawning multiple (200+) threads like in the BT client? I don't think that is possible. Especially if you can only have cores x 4 threads.

    QUOTE (jdunham @ Apr 27 2009, 04:09 PM)

    It's fine if you don't want to use more queues, but I don't think you'll manage to dissuade the rest of us.

    So I guess your in the Q or die camp :( (but suspected that quite a few posts ago)

  8. QUOTE (jdunham @ Apr 27 2009, 09:41 AM)

    Quite the converse in fact. You would use a queue to "queue" ( or buffer) the messages/data/etc (because you can't process them fast enough) in the hope that they may ease up later so you can get through the backlog.

    QUOTE (jdunham @ Apr 27 2009, 09:41 AM)

    Why do you need wait functions if there is data available?

    Because you may be busy doing something else that is time critical and higher priority.

    QUOTE (jdunham @ Apr 27 2009, 09:41 AM)

    So many why's. I've already explained that one.

    QUOTE (jdunham @ Apr 27 2009, 09:41 AM)

    Why would you let a queue consumer get data that wasn't meant for it? That's what I call a bug.

    How can you not? Since there is data in the queue how does it know that its not for it? Thats what I call the nature of queues.

    QUOTE (jdunham @ Apr 27 2009, 09:41 AM)

    Don't get all Trekky on me now :P And I know why as queue is useful, in the same way I know that a car is useful unless you in a swamp.

    QUOTE (jdunham @ Apr 27 2009, 09:41 AM)

    Well, do a Google search on "Global variables are bad". I got 400,000 hits. They are considered dangerous in every language. I have been using more unnamed queues and notifiers lately so that they are not available globally.

    Do a search on "kill Bush" and you get 12,700,000. Your point is?

    This is what NI have to say on it:

    http://zone.ni.com/devzone/cda/tut/p/id/5317

    QUOTE (jdunham @ Apr 27 2009, 09:41 AM)

    About my version of the sample application, I tried to add some asynchronous behavior to show the power of the queues. Did you read all the diagram comments? I though that would have answered your questions. It would be easy to modify it to match the original more closely. I took all the globals out because I think they are a defect, not a feature.

    For asynchronous behaviour they are already in while loops. If data is lost, then I'm not really sure what you were trying to demonstrate with the example.

  9. QUOTE (jdunham @ Apr 26 2009, 06:29 PM)

    As lame as my weekends eh?

    we may have converged on a spin-off topic. But you are still quite a way from convincing me that queues are "the magic bullet" and all applications should use this architecture.

    QUOTE (jdunham @ Apr 26 2009, 06:29 PM)

    Same thing would work better with a notifier. No polling, no latency.

    Oooooh. No. Because then the UI would have to wait on the notifier(s). Also if you go down this path you end up with notifiers everywhere like a plague of mosquitos. A pain in proverbial to debug. All I have to do to debug is watch the global. There is no need for sequencing so a notifier is not useful.

    QUOTE (jdunham @ Apr 26 2009, 06:29 PM)

    :wacko:

    I started this thread after a comment in another thread that suggested a fairly simple implementation would be better as a queue. I asked whats everyone fascination was with queues on this forum. As a newbie to this site, as I looked at more and more posts it seemed everyone was queue crazy and the remit was...lets start with a queue and make it all fit. So Rather than hijack the thread, I started a new one to find out why people thought (and I think even you said this too) queues are "the magic bullet" to application design.

    All applications have some degree of asynchronicity that doesn't mean you should design around a queue. It sounds almost as if you are agreeing with me in repesct to queues adding complexity ;)

    QUOTE (jdunham @ Apr 26 2009, 06:29 PM)

    Amen, brother. Dataflow is your friend. Easy to read, simple coding. But when you have parallel processes, dataflow doesn't apply. If they need to share data, you can use globals, which have lots of problems, or queues, which don't.

    The only problem with globals arises when you require synchronisation. But that isn't really a problem, it is (a very useful) feature of globals. The fact that it creates copies of data is a drawback (if you were running on a ZX spectrum...lol). But a queue isn't a replacement for globals as you point out in your example (removed the stop button from the user). And even in the first example it was used.

    QUOTE (jdunham @ Apr 26 2009, 06:29 PM)

    I did say that distibuted IO (which is I think what you are describing) is one scenario that would warrant a queue. However, yours is a large app as I seem to remember (how much of that is event management and interprocess comms?) and certainly realising the BT client wasn't a large app because Delphi is event driven therefore very suited to the task. Horses for courses.

    QUOTE (jdunham @ Apr 26 2009, 06:29 PM)

    I generally run these handlers with infinite timeout, so there is no timeout case (and no wait function). LabVIEW's internal execution scheduler may have to poll the queue somewhere deep in the bowels of
    LV
    , but that's not exposed to me. We have dozens of queues waiting in parallel with very low overhead and very low latency when an event is fired, so I suspect it's not polling at all, but is really sleeping. I don't know what you mean about a difference between queues and notifiers. As far as waiting and timing out, they act exactly the same.

    Queues do not have a wait function. Yes you can get similar behaviour IF you only ever have 1 message on the queue at asny one time, but if your producer(s) is faster than your consumer this is rarely the case. Therefore having an indefinite timeout makes no difference as your sub process still needs to inspoect the message to see if it was meant for it. So it is not sleeping, it is inspecting. You would then need a case for if the message wasn't for it and you can't just let it run through a tight loop so a wait so many milliseconds would be needed. So it's not sleeping evertime there is a message on the queue regardless of who it is for.

    QUOTE (jdunham @ Apr 26 2009, 06:29 PM)

    Ummm. It doesn't do what it says on the tin.

    It uses no globals, because you have removed the "Stop" from the user in SubVI1. The original example uses a global also.

    In the example I posted (ver 2), I set the aquisition time to 0ms and could acheive 3 ms of aquisition (mainly due to the 1ms delay I have in my notifier VI). All of the VI's show 3ms and all the vi's show the same loop iteration thus proving they are all capturing the aquisition "Event" with no loss.(well. The aquisition VI might show one more since it gets an extra go after you press stop on the aquisition vi).

    In yours, however. If I set it to 0ms the aquisition vi runs like the clappers (6229 for the length that I ran it) but the others show significantly less (2654). What is happening to the other 2654 samples of data?

  10. QUOTE (Aristos Queue @ Apr 26 2009, 08:50 PM)

    Let me assure you -- it really does go to sleep. There is no CPU load at all from a sleeping queue prim. There is no polling for data. Thread A executes and goes to sleep on a queue. Thread B runs free. When Thread B puts data into the queue, it wakes up thread A. In fact, it doesn't even put the data into the queue. It puts it directly into the output of Thread A and A wakes up and starts running as if it had just gotten the data out of the queue.

    Shorter ones first...lol.

    Even if there IS data in the queue but not for that "thread"?

    And (just a point to fill my knowledge gap) Are you saying that 2 while loops (or 50 even) will run in their own separate threads?

  11. QUOTE (jdunham @ Apr 25 2009, 08:12 PM)

    What I actually meant was why do you use notifiers to receive updates when you are using a queue anyway for events. I've just read it back and see that I phrased it badly (the subject before being events) it was in response to the previous paragraph which finished with

    QUOTE (jdunham @ Apr 25 2009, 08:12 PM)

    they use queues to communicate with the various processes they need to effect. Often the receive status updates via notifier.

    I tend (generally) to use one or the other as in many cases as (you point out later) their features can be seen to be synonymous.

    QUOTE (jdunham @ Apr 25 2009, 08:12 PM)

    I use an appropriate strategy. Not really answering your question though, I know, but I'm not sure of what you have in mind. I tend to think through the partitioning and use encapsulation to distill interaction between sub components to a bare minimum and make each aynchronous task as autonomous as possible.

    Generally it boils down to an error indication, start, stop and pause.

    But I will give you a very typical example of an every day scenario that would be very complicated using events/queues/notifiers etc. But Labview makes very easy and can be done it minutes.

    Lets assume the system is monolithic and only runs on one machine (a test/inspection machine for example) and say I have 32 digital inputs that indicate alarm conditions on of which only 8 of them are to be displayed on the user interface. I can (and do) arrange with the electrical guys that those 8 are all on the same port (I give them a spreadsheet with the pin numbers of the DIO device and define which sensors/outputs will be attached to what).Now I can have an asynchronously running digital input VI that all it has to do all day is read the status of those digital inputs and write them to a global as a 32bit number. Then I can easily mask them off in the user interface just by polling that global and (with the number to boolean function) show the user which ones they are in a 1D array of booleans or I can use the number as an index into an array of strings to show an error string. If you have multiple banks (like 128 in banks of 8) you can partition those banks for each hardware subsystem). Then your on-screen alarms become a 2D array of booleans, each row (or column) associated with each piece of hardware. Any other VI can also read that global if and when it wants to (none of that critcal section rubbish with Labview :) ). So if some other part of the system needs to now about it it can. Quick, simple and as I said takes a few minutes.

    Now. This test machine needs to feed a part from a bowl feeder into the test/inspection section. Again. I create a "Bowl Feeder" vi that requires a Start (give me a part), Stop (shutdown), Pause (wait a mo 'cos somethings wrong) and error (or no error if everything is ok). I don't need a response that a part has arrived because that will be given by a sensor.

    So I eventually end up with all these autonomous, asynchronous subsystems (each only requiring a start, stop, and pause). The start is usually from the main sequencing engine (single notifier if everything happens in parallel or one for each if they are staggered). The stop and pause can be a global (similar to that used in my previous posted example) and the subsystem handles its own errors and pauses all the other subs and the sequence engine while it figures out what to do about it and invokes the shut down procedure if it can't do anything.

    Now. Distributed IO is a different kettle of fish!

    QUOTE (jdunham @ Apr 25 2009, 08:12 PM)

    Well I found it difficult to manage an event-driven user interface in the same loop as several acquisition/control processes. If some of those processes had to maintain an internal state, it got even harder. If I wanted to reuse those hardware items in other applications, it was often easier to just rewrite the code. With a queue handling the inputs for a given device, I can have a modular program for that device which maintains any necessary state and accepts asynchronous event messages.

    I have always had the UI in its own loop. I used to "break" the link with globals and dynamic loading (the example I posted would have used globals instead of notifiers and would have been quite messy), now we have other tools like events, notifiers, queues, semaphores and the like. We have the tools to make more elegant solutions.

    QUOTE (jdunham @ Apr 25 2009, 08:12 PM)

    I do rarely use them (in the way that they are often used). Not because I don't like them, but because they don't warrant the use in a lot of the systems I design (take the example above). I could use them, but a couple of notifiers and a small global do the job without having to define messaging scheme for interaction. If it were a distributed system or a supervisory system where a lot of information is being exchanged, then yes it would warrant it, but not just for a start, stop and pause. I'm an advocate of the choosing the right architecture for the specification rather than just throw a queue at it, which it strikes me a lot of people seem to be.

    QUOTE (jdunham @ Apr 25 2009, 08:12 PM)

    I am certainly open to other opinions. What architecture do you use for your majority of large applications where queues were not the best solution? Do you handle user input and environmental input (alarms, triggers, other state changes) in the same loop of execution? Do you pass messages between with some other mechanism? Do you run a monster event loop, and run everything in the timeout case, and make sure that every subvi can finish in 50ms or so? I would love to hear more about other architectures you prefer.

    See above

    QUOTE (jdunham @ Apr 25 2009, 08:12 PM)

    In the above example and in the case of an alarm dialogue. It would set the pause flag while it is on-screen (if that's whats required or it might just log it to a file...depends). Crowbar all the subsystems and invoke the "graceful shutdown.vi" on a reset or stop. And un-set the pause flag for a cancel. . Triggers would probably be hardware and catered for by the the individual subsystem responsible for it.

    QUOTE (jdunham @ Apr 25 2009, 08:12 PM)

    My current project has about 4000 VIs, and probably 2500 are running at in the main app, with about 25 parallel static loops and 2 to 100 or more dynamically spawned loops, all of them containing at least one queue or notifier for message passing and synchronization. When this system grew to about 1500 VIs, we couldn't maintain the code any more until we refactored everything and used a lot more queues. I think that a much smaller app of only a few dozen VIs could still benefit from using queues if there are mulitple asynchronous tasks.

    That depends on how much info they need to do their job. I prefer autonomous encapsulation of the task as it makes the code a lot more understandable and intuitive (and less documentation :P )

    QUOTE (jdunham @ Apr 25 2009, 08:12 PM)

    I think I see the where the difference in views lie. I don't see dataflow as a limitation. The fact that it is a a dataflow paradigm, means that you don't have to worry about state information. The function (or vi) gets executed when all its inputs have data. Its implicit. In event driven languages (I also program in Delphi and C++ by the way) you have to have a lot of state information to make the application work in an ordered fashion. This is unnecessary in Labview which is why it is fantastic for test/automation/inspection etc but sucks as a webserver (although NI would like to think its great). I recently wrote a bit-torrent application (lots of concurrent connections appearing and disappearing at random, asynchronous pipes etc). Wrote that in Delphi because it would be a nightmare in Labview. Square pegs don't fit in round holes.

    QUOTE (jdunham @ Apr 25 2009, 08:12 PM)

    Well I have a couple comments here. For one, I'm not a huge fan of over-using state machines. I always prefer dataflow. If I have to do four operations, I'd rather see four subvis in a row than four cases in a state machine loop. But other people really like them. The large app I mentioned above has very few state machines.

    Ditto. They hide functionality, can be difficult to conceptualise and break dataflow. That said. They do have the advantage that they compact code and enable selective branching. If used spareingly a definite asset. But often abused. I think were on the same page there :)

    QUOTE (jdunham @ Apr 25 2009, 08:12 PM)

    First off. I don't consider the former to be the "wrong way" just "another" way. There are many tools at our disposal and we should choose those that are appropriate. As I think I said in the notes. It was to demonstrate that the use of queues adds complexity and obfusification. It took me about an hour to write that, debug, benchmark and comment it (with coffees). I expect the same cannot be said for the original (excluding the pictures and write-up I mean). It may have been an illustration. But there are many out there that would do just such an app that way.

    QUOTE (jdunham @ Apr 25 2009, 08:12 PM)

    Your example is a better solution to that problem, but we already established that the author wasn't trying to solve a problem so much as illustrate a scalable architecture.

    Better? No. They both fulfill the spec. I think one is easier to read and understand because it uses Labviews dataflow more and the other is more complex and difficult to read because it breaks that dataflow and adds complexity to compensate.

    QUOTE (jdunham @ Apr 25 2009, 08:12 PM)

    No. My thesis is that queues add complexity, are cryptic and (sometimes) require more VI's to be modified throughout the code. And that should be taken into account when designing a system since other alternatives can yield a more intuitive and easier to read solution and have better encapsulation.

    QUOTE (jdunham @ Apr 25 2009, 08:12 PM)

    I made a VI, which isn't too much different than other stuff you've seen but I'll post it anyway. It's an architecture that is working well for me. I would still love to see more about what is working for you in your large applications.

    post-1764-1240686447.png?width=400

    Many thanks.

    One observation. It doesn't "go to sleep" it polls the status until it has something in the queue. So I'm guessing you have a wait so many milliseconds in the timeout case. That is the big difference between queues and notifiers. If you add another notifier (wait) to my example before the acquisition another after the AQ notify in the Subvi 2 (notify) and a third before the while loop in the main (also a notify just to kick off the aquisition in the first place) then you can run the system fully synchronised, flat out with no loss of data (3ms). You can't do that with a queue.

    See attached:

    Download File:post-15232-1240703966.zip

    And if you read all that your a star....lol.

  12. I was perusing the internet this afternoon and came accross this:

    Queued Statemachines

    It seemed a very complicated solution just to acquire and display a graph. And an excellent example of why you should not use Queues for everything. They obfuscate and complicate.

    So (for a bit of fun - I'm sad like that) I decided to rewrite it NOT using queues but instead using more traditional methods. In fact, I thought I'd demonstrate notifiers at the same time. It can be improved but the purpose was to replicate the queue example and I didn't want too spend more than an hour of my life doing it.

    The result I'll let you judge for yourself. However it is a fraction of the size, fewer VI's, less complicated and extremely easy to understand unlike the queue example.

    The example from the above website.

    Download File:post-15232-1240670379.zip

    Alternative.

    Download File:post-15232-1240670495.zip

  13. QUOTE (shoneill @ Apr 24 2009, 08:26 AM)

    For me the big drawback of queues and notifiers is that there has to be a part of the code which is waiting for data to arrive. With an event, this is not the case. With an event, the code to receive new data can be one pane of an event structure. You can even have multiple "receiver" panes in one event handler, each one with their own strictly defined data type (No variants and so on).

    Just my 2c.

    Shane.

    Succinctly put! That is why queues are not events.

    You can even have multiple event structures linked to a single event (that's how I get round the local variable on Latch booleans).

    What (IMHO) would be a good enhancement to events is.....

    if you could define an event (say by right clicking on a control or indicator), plonk an event structure anywhere in your code (not just the same VI) and it appears in the list of events to link to. Then you could do things like when a DAQ digital line toggles and sets an indicator on your low level acquisition vi, an indicator on the screen toggles or an alarm dialogue appears or even kick off entire processes. It would make notifiers and occurrences obsolete and make rendezvous and semaphores actually useful. I would save weeks coding. We would also have an event scheme to rival any of the other event driven languages with the added bonus that we can also use dataflow.

  14. QUOTE (Roger Munford @ Apr 22 2009, 10:18 PM)

    I have just started with labview and have a data logging project using cRio-9012 and the 9205 modules. The data logger is connected by a slow radio link and so datasize must be kept to an absolute minimum. It also has to run unattended for three months in a harsh environment.

    If I store the calibrated data each measurement will require 4 bytes. If I store the raw data then each measurement will need only two bytes. However the raw data will require separate storage of the calibration and offset data. I assume that both of these will drift with time and temperature and so what sort of period should they be recorded for later correction?

    I assume that the calibrated data will be continually corrected. Is it possible to convert the calibrated fixed point data to binary with the original 16 bit resolution for data logging but with the advantage that calibration has been accounted for.

    Thanks for your attention.

    Roger

    Hmmmm. Not sure what your asking here.

    First of all, a fixed point number is an integer that is scaled by a factor (12.3 can be expressed as the integer 123 scaled by 1/10). If your raw data is only 2 bytes then your calibration data need only be 2 bytes IF you won't exceed the 2 bytes by adding it (65536). If by adding the calibration you exceed this you will require more (1 more byte will give you a ceiling of 16777216) . However, you only need to store 1 calibration number per measurement interface so if you have 8 analogue inputs, you only need 16 bytes to store the cal data for all inputs. Your results data will still be 2 or 3 bytes per measurement.

    This is where I'm confused.

    You say that if you "store the calibrated data", you have 4 bytes per measurement. But the raw data is 16 bytes. So it could be that your cal data is 4 bytes and you are doing 4byte (32 bit) arithmetic or your cal data is 2 bytes but you are doing 4 byte arithmetic.

    Alternatively are you saving the scale and offset for each result? In which case there is no need to. You can just store 1 cal and offset for each channel (2 bytes per channel so for an 8 ch analogue input that would be 16 bytes) and your results would still be 2 bytes (with the caveat outlined earlier).

    Another scenario is that you are actually converting to a Single Precision number (4 bytes) which is a waste of time as your data is 16 bits.

  15. QUOTE (jdunham @ Apr 23 2009, 03:42 PM)

    Giving up already :o

    I believe the Event Structure to be the best innovation in labview since.....well...I can't remember when. Why don't they receive by a queue?

    QUOTE (jdunham @ Apr 23 2009, 03:42 PM)

    Occasionally I am asked to do maintenance from very old programs before I started to use queues (some of them pre-date the introduction of queues), and not only do they work less naturally from the end user perspective, but it is a pain to maintain the code since everything is in one big hairy loop or else there are lots of crazy locals and globals causing race conditions. In addition those apps are not as big, because those problems get exponentially worse as the program size grows, so there is kind of a limit to how big the app can get before it is too much work.

    I don't see why they should work less naturally just because they don't use queues.

    QUOTE (jdunham @ Apr 23 2009, 03:42 PM)

    Every time I experience this, I think, "Wow, queues are really the magic bullet to program design that makes large application development feasible in LabVIEW". I'm sure there could be other ways to develop large applications, but queues are very flexible and robust, and have a terrific API (unlike the horrible File I/O library), and have great performance. Obviously you have a different opinion, but I encourage you to try a big application with queues, and I think you won't go back.

    It's always been feasible (and fairly straight forward).

    You seem to be under the impression I've never used queues. I have written several queue based applications where that technique was the most appropriate (2 of them with a team of 8 Labview programmers). But I have written far more where it was not. So I guess I have gone back, and forward, and back......etc.

    I'm not sure of your criteria for "big" but I tend to gauge the scale of a project on how much hardware I have to interface too since that is probably 75% of the programming time on most most of my applications. The current one involves 12 motors, 8 marposs probes, 5 camera's, 192 digital IO's, 2 analogue inputs, 12 analogue outputs and 3 proprietary devices using MVB , CAN and RS485. This part of the project I would consider medium sized since it is one of 3 machines (which are similar but not identical) and will be part of an automated production line.

  16. Wire an indicator to the Standard out and you will see the result from your call to the DOS box. You don't get an error because the SystemExec successfully completed the CMD call. However, the DOS box may not have executed the copy command.

    If you look in the windows help, they suggest making a batch file with the command options and calling that.

    I personally would use a "Call Function Block Node" to call a windows API to achieve what you are trying to do. (Kernel32.dll has a SetFileTime function). Although there may be an easier/more elegant method.

  17. QUOTE (jdunham @ Apr 21 2009, 09:23 PM)

    Your talking about not interrupting an interrupt on a microcontroller with one interrupt level. An interrupt, (generally-as it's name suggests) "interrupts" program execution. If your main program is running and an interrupt comes in, on a microcontroller, it will automagically switch to the interrupt vector where your handler sits after pushing the program counter and other state information onto the stack. Once the interrupt has been serviced, it will pop the stack and resume program execution.

    But.

    If you remember I said I view events in a similar way to interrupts (analogous, not that they were), and qualified that by saying that they can happen in any order and at any time. which is is true. An interrupt can be from any of a number of sources (character comes in on the USART, watchdog timer, A/D conversion etc) which, when this "event" occurs will immediately pause the main program execution and jump to the handler(s). And one of those "events" may be every 20ms and another may be when there is a "T" in the day and the girlfriend has gone to see her mother.

    QUOTE (jdunham @ Apr 21 2009, 09:23 PM)

    With any event driven system, the maximum amount of time an event takes to be handled determines the latency of the system to handle new events.
    It would be nearly pointless to use any event-driven system to handle a 10-minute monolithic process
    . If you need to handle other events, you can usually break up a long process into many successive events, and throw the follow-on events from inside the handler. That's a state machine, which is another great use for a queue.

    Are fou saying that VB, C++ or Delphi couldn't handle a file search? (of course your not :P ) A file search can take more than 10 mins and when it finds a file matching the search criteria, raises an event (usually with passing a search record). The main program is just sitting there (animating an icon, refreshing the display, picking its nose) untill the event tells it its found something.

    I'll start another thread about Labview, state machines and why windows programmers love them....lol.

    QUOTE (jdunham @ Apr 21 2009, 09:23 PM)

    But I've just been convinced that Labview is parallel in nature :o ). Surely we just parallel up our slices until its big enough for our complete task :)

    QUOTE (jdunham @ Apr 21 2009, 09:23 PM)

    No, the major difference is that queues are FIFO, and notifiers are broadcast events with no history. If your notifier handler is not fast enough, you will lose events rather than stacking them up and falling behind like a queue would.

    Indeed (well 50% indeed anyway). Queues are a particular type of buffer where only the first and last elements are accessible (FIFO,FILO). If your consumer is slower than your producer (as in my example), your buffer (queue) will just increase until you reach a limit (resources or you've fixed the length of the queue). However, with notifiers, if your consumer is slower than your producer your producer can just sit idle until it receives some indication (another notifier perhaps) that the sub process has finished. A queue based system demands that things are taken off the queue faster than they are put on the queue. Notifiers do not have this limitation (but they do have limitations). The consumer is idle until a start "event" has occurred and the producer is "idle" until the "process complete" event has occurred.

    I'm not anti-queues. I just don't think they are the magic bullet to program design which some people (not necessarily on this forum) seem to think they are.

    QUOTE (jdunham @ Apr 21 2009, 09:23 PM)

    I've still got Marks post to do :P

    QUOTE (Mark Yedinak @ Apr 22 2009, 06:40 PM)

    I still fail to see how you can say that a queued message is not generating an event. A message can be queued from anywhere at any time just like your interrupts. The event handler (the part of the code taking messages from the queue) processes them as soon as the arrive just like an interrupt handler. Also, an interrupt handler will only be working on a single event at a time just like a queue.

    /quote]

    A queue doesn't generate events, neither does it react to events WHEN they happen (which is what is meant by event driven). I would consider an OnQueue or OnDeQueue to be an event that would be "generated" by a queue (which doesn't exist in Labview). Your queue implementation is a history (or buffer) of "events" that have occurred at some point in the past and the order in which they occurred (user clicks something on screen, DAQ, VISA or whatever). It is an extension to the logging example in the examples directory.

    It will only process these historic events if it is at the front of the queue therefore it will only process it immediately if there is only 1 in the queue (queue of one sounds familiar
    :P
    )

    The old Motorola 68000 family processors had 7 interrupt levels which denoted priority levels. In LabVIEW if you created 7 queues and had 7 parallel message handlers (one for each queue) your system would not behave any differently than a 68000 processor. What you do and how events are processed is up to the "interrupt" handler. You had to write the specifics of your ISR for the 68K too. In addition, since the 68K was single threaded higher priority interrupts caused the code in the lower priority ISRs to stop running. Only one thing could be running at one time on that processor. For multithreaded, multicore systems you still need to figure out a way for one task to stop another. This would is true regardless of whether you are using
    LV
    or not. Multiple priorities don't really solve this problem when you have multiple parallel tasks running since each task is independent. In addition if you are using a single queue for events you can always queue a high priority task at the front of the queue. This way that event will be processed next.

    Whew. What a lot of effort to mimic a 20 year old single threaded processor :P . This example, however, is a good example of interrupts interrupting interrupts.

    The key point here though is that WHEN the interrupt occurs "code in the lower priority ISRs to stop running"! Not "the interrupt will be serviced IF the request is at the front of the queue".

    QUOTE (Mark Yedinak @ Apr 22 2009, 06:40 PM)

    With respect to concurrent or parallel I think you are being a bit picky about the terms. Of course if you have a single CPU nothing every trully runs in parallel. However with multicore CPUs no LabVIEW does utiltize all of the cores. You don't even have to change your code for this to happen. I am not sure how old versions of
    LV
    would handle this but certainly the newer versions are aware of multiple cores. This is not true in the text based languages. You have to jump through quite a few hoops to take advantage of multiple cores with a single application.

    I think Greg answered this better than I.

  18. QUOTE (Mark Yedinak @ Apr 21 2009, 12:45 AM)

    Done.

    QUOTE (Mark Yedinak @ Apr 21 2009, 12:45 AM)

    Creating parallel tasks in C or C++ is not a trivial task. You have to manually create your processes and threads. In LabVIEW this is all done for you. Drop two loops next to each other and you have parallel code. It is as simple as that.

    I will concede Labview "parallelism" but I I think we are talking about concurrency and I would wholeheartedly agree that labview runs concurrent tasks but not parallel code. But it's not an area I'm an expert in and perhaps I'm being too pedantic (I don't really care how it works as long as it does...lol).

    You are right though multithreading in C++ is not trivial. It is in Delphi though :)

    QUOTE (Mark Yedinak @ Apr 21 2009, 12:45 AM)

    . Since you already use notifiers it shouldn't be too difficult for you to use queues.

    I see events rather differently.

    Events (to me) are analogous to interrupts. Events can occur in any order and at any time and, on invocation, handler code is executed. A queue in Labview, however, does not generate events rather (from what you have described) you are taking the presence of data to mean that an event has occurred. You don't know what event has occurred until you have popped the element and decoded it The order is fixed (the position in the queue) and presumably, while this is happening, no other "events" can be processed so they cannot occur at any time (well perhaps they can occur at any time, but not be acted upon). The major difference between notifiers and queues is that notifiers can occur in any order and at any time and the "handler" (the section of code waiting) will be invoked.

    I would be interested to see how you handle priorities with a queue. Lets say (for example) Event 1 must always be executed straight away (user presses Emergency Stop) but event 2 can wait (acquisition data available. And just to be annoying, lets say processing the acquisition data takes 10 minutes and you've got 100 of them in the queue when the e-stop comes in ;P ).

    In an event driven environment, when Event 1 comes in its handler can check if the Event 2 is running and stop/pause it or postpone it (cut power and gracefully shut down acquisition).

  19. Not wisihing to hijack this thread (perhapse start a new one? This could go on a while...lol)....but!

    QUOTE (Mark Yedinak @ Apr 20 2009, 11:20 PM)

    Didn't most versions of LabVIEW executables require the run-time engine? At least this is what I recall from as far back as LV 4.0.

    Well. It was a while ago (I weened on version 2.0...it came on floppies...lol). But I seem to remember creating monolithic executables. Deployment was a doddle :P

    QUOTE

    Since LabVIEW is inherently parallel in nature you always need some mechanism to pass data between parallel tasks and to synchronize them as well. Queues naturally do this. Unlike a global variable queues provide synchronization as well. In addition they are event drvien so you can avoid polling local or LV2 style globals. They are also very efficient with respect to performance.

    Actually Labview is inherently serial in nature (left to right). That is why you have to resort to other techniques to manage parallelism. I also fail to see how they are event driven given that you put something in the queue and take things out...nothing more. It is a serial buffer with access to only the first and/or last entry in the buffer.

    I don't tend to use queues much, but I do extensively use notifiers for passing data and synchronising, which aren't really event driven either in so much you can wait for a notifier and it will get triggered. The only truely event driven features in Labview are the Event Structure and VISA Event. But linking events programmatically accross disembodied vi's (which I use far too often); I've always found troublesome.

×
×
  • Create New...

Important Information

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