07-28-2017 11:01 AM
I have written a VI for a syringe pump that controls aspiration and dispense.
Along with the control, I would also like to record total aspiration and dispense volume and I got that done using a while loop.
My problem is in the case of error, in which dispense volume is larger than aspiration volume.
The hardware is programmed that if the dispense volume (V_dis) is bigger than aspiration volume (V_asp), it does nothing.
I want to reflect that on my VI as well that if V_dis is larger than V_asp, the total dispense volume does not change.
The case structure (under "dispense" case and outside the subVI for dispense) for this particular condition works well, but there is some case in which it does not work and return some random value.
It is in this scenario that it does not work:
1) Aspirate 1mL.
2) Dispense 0.2mL for 5 times.
3) Dispense 0.2mL for 6th time and the number does not change (functioning well as I intended).
4) Aspirate 0.2mL.
5) Dispense 0.1mL for twice. <- Problem in second dispense.
It works well until the first dispense of 0.1mL in step #5, but not for the second dispense.
After the first dispense, V_asp = 1.2mL and V_disp = -1.1mL. So V_asp > V_disp and the case should let the syringe dispense 0.1mL.
However, it does not dispense and stay at that status.
I set up the probes to see where it was going wrong and found that after going through comparison, it give a random number.
I am attaching my VI, so please take a look at it and leave a comment if any of my explanations does not make sense, for I know this is a weird case where it works fine except for one particular set of numbers.
Thanks.
07-28-2017 11:07 AM
I am installing software and can not look at the code but I will offer a first question...
Are you doing comparisons where you expect a floating point number to be exactly equal or such?
the number "0.1" can NOT be represented in binary so exact compares will fail.
Ben
07-28-2017 11:21 AM
So, I tried to multiply the comparing numbers by 100 or 1000, but still gave some random numbers.
And the format of numbers I am comparing is DBL.
07-28-2017 11:28 AM
100 X 0.01 = 1
on paper but not in a computer.
What you get is;
100 X (something note equal to 0.01 ) = not 1
Ben
07-28-2017 11:30 AM - edited 07-28-2017 11:33 AM
I am not following this.
I multiply each number before comparing them.
And it works well if I do Steps #4 and #5 before doing steps #1-3.
So I guess the problem is not on comparison?
Also, if what you are thinking is the right problem, what would be the solution?
07-28-2017 11:36 AM
Maybe these will shed some light on the subject
Comparing Floating-Point Numbers
Comparing Floating Points Does Not Seem to be Working Properly
An Introduction to Floating-Point Behavior in LabVIEW
07-28-2017 11:39 AM
Do the following;
1) Drop a DBL control on a front panel.
2) Enter "0.1"
3) pop-up and change the precision of the display to 14 digits or so.
4) Inspect the number you see displayed.
I the same way that 1/3 can not be represented in decimal, 0.1 can not be represented in binary.
You have recognize the limitation of binary and code accordingly and never expect that math will be exact but rather close. There is a constant on the numeric palette "epsilon" that will show you what the precision of your machine is.
Ben
07-28-2017 11:43 AM
You're missing the point of multiplying. You need to multiply, and then either round it to a whole number or convert its datatype to an integer, THEN do the comparison. If you look you'll probably find that you're comparing 100.000000000000001 to 99.9999999999999999997 or something.
07-28-2017 01:30 PM
Comparison or not, your code is a complete mess and will probably not work as desired. For exzample, you are setting certain hidden boolean controls to TRUE (one via a local variable, one via a value property node), while their terminal is outside the loop and will never get read again by the code while the loop is running. The boolean wire inside the loop will always reflect the initial values. Think dataflow! This entire thing is way too convoluted to troubleshoot. All you probably need to do the same thing is some simple code the size of a postcard. Try it!
(As a first step, eliminate the hidden booleans and use shift registers instead. Then also eliminate the stacked sequence.)