08-31-2013 11:51 AM - edited 08-31-2013 11:58 AM
The code by aputman is not good, because it is not predictable. It is a bad idea to change global functionality on first call. What if the first call is a "set" operation? The first array element would be lost forever and the calling code would not know about it.
All the "first call?" primitive needs to do is initialize on first call, then proceed with the requested operation (set or get)!
I would also recommend to output the appended array even during the "set" operation. Sometimes you want the new data immediately and this eliminates a second call.
As I already mentioned, a globally initialized shift register is the better choice here, because it includes the "first call?" functionality as well as eliminating the while loop, thus dramatically simplifying the code (bottom in image).
Anyway, attached are two possible implementations. Modify as needed.
abenigma wrote:
please bother to read the entire message and not just take a look at the picture.
OK, I haven't read your post here until now, but it deserves some comments. At this stage of your learning curved it is ill advised to play the smart a$$. It looks silly, especially if you re-read your comments a few months from now once you have more experience. 😮
abenigma wrote:as i already wrote, this will be a subVI and i need the boolean value to be read every time (the boolean itself isn't "near" and it doesn't look good if i wire it directly, i might be wrong, but this is the way i want it for now).
In a few months your aesthetic values will hopefully change and using a control reference in this way will look far worse to you. On a properly modularized and architected diagram, nothing is "not near". If things are far apart, your diagram is too big. First of all, property nodes execute synchronously, and are thus orders of magnitude more expensive. Some property nodes force the front panel to be loaded in memory, adding additional strain to the system. You also open yourself up to race conditions, for example what would happen if the boolean changes right after you call the subVI, but before the property is read? Also, using control reference this way prevents you from running the subVI standalone for debugging purposes, something you should definitely be able to do at this stage.
abenigma wrote:i know that the shift register needs to be uninitialized, that's what i wrote, i also wrote that if i disconnect, the wired become black (which is to my understanding means that labview doesn't recognize the data type of the wire).
Well, if you "know" that something is not right, but then attach a picture that shows the wrong thing, you are sending mixed messages. In fact in my first reply I suggested to use a globally initialized feedback node to exactly mitigate that problem. For some reason you ignored my advice. Let me use your words: "please bother to read the entire message". 😉
abenigma wrote:p.s. if i initialize inside (3rd state), from the way i understand, i would have leading zeros in my data arrays which i definitelly don't want/need.
Obviously, you understand wrong. If you look at the arrays, you notice that the first element is greyed out, meaning the the arrays in the diagram constant are empty. I recommend that you go over some of the online tutorials to become more familiar with LabVIEW in general before attempting any more complicated project.
08-31-2013 12:23 PM - edited 08-31-2013 12:34 PM
Thanks for the advice, duly noted.
Since this is a part of a course we are taking, according to the lecturer, we have already been taught all we need to accomplish the task, that's why I stuck to exactly what I was told/needed.
I'm afraid that my lecturer wouldn't accept the FB node solution since it it something he hasn't taught us...
Once again thanks, and it will probably be a long time before I use labview again after this project is done 🙂 (our lab works with other software or uses external people to write specific software for our test machines).
P.S.. After taking a good hard look at the FB node (which looks much less cumbersome BTW), I imagine that it work in pretty much the same way as a shift register? (in terms of data being transferred between two calls of a loop?)
08-31-2013 01:01 PM
@abenigma wrote:
P.S.. After taking a good hard look at the FB node (which looks much less cumbersome BTW), I imagine that it work in pretty much the same way as a shift register? (in terms of data being transferred between two calls of a loop?)
Yes, a feedback node works pretty much the same, but is a more recent addition to LabVIEW and in cases like this, much more elegant. Here it is globally initialized, a functionality that does not exist for shift registers (which always require a loop, even if it does not iterate as in this case).
A feedback node can be configured to give one earlier history value (n-1, n-2, etc.), but a shift register can be resized to give multiple histories at once.
It ia great to have both!
(While you are at it, you should also remove the "accepted solution" tag from this post, because the solution is wrong as already explained. Future users of the forum should be guided to the correct solution instead)
08-31-2013 01:20 PM
Done (thanks for reminding me).
While I am at it (as already noted), I will ask another question (hope this doesn't make the thread look like a lesson too much), in this specific case, if I use a SR and a FBN, will I be able to dynamically set how many last/previous values I would like to read? (that would reduce a whole procedure from one of the uses for this FGV).
I've already seen the FBN appear when I used the "has time elapsed" true/false output as a "reset" activator for the time elapsed express function, just didn't know what it was since it was the first time I've seen it.
08-31-2013 01:37 PM
@abenigma wrote:
will I be able to dynamically set how many last/previous values I would like to read? (that would reduce a whole procedure from one of the uses for this FGV).
You can add another control for "output size" and insert an array subset right before the output terminal. You need to calculate the start index from the current array size in the feedback node and the value of the "output size" input. SImple math! 😉
Also be aware that the current FGV memory use grows without bounds and you computer will run out of memory eventually (depending of the set rate). If you want to keep a fixed sized history only (e.g. the last 1000 points), you can implement it as a fixed size history buffer that will be much more memory efficient and elegant.
08-31-2013 02:55 PM
wow, thanks a lot! sorry for the rudeness earlier, i guess that was mostly frustration talking from within (After spending too much time on this as it is).
that really does make life easier in this project.
i'll attach what i have up to this point for your comments (if that's not too much to ask).
a few notes, i'm not sure if i can limit buffer size since the FGV acts as data accumulation for acquired signal from a physical device (connected to a myDAQ if it's relevant) and in theory, i'm suppose to allow it to run like a scope so maybe a big limitation, something in the area of 50000 datapoints would be ok since i'm producing 10-100 samples entries/sec.
also i can't find part of the elements you used in your diagram (understanding how little we were explained in everything related i am trying to read about what i'm using as much as possible).
after looking a little bit for some type of "end" index (like matlab uses) the workaround for that is also there, all of this is since i'll always be wanting to get the last N elements of that array so i need to know the last index and how many "backwards" points is a given.
is this ok that i'm posting all these questions here or maybe i need to open another topic? (i'm almost sure i'm pretty much done with this matter but i'd love to pick your brain about other things if possible).
08-31-2013 07:46 PM
abenigma wrote:also i can't find part of the elements you used in your diagram (understanding how little we were explained in everything related i am trying to read about what i'm using as much as possible).
Well, it is difficult to tell when you are not telling us what elements you could not find. I assume the in place element structure.
Take advatage of labels and add descriptive labels immediately after adding any control or indicator (numeric, boolean, numeric 2 and enum are too generic to be useful) Also make sure to label the elements of the cluster constant so you can use bundle/unbundle by name for self-documenting code.
Here's what I would do (see attached).
08-31-2013 08:11 PM
you were right about the element, sorry since i figured everything else was sort of basic (once again, my mistake).
btw, not wanting to be a smart a$$ (again), but you wired the index without a decrement, was that an honest mistake or am i getting something wrong? (the way i understood indexes in labview is that they start at 0 but an array of size 3 would have last element with an index of 2, is that correct?)
08-31-2013 09:40 PM
@abenigma wrote:
btw, not wanting to be a smart a$$ (again), but you wired the index without a decrement, was that an honest mistake or am i getting something wrong? (the way i understood indexes in labview is that they start at 0 but an array of size 3 would have last element with an index of 2, is that correct?)
Well, instead of straining the brain and overthinking things, just do the experiment as in the attached example!
You will see that my code behaves correctly. Agree?
09-01-2013 05:29 AM
this is sort of funny because i built my own test VI and they are almost the same :)) (didn't see that there was an attached file at first)
this is confusing, because when i call an array element with a specific index it's "decremented" and when i call a subset it's not... oh well... another thing to remember...
thanks for all your help.