09-30-2020 01:36 PM
We are using an uninitialized shift register that holds the I2C or SPI configuration for manual navigation through the communication state machine: init, write, read,get DataA, DataB, close...etc. For SPI after init the config is loaded into memory and the values are persistent in the LabVIEW context via the uninitialized shift register. No issues on SPI. But for I2C when VI finishes running the I2C config reference is still open and valid but the address property is reset to 0 on VI exit. This makes us always rewrite the I2C address into the address property if we exit VI. Is there a reason why this this address property is not persistent between runs like the SPI properties and other I2C properties are? As far as I have seen it seem unique to the address property the other properties maintain state like address size, pull up enable etc. Maybe the thought is you will always use the 0 broadcast address when starting comms? On VI exit event forcing this to 0 as a feature.
09-30-2020 08:09 PM
Need to see code to say for sure, but this points toward you are using a tunnel set to "Use Default If Unwired" and you did not wire up the reference when you need to.
09-30-2020 11:06 PM
10-01-2020 07:25 PM - edited 10-01-2020 07:30 PM
Exit? flag reports the values pre and post state
REF is the ref cast as U64,
The top run does not initialize the ADDR, SIZE, RATE on every run.
Whereas the bottom picture reloads the properties on every run.
It appears that the property values are reset back to defaults when the VI terminates and does not save the state. Also, it all the properties are reset as the rate goes back to 100.
132 from the read data is the expected value from the Ï2C device. If the read is successful it just keeps reading.... If there is an error the state goes to close then back to init. The I2C config reference is always the same so it is not pointing to a null reference or uninitialized reference.
10-02-2020 06:58 AM
Since you are using an enum for your state, do not have a case that has "Default". Because right now if you do a "Write", you are actually calling the "Init" case.
@az_ltr wrote:
It appears that the property values are reset back to defaults when the VI terminates and does not save the state..
Why are you aborting your VI? Why aren't you calling the "Close" case. When you abort your VI, all of your references are now invalid. You need to cleanly stop your VI. This is typically done with a stop button. When the button is pressed, call the "Close" state and stop your loop.
10-02-2020 01:01 PM
Understand on the default, but not taking it for this test case.
There are of course many ways to do things. In this case the init run close is not consecutively run but the state is maintained in the context between runs. We end up manually driving at this level when debugging or for quick readings. Also, some users like the simplicity of set run read sequence when driving at this level.
References do not go null when your VI loses scope if they are in a Data structure that is in the LabVIEW context like a uninitialized shift register or project global, FGV etc...And in this case the reference does not go null but does reset its properties. The SPI Config ref does not do this. It seems to me that the I2C driver registers for an event on LV not running and resets its properties but it does not null out the reference.
I agree this use case is fairly specific and there are clearly work arounds and different implementations. But consider Let's say I used the .net implementation of this driver and called it from LabVIEW then the reference to the DLL would not change on LabVIEW state. I know what your thinking...Doc it hurts when I do this...right? But I think reference parameters should not reset on LabVIEW application state exit if they have not left LabVIEW context.
10-02-2020 07:43 PM
@az_ltr wrote:
But I think reference parameters should not reset on LabVIEW application state exit if they have not left LabVIEW context.
But when you abort a VI, you are exiting the application context of the project. Again, YOU SHOULD NOT BE USING THE ABORT BUTTON. It is only there for debug purposes. You need to properly allow the user to control the state and close the VI/application without suddenly running the VI into a brick wall.
10-02-2020 07:51 PM - edited 10-02-2020 07:53 PM
10-03-2020 08:19 AM
@az_ltr wrote:
Not using the abort button. The VI runs and terminates normally. In fact probably not fast enough to use the abort button. Never mentioned the abort button.
Ok, my bad. I saw a constant wired to the Conditional Loop Terminal and thought "Endless Loop".
But still, you are not using a proper structure for this. If you really just want the user to occasionally do a write/read, then use an Event Structure inside of a While Loop. You can initialize the device before the loop and close it after the loop. Then you can use a button's value change event to trigger when to do your query. Likewise, use a stop button's value change event to stop the loop. This way, the VI is constantly in a running state and your references are safe from automatic cleanup.
10-03-2020 08:42 AM - edited 10-03-2020 08:42 AM
I just rewrote your VI to use an Event Structure instead. I am initializing before the loop, using an event to perform a read, and another event to close all of the references and stop the VI.