LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How to make a value non-volatile?

I searched a little bit but I didn't really come up with much. And since this is a generic and broad question, I'm not going to post any code.

 

But basically I have a remote client that connects to a compactRIO. That remote client will send a string value to the compactRIO. I want that string value to stay the same unless the user changes it at some point on the remote client.

 

What I'm noticing is that when I close out the remote client app, the value is no longer what the user had set it to when they last had it open. And I don't know what would happen if the cRIO was power cycled without the remote client app connected. It would probably be pretty confused since no data is being sent and it also didn't retain the last data that was received.

 

Can anyone point me in the right direction to solve this? Thanks

0 Kudos
Message 1 of 8
(1,422 Views)

Well for starters, it seems clear that this will have to be handled on the cRIO side, not the client side...

 

(Sorry, I don't have experience with cRIO to be more specific about non-volatile storage options).

 

 

-Kevin P

ALERT! LabVIEW's subscription-only policy came to an end (finally!). Unfortunately, pricing favors the captured and committed over new adopters -- so tread carefully.
0 Kudos
Message 2 of 8
(1,416 Views)

@David99999 wrote:

What I'm noticing is that when I close out the remote client app, the value is no longer what the user had set it to when they last had it open.


How exactly do you know what the "values" is and what else has access to that value? (for example do you notice the value changed when the client disconnects or only once the client reconnects? Could it be the client has some initialization code that reset is on reconnect?)

 

How do the two side communicate values? There are so many possibilities!

 

To make it persistent on the cRIO, you need to write it to e.g. a local ini file that gets read on startup. (with proper default handling if the file is missing)

0 Kudos
Message 3 of 8
(1,410 Views)

@altenbach wrote:

How do the two side communicate values? There are so many possibilities!


As always, it seems, I should have provided more details 😁

 

The two sides are communicating via TCP. Server on the cRIO side.

 


@altenbach wrote:

How exactly do you know what the "values" is and what else has access to that value? (for example do you notice the value changed when the client disconnects or only once the client reconnects? Could it be the client has some initialization code that reset is on reconnect?)


That's actually a good question, and has revealed something obvious that I didn't notice. My cRIO may actually be completely losing the value when the remote client disconnects. The reason I say that is.....I'm just continuously sending those values to the cRIO via TCP connection. Actually no, I just realized that when my remote client is not connected then my TCP server loop errors out with error 56(?) because the listener didn't detect a connection. Which means the values I'm setting don't get scanned. I'll have to do look into that.

 


@altenbach wrote:

To make it persistent on the cRIO, you need to write it to e.g. a local ini file that gets read on startup. (with proper default handling if the file is missing)


Ok, I'm familiar with using an ini file since I've already got one on this cRIO. But is that really the best or only way? Because if that's the case, every time the user changes the value on the remote client side, I'm going to have to detect a change in the value and then open up the ini file then change it there and then close it.

 

I dunno....maybe I need to open the ini file once every minute and read the values from it. And then when I've detected a change in value I open up the ini file and make the change and then it can continue reading from it once a minute?

0 Kudos
Message 4 of 8
(1,376 Views)

Ok, I'm familiar with using an ini file since I've already got one on this cRIO. But is that really the best or only way? Because if that's the case, every time the user changes the value on the remote client side, I'm going to have to detect a change in the value and then open up the ini file then change it there and then close it.

 

I dunno....maybe I need to open the ini file once every minute and read the values from it. And then when I've detected a change in value I open up the ini file and make the change and then it can continue reading from it once a minute?


No, you would not have to open file each time. Open the file at the startup and write it at, say when error 56 is seen or if loosing power is a possibility then write it periodically, every so minutes. When you open the file keep its reference alive to be used at later parts of your sequence. I use an FGV or a global (on PC side) to store all the values of interest. So at startup read and "SET " values in a FGV or global and when you need to write values to file, "GET" values from FGV or Global.

 

 

EDIT: Just read @altenbach 's important note on missing file. I usually do a check for missing file, if not found, create one with some default values stored as constant, if needed. I believe

what @altenbach suggested is one of the neat solution to meet your needs. I also am using something like this and it is easily expandable and easy to manage.

 

Hope it is useful.

0 Kudos
Message 5 of 8
(1,370 Views)

@XM43 wrote:

Ok, I'm familiar with using an ini file since I've already got one on this cRIO. But is that really the best or only way? Because if that's the case, every time the user changes the value on the remote client side, I'm going to have to detect a change in the value and then open up the ini file then change it there and then close it.

 

I dunno....maybe I need to open the ini file once every minute and read the values from it. And then when I've detected a change in value I open up the ini file and make the change and then it can continue reading from it once a minute?


No, you would not have to open file each time. Open the file at the startup and write it at, say when error 56 is seen or if loosing power is a possibility then write it periodically, every so minutes. When you open the file keep its reference alive to be used at later parts of your sequence. I use an FGV or a global (on PC side) to store all the values of interest. So at startup read and "SET " values in a FGV or global and when you need to write values to file, "GET" values from FGV or Global.

 

 

EDIT: Just read @altenbach 's important note on missing file. I usually do a check for missing file, if not found, create one with some default values stored as constant, if needed. I believe

what @altenbach suggested is one of the neat solution to meet your needs. I also am using something like this and it is easily expandable and easy to manage.

 

Hope it is useful.


Ok, I don't QUITE get what you're saying but I haven't had time to really think about what you're saying. I need to look up what FGV is. 

 

But regardless, your idea still works if the user can change values on the client side at any point in time? The cRIO system will continuously run, might as well say forever. The client application might not. So at any point the user may need to come in and say "hey I need to change this to this" while everything is running, and start up the remote client to make the change.

0 Kudos
Message 6 of 8
(1,340 Views)

Ok, I don't QUITE get what you're saying but I haven't had time to really think about what you're saying. I need to look up what FGV is. 

 

But regardless, your idea still works if the user can change values on the client side at any point in time? The cRIO system will continuously run, might as well say forever. The client application might not. So at any point the user may need to come in and say "hey I need to change this to this" while everything is running, and start up the remote client to make the change


FGV, an acronym for Funcitonal Global Variable. In a nutshell, you store values in shift registers and read from them when needed. Read more about them in the inserted link. 

 

In your case I would imagine it would have to be a cluster of information stored in an FGV. So yes, it will work if user make changes on the Client Side and you send that value to cRIO side and it is updated in the cluster in the FGV. This is assuming that you have connection established between Client and cRIO to transfer information in between.

 

You have to be careful in the implementation to make sure that there is no race condition taking place. Simply put, reading and writing at the same time. You would not get reliable data if that happens.

 

 

0 Kudos
Message 7 of 8
(1,310 Views)

Your comments are a bit unclear but if I understand correctly what might happen is that your TCP Server tries to receive values from the client and if the client is connected and sends those values all is peachy. But if that client dies or has some other communication error you do error out but still overwrite the setting with an empty string. You have of course to make sure that you only overwrite that setting (global variable, FGV or some tag engine value) when you have successfully received a value from the client.

 

Otherwise you need to do some error indication. That could be to set a different variable to indicate that the communication has been lost and your cRIO device now operates in disconnected mode, with probably the last valid received value. But don't update the value itself unless your system has some security implications that could cause loss of resources or even worse human health if it continues to operate while disconneced.

 

As to make your value persistent when your application or controller restarts: Whenever you receive a valid value from the client, write the value also into your ini file. On starting you can read that value back and store a default value if it doesn't yet exist in the ini file.

 

If you create a FGV you can put this all nicely into this VI. Have an "Init" case that reads the value from the ini file, a "Write" case that updates the value when you receive a valid one from the client and also stores it in the ini file and a "Read" case that you can use to read the current value for use anywhere in your application. You can easily make the write to the ini file inside the FGV conditional by detecting if the new incoming value is different to the already stored value and only write to the ini file if there is a change between the two.

 

One caveat about FGVs, try to avoid a Read-Modify-Write sequence at all costs. This is a very easy way to introduce race conditions. You should never do a modify of the stored value by first reading it, do something with it and then writing it back, but always integrate the modification into the FGV itself as a separate case method.

Rolf Kalbermatter
My Blog
0 Kudos
Message 8 of 8
(1,304 Views)