I should have written this post one month ago before I took the CLD exam. The good news is I passed that. 🙂 80 out of 100, which is more than I expected (I’ll carry on this later).
I will not talk anything about the exam itself, as I promised in the exam. But just finish the things I prepared for the exam.
1. I found this blog “Pass your CLD/CLA exams the JKI way” very useful, which gave me the confidence of carry on preparing for the exam. Though I didnt use it at the end, it is very helpful for preparing your own template.
2. Timing problem. The timing problem is the tricky part in the exam, such as how to pause/resume/restart your state machine. I made a subVI beforehand to practise it. You can find it here.
3. Pay attention to the documentation, which should be the easiest part to get the credits.
4. If you can finish the sample exams within 4 hours, I’m pretty sure you can pass the exam. If you can finish that within 3 hours, you can get the full marks in the exam.
Since I didn’t finish all the functions during the exam, I felt bad about it. But it turned out I got almost full marks in the programming style and the documentation parts, which saved my life. I didn’t have the plan to take the CLA before, but now I’m considering about it.
Good luck to all of you who are going to take the CLD exams.
Related post: Preparing for LabVIEW CLD exam (1)
Elapsed Time.vi is a very useful Express vi which returns the elapsed time and can be reseted. Unfortunately there is no pause function in Elapsed Time.vi ( LabVIEW 8.5 to 2009). I had been looking for the examples of pausing and continuing the time in LabVIEW, but there seems not be a simple one.
So I created this myself. It is not efficient in term of excecution time, but it is simple to be made from scratch and memorized.
Basically the shift registers are used to store the previous elapsed time. When it is in the false (run) case, the elapsed time is added to the ‘total elapsed time’. When the vi in the true (pause) case, the total elapsed time is transferred to the start time and the Elapsed Time.vi is reseted (stopped). Hope this will be helpful. 🙂
———————–In response to Mark’s question——————————–
So I added the reset function for this SubVI:
This is a simple demo using the mouse wheel to control the numeric indicator in LabVIEW. The value of the ‘mouse wheel position’ increases or decreases when we scroll the mouse wheel forwards or backwards.
The reason of posting this is when I tried to using the mouse wheel to control a camera (to zoom in/out) in LabVIEW, it took me a lot of time finding the right example. If this post happends to be the top 3 of your google results, it should save you some time.
This VI was modified from the example ‘Basic Input Demo.vi’ in LabVIEW. Since the windows’s dll only returns the moved (or related) position of the mouse wheel, a shift register was employed to display the ‘absolute’ position.
Sorry that I cannot upload the .vi file for the limitation of wordpress.com. But it is easy enough to re-create this vi yourself from the snippet.
Note that:1. There is no ‘mouse wheel’ triggering event in the event structure (at least before LabVIEW 2009);
2. The .dll file in ‘Acquire input data.vi’ returns only the moved position of the mouse wheel comparing to the position when the dll was called last time;
3. The returned mouse wheel postion was divided by 120 in this demo, which may change according to different mouse setups.
4. The polling event (nodes in the while loop) could be put into the timeout case if you want to use event structure together with it (and the timeout shouldn’t be -1).
So I registered for the CLD (Certified LabVIEW Developer) exam on 5th August. I knew LabVIEW when I started my Ph.D in November 2007 and have been using it for 3 years. I had been “learning” LabVIEW for 2 years. In the 3rd year I was more of using it instead of learning more things. Since it is said that the CLD is suitable for users with experience of “a year and a half”, I think it is fair for me to take the exam.
There are 4 exam samples online (link) and they are said to be very similar to the actual exam. Also Darren’s note on CLD is very helpful (link). So my plan is taking the examples as the real exam and finding the knowledge I’m not aware of. One exam lasts 4 hours and I have to use one weekend to finish one. So the examples have to be finished before end of June (5 weeks to go).
I took the “ATM machine” examle last week and failed to finish it in time. I think that might be the most difficult one among the 4 (or not?). Anyway, fortunetly there is still time to fix that problem.
Here are what I have learned from the examples, and I will add more thoughts as the practice goes on. Hope this can be helpful:
1. We do not need to install any module beside LabVIEW to take the exam. It tests your coding ability instead of your module experience.
2. The logic of the exam is very complicated.
3. For me, the exam could be finished if more time (maybe 2 more hours) was given. Thus the challenge is how to finish it in the limited time. You cannot do that without good practice.
4. Use state machine, as stated in the exam. And I found the queue operation is not necessary in these 4 exam samples.
5. The project manager is not neccessary for there won’t be many versions of your code.
6. Folders named “SubVI” and “Control” are useful. Put the Top_level.vi in the top folder.
7. There could be file read/write operation, and thus we need to master how to manipulate the file path and text-related functions.
8. Draw the states clearly before coding, which saves you a lot of time later (Or, do not code before the logic of states is clear).
9. Because of 8, pens of different colours are very helpful (but is it allowed to bring our own pens?).
10. Set the preference of block diagram a ‘comfortable’ way. E.g. untick Display terminals as icons; untick Show dots at joints; untick Auto wiring; tick Default SubVI terminal as required.
11. Quick drop saves you time.
12. Save the code frequently in case of unknown situations.
13. If you cannot finish the code, create all SubVIs only with front panels. At least the program could be ran (with some missing functions).
14. Knowledge of timed loop and control reference are necessary (Update: I added an example in this post).
I will carry on the exam simulation this weekend and my timeline is: finish the state diagram within 1 hour; Create the structure and SubVIs with only terminals and descriptions in 1 hour; try to finish all the functions in 2 hours.
Good luck to me.
Update: Related post Preparing for LabVIEW CLD exam (2)
Shift register is very handy in LabVIEW programming. To add one more shift register (say, shift one more time), what you need is only click and drag down the shift register. If you want to recall the data generated in a loop 5 times ago, you drag down 4 more shift registers and pick the bottom one.
But the drawbacks are obvious,
1. It is not neat nor scalable in coding.
2. User cannot modify it without modifying the code.
So here is a alternative method for large/unstable number of shift registers — using the queue in the loop. The thought was quite straightforward, just to find something that can buffer the data. I’m sure there are many cleverer ways.
So the queue is used to store the data. With enqueuing and dequeuing we can do the shifting. The case structure is to determine if we shifted the right number, and the condition can be modified (e.g. if(get queue state==#shift regisiters) ).
The problem is solved now. Please let me know if you got better solutions:)
I have been using IMAQ module in LabVIEW these days, and the integration of many algorithms saved me a lot of time. It is the core module when we want to do Machine Vision. I haven’t digged into it since the subset seems OK for my job. But in this post I’m not saying the beauty of it, instead, I’m going to tell seven sins of the IMAQ module. Just to clarify, I splitted some up in order to make it “7”. All the problems are based on vision development module 2009.
1. It has to be in IMAQ. Sometime I just want a simple “2D array filter” to proceed my 2D data, but there is no such a node in the core functions, although I though it’s not complex. And the fact is, if I want to proceed my raw 2D array in any ‘image’ way, I have to buy and call IMAQ module to do that, plus conversion back and forth. That’s not handy.
3. Old style front panel. Here is the front panel comparison of the “IMAQ create.vi” and “Open/Create/Replace file.vi”
As you can see, the controls and indicators are different in two VIs. So if we have IMAQ VIs with other VIs in the same top level, we will have diffrent front panel controls if we just create controls by right clicking.
4. “IMAQ VIs should support all image types which makes sense” as described in the NI idea exchange.
5. Along with the last sin, there is no boolean array input/ output in “IMAQ ArrayToImage.vi” and “IMAQ ImageToArray.vi”. Actually boolean 2D array is quite useful in many pattern recognization applications. (Yeah, this is the extra sin I just divided from last one)
6. “Image Dsc Out” missing in some VIs. E.g, after the proceeding of the image and we want to convert it back to an array, do we need to release the buffer we created? If yes, there is no such a connector on the output. I assume all the VI without the “Image out” connector is to be used as indicators, but still, it’s better to keep it uniform.
7. We have to create buffer to manipulate images. In this module it’s not as smart as in Array functions, we need to create one buffer to proceed an image, mutiple buffers for mutiple ones (or, use one buffer one by one). It would be nicer if NI can make this easier.
Anyway, IMAQ is a very useful module and hope I’ll study ultilize it better in the future.
I posted an article <Play the music with your DAQ card> some days ago. It saves you when you have no sound card but only a data acquisition card to play the music (and you’re welcome:)). Now what if you have no speaker but only a Jacob’s Ladder? We borrowed a Jacob’s Ladder from the physics department and had a play with it. Using the electric arc we are able to play the tunes!
This is the video I uploaded in youtube, please help yourself:)
For the people who are not convinient to browse youtube, you can also find it in this link (tudou.com, a video server in China).
Sorry I didn’t edit this phone recorded video, and you have to rotate your head to the left to view it. So we converted the sound file to a sequence of train pulses in LabVIEW, which triggers the Jacob’s Ladder to genenrate sparks. By changing the duty cycle and the frequency of the pulses, we are able to change the volumes and tunes.
P.S. We are not playing all the music, for the tune and pace range of the Jacob’s Ladder is very limited. It only makes the sound when the electric arc appears.
I came up with a similar question (<Return #elements of an array greater than a certain value>) before, and today this one “What’s the efficient way of comparing 2 arrays and returning an array with the bigger values?” was posted in gsdzone.net forum.
This is not a complex problem and many responses were given. But all of them suggested using a for loop to compare the elements one by one. Most of the comparison and numeric nodes in LabVIEW are polymorphic and we should take use of them efficiently. I tried the following code and it works 🙂
A thought that may or may not be helpful (or even correct!) in optimization: Always try to do it with polymorphic nodes when you did it with a loop; always try to do it in one loop when you did it with several loops.
Thanks to rogel who brought up this problem.
Producer/Consumer loop (PC loop) is one of the most important architectures in LabVIEW. It gives a good solution when your data producing rate is faster than your consuming rate. A typical example is analysing/storing the data while acquiring new ones. We dont want any slowness or jag of the post-process interrupt the acqusition. Thus PC loop create a space from the memory and uses it as a buffer to deal with the asynchronous tasks.
In this architecture, the consumer loop will wait (for timeout period) until there is a new element in the queue. What if we want to run the consumer loop regardless the queue is empty or not? Sometime, we want to output waveforms until new waveform is generated. I modified the PC loop as following:
So the consumer loop does the normal things (like output pre-defined signals) when there is no element in the queue (determined by state of queue.vi). And when there is, the consumer loop dequeues it and updates the state (like updating signals). I think this thought is logical and similar to human thought. An alternative method is to enqueue the same element after we de-queue it. In this case the loops will be keeping enqueuing and de-queuing. I don’t quite like this method, of which the thought is not straightforward.
These days my supervisor and I have been working on some amazing (and silly) things. Briefly, using LabVIEW to synchronize a movie, a piece of music and a Jacob’s Ladder. The goal is to demo an interesting show to the school kids. And I would like to share a piece (cause it’s not done yet) of the LabVIEW code, which loads the music and plays it.
So what you need is a data acquisition card (analog output rate greater than 44k Hz, at least 2 AO channels if you like stereo), a speaker or an earphone, LabVIEW and your music. In LabVIEW we read the music file and send the waveform file to 2 analog output channels. If you chop your earphone and connect the three (L, R and ground) lines to the corresponding AO ports, you will hear the sound.
What’s the point of doing that rather than inserting the earphone straightly to your laptop? Because WE CAN.
Note: 1. In my test, reading a block of music won’t slow down your DAQ loop, since the AO task is only 44.1k Hz. I used a Producer/Consumer loop just to make it scalable.
2. To prevent the music from section repeated, I selected ‘Do not allow regeneration‘ mode.
3. Enable ‘auto start’ for ‘Analog write‘ VI.
4. Future work can be done on stopping the AO task automaticly once the music is over. To do this, we can simply bundle the ‘end of file?‘ state of ‘sound file read.vi‘ to the queue element, and use the state to stop the consumer loop.
5. Tell me if you really have done this. 🙂