From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

fgv with two types of variables

Solved!
Go to solution
Solution
Accepted by topic author abenigma

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.

 

 

Download All
Message 11 of 26
(1,439 Views)

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?)

0 Kudos
Message 12 of 26
(1,428 Views)

@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)

0 Kudos
Message 13 of 26
(1,416 Views)

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.

0 Kudos
Message 14 of 26
(1,410 Views)

@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.

Message 15 of 26
(1,406 Views)

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).

0 Kudos
Message 16 of 26
(1,399 Views)

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).

 

  • Remember, you need to handle the situation where more data is requested than currently available, for example.
  • As I already mentioned, I really recommend wiring the array output also in the "set" case. It makes the code more useful.
  • Also note that you don't need to wire the size input of "array subset" if you want all data from the index to the end. Less code means less places for bugs to hide. 😉
0 Kudos
Message 17 of 26
(1,382 Views)

you were right about the element, sorry since i figured everything else was sort of basic (once again, my mistake).

 

  • i will change the labels where i can, it's a good practice to which i need to get used to.
  • i didn't use the array output in the "set" case simply because i will be handling that case only once (that's the plan for this specific FGV), also because (and i'm just saying) we were taught during classes that an FGV should have one set mode and one read mode, without mixing the two, if in all cases i would be able to get an output, wouldn't that make one redundant?
  • i am not taking into account the output size since the size itself would be fairly constant (depending on number of seconds and samples per second the FGV receives), the FGV would receive constant data over several minutes and only in specific cases i will be "taking data out" (when a timer has reached it's end goal after running a certian experiment routine). that is not to say that i don't understand why that would be needed. i'm guessing that placing it inside or outside the while loop makes little to no difference or am i wrong again?
  • missed the sentence that said it would give out the end index if i don't wire anything, thanks for that also 🙂

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?)

0 Kudos
Message 18 of 26
(1,379 Views)

@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?

 

 

0 Kudos
Message 19 of 26
(1,369 Views)

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.

0 Kudos
Message 20 of 26
(1,361 Views)