LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

CLD Exam Feedback

In the "Car wash" example, if I pass the "Stop" and "Car wash simulation switches" references to a "Car wash" sub vi and then check via "property node" in the sub vi if there is any value change of these booleans, I think I can easily save 20-30 minutes. The structure of the application would be much simpler too. Reading the values of these booleans via "property node" should have almost no effect on the speed. Will I lost points? It would be really nice if NI can give an "official" answer.

0 Kudos
Message 11 of 23
(2,118 Views)

Passing a reference of a control to a lower level vi to read its value is a legitimate use of a property node.  Don't worry about it.  Like I said before "minimize" does not mean "avoid".

 

- tbob

Inventor of the WORM Global
0 Kudos
Message 12 of 23
(2,066 Views)

I modified jgcode's code (hope you don't mind, jccode) and the main part of the program is now done in the "car_CarWash_main_Reference.vi". I think the structure of the application is simpler,  but I do pass references of several controls on the front panel to a lower level vi.

 

Is this a "legitimate use of a property node" or I should avoid this technique in the CLD exam. Thanks.

0 Kudos
Message 13 of 23
(2,057 Views)

As I said before, passing references to lower level vi's and using property nodes to get or set values there is a legitimate use of property nodes in my opinion.  But I'm not a CLD grader.  However, I would not worry about it.  It won't make you fail.

 

- tbob

Inventor of the WORM Global
0 Kudos
Message 14 of 23
(2,051 Views)

 


@Ian Ren wrote:

I modified jgcode's code (hope you don't mind, jccode) and the main part of the program is now done in the "car_CarWash_main_Reference.vi".


Hi Ian

 

That is fine, I don't mind at all - although your code post is missing some file(s)

 

 

@Ian Ren wrote:

I think the structure of the application is simpler,  but I do pass references of several controls on the front panel to a lower level vi.


Ian, I think it would be helpful for the discussion, if you comment in detail, as to why you thought the original implementation of using a enum-based state machine in a multi-functional VI (MFVI):

 

18423i7000F80AE036ACCA

 

Versus your changes below, leads to creating an application that is more scalable, maintainable and readable? Or any other reasons for your design choices?

 

18421i46BD17736BE01A17

Cheers

 

-JG

 

Certified LabVIEW Architect * LabVIEW Champion
0 Kudos
Message 15 of 23
(2,034 Views)

JG

 

1) First, just like to thank you for sharing the complete and very well organized code. Being a "lone ranger" LabVIEW programmer, I really learn things from the fellow LabVIEW programmers like you. I have attached the zip file, hopefully, nothing is missing this time.

 

2) When I said it being simpler, it is just my opinion. It arguably uses less nodes, and it may also arguably be more scalable since all I need to do is to change the cycle reference array. I am not a frequent user of MFVI, so I am biased.

 

3) The main reason for my posting is that for the real project I do (which involves a lot of number crunching), a sub vi usually runs for more than 100 ms. So passing a reference to a sub vi is the only way I know to get front panel input promptly. It works very well for most of my applications. Just would like to get some input from the community if this is a good practice, and also from NI if I will loss any points at the CLD exam.

 

Ian    

0 Kudos
Message 16 of 23
(2,000 Views)

Hi Ian

 

No probs with the sharing, I enjoy feedback and discussion and am here to learn too.

 

For me, there are a couple of main issues:

 

The biggest issue with your implementation is that making a simple change e.g. adding another Washing Type (e.g. Clean Tyres) in the middle of the other Washing Types would potentially add bugs to your application as the logic depends on the specific index of items in multiple arrays (rather than by name in a cluster). You would also have more work to do in updating all arrays if a change was introduced (as opposed to the single cycle reference array you mentioned).

 

Secondly, the bottom loop of the top-level design does not "run" during a Cycle as it will be "stuck" in the while loop of your logic. Therefore the only way you can currently exit this loop is via the Stop Button PN changing (or on completion). What happens if you need to insert another message or stop the loop in a different way? As the bottom loop does not "run" this limits what the design can do. A better implementation is that the bottom loop continues to execute and using this natural looping, you check (poll) the state of the Cycle module (called software control timing). 

 

Thirdly, programming with a linear approach fixes/locks you in to what in the array and cannot change during execution of the application. I know it is not the case now, but what happens if you need to return to a previous cycle (e.g. repeat rinse once more IF STILL soapy)? You do not know if this when you create your array therefore, you cannot easily expand your approach to handle this.

 

The other main issue is that you are not creating modular code. Incorporating UI elements into your code would impinge on your ability to easily test that module of code and verify that it is working correctly without running the main application (i.e. before integrating it). This effect will get worse as the application grows. It will also be harder to isolate and fix bugs when encapsulation is not used.

 

Aside from the main issues IMHO some minor issue with your approach include:

  • Performance: It is my understanding you will be taking hits swapping threads for PN value read/writes
  • Storing data in FP objects: This is generally considered bad practice. You pass Wash Cycles via Local Variable but you could have easily used by-wire. You are using the FP to store data when you read, update then write to a PN.
  • Reference closing: You do not explicitly close the references you open which may lead to a memory leak (prob not a big concern in this example tho)
  • Lack of error handling
It also seems there are two bugs in your application:
  • The Soap Application state always run regardless if Main Wash Position Switch is set to TRUE
  • The Standard/Deluxe buttons do not "pop-up" with the way you have used a PN in the Event Case
I understand that my approach could be better, but given the time constraints for the exam, I think it does create a more readable, scalable and maintainable approach then using PNs. As for your third point, in what situations do you need to get "front panel input promptly"? For example if you have number-crunching or another process that takes 100ms or 1sec then it may be nicer in your application to set the cursors to busy so your users can't press and change a whole bunch of stuff whilst the process runs. If the process takes e.g. 10secs or 30 secs you may what to enable an abort function but disable everything else on the FP. Of course this will depend on the application so it is just an example.
Cheers
-JG

 

Certified LabVIEW Architect * LabVIEW Champion
Message 17 of 23
(1,986 Views)

JG

 

Thank you for your comment. I agree with you in principle.

 

1) Your approach is "more scalable, maintainable and readable". However,  from you notes, I also noticed that it took you 3 hours 50 minutes to finish two of the sample exams. I do not know if I will be able to finish everything as neatly as yours in 4 hours. Using my "less scalable" approach, I am sure I can finish the job a lot faster. I attached the code with "added Wash Tires" operation, as you said, it takes a bit more than updating the cycle reference array, but I can implement othe mods in 5-10 minutes. (mods shown with red comment).

 

2) You are right that the bottom loop of the top-level does not "run" during a cycle. I usually overcome this by passing the references to the sub vi. I agree that your approach is neater, however, it is not always possible for many of real applications. As I said last time, my applications usually involve a lot of number crunching, which takes a few seconds to a few minutes. It is just not practical to sub-divide a task into less than 100 ms sub-vis and use the "software control timing". Usually, the user needs to 1) know the progress of the computation and 2) able to abort the operation. Both can be easily implemented from passing references to sub vis.

 

3) If the application involves making decision based on the result of a previous task (e.g.. Repeat rinse once more IF STILL soapy). I will use the state machine, but if the process is pre-defined, I think the Enum array approach is simpler to program.  

 

4) Usually I replace the UI element by constant while trying to verify the code.

 

5) It is also my understanding I will be taking hits swapping threads for PN value read/writes, but I sometimes think it is overstated. It really depends on the application. 1 ms hit can mean a huge difference or nothing depends on the application. I have passed the references of waveform graphs to sub vis so that they can be updated while data is being acquired. I understand this is a very "Bad" practice, but as long as the performance meets the requirement, why it matters. It does simplify the coding.  

 

6) Yes, I should store the data in an constant array and wire directly. Thanks.   

 

7) On "closing reference", I thought I should only close the reference when it is not used anywhere in whole application.  

 

😎 On error handling, you are right again. 

 

9) I have fixed the two bugs in the attached.

 

I am not

 

0 Kudos
Message 18 of 23
(1,928 Views)

Sorry, press the "post" by mistake.

 

I guess I am trying to strike the balance between "good practice" and "get the job done fast". At the CLD exam, I hope I will not be penalized for some "get the job done fast" practice.

 

Thanks again for your comments.

 

 

Ian

0 Kudos
Message 19 of 23
(1,926 Views)

Hi Ian, thanks for your comments.


@Ian Ren wrote:

 

1) Your approach is "more scalable, maintainable and readable". However,  from you notes, I also noticed that it took you 3 hours 50 minutes to finish two of the sample exams. I do not know if I will be able to finish everything as neatly as yours in 4 hours. Using my "less scalable" approach, I am sure I can finish the job a lot faster. I attached the code with "added Wash Tires" operation, as you said, it takes a bit more than updating the cycle reference array, but I can implement othe mods in 5-10 minutes. (mods shown with red comment).


How long does it take you to complete the exam from scratch?

Including comprehension of the problem, designing, coding, testing, documentation etc...?

On average for the 3 projects I was able to design the code, get the main functionality down and tested in about ~ 3hrs.

The remainder of time was spend documenting the FP Objects Tip Strips and Description, and rehashing Block Diagram and VI Properties comments.

I also added in the requirement for Clean Shutdown on Error last.

I have not written an application in under 4 hrs in the real world and whilst I admit my times maybe a bit slow, I never felt under-the-pump to complete it (unlike the actual CLD).

 

You say 5 -10 minutes to make a change, but how long does it take for you to test and valid that change?

Using PN you would have to run the entire application.

I may be able to make the same change in <1 minute to my module, and be able to test and validate the code module quickly (by rerunning a test-VI) assuming the module has been designed with loose coupling and strong cohesion etc...

Of course 5-10 minutes vs 1 minutes is here nor there, but if you move away from this small application example and think of a much larger one, this difference will blow out exponentially. 

 

I also think rearranging then rewriting some code is not the best indication of an accurate time that it would take to complete the whole thing - the best way would be to actually do it then post your times.

I am pretty sure that I could have hacked a working solution in a much faster amount of time, but IMO I don't think that is the point of the exam (maybe I am wrong? - but the having the fastest time is not in the marking criteria, only finishing within the time-limit.

 


@Ian Ren wrote:

 

2) You are right that the bottom loop of the top-level does not "run" during a cycle. I usually overcome this by passing the references to the sub vi. I agree that your approach is neater, however, it is not always possible for many of real applications. As I said last time, my applications usually involve a lot of number crunching, which takes a few seconds to a few minutes. It is just not practical to sub-divide a task into less than 100 ms sub-vis and use the "software control timing". Usually, the user needs to 1) know the progress of the computation and 2) able to abort the operation. Both can be easily implemented from passing references to sub vis.

 

4) Usually I replace the UI element by constant while trying to verify the code.

 


 

I am not saying you have to sub-divide the tasks (i.e. logic) to compensate for the UI requirements. I am saying you should separate your logic from you UI. Otherwise you will never be able to test your code modules. So on a change to the application, if you cut and paste constants to replace PN then that is not manageable (maybe aside from the very first time, but this is a limited thought) and you can never rerun a test, as you would have to cut and paste manually each time. Aside from introducing human error and extra bugs, this would be impossible to test in a large application. You don't really want to be changing your logic (i.e. editing the code you are testing) to test it, you want to passing in different inputs to test it.

 

So IMO having PN in logic is not good - unless it is specific code encapsulating UI functionality (which requires a different form of testing).

 

Also in the Car Wash example the logic does not take longer than 100ms, so there is no reason for the UI to be unresponsive.

Therefore, waiting for the entire cycle to complete is not practical IMO and is a bad design choice.

Certified LabVIEW Architect * LabVIEW Champion
Message 20 of 23
(1,888 Views)