12-27-2016 11:07 AM
Because your For Loop is occurring in the same loop as the main line of code that does the writing. The master loop doesn't iterate until all code inside of it has completed. (Basic rules of dataflow in LabVIEW). So your inner For Loop must complete its 6 iterations before the master while loop comes around, reads Data to Write again (which will only have the last data) and executes that. If you want to write 6 data items in a row, then include that in the main line of code.
Don't try to parallelize something that shouldn't be in parallel. You are dealing with a single CAN resource so anything working with that should be done in series. But you actuallay failed to parallelize it because you put it in the same loop.
12-27-2016 03:11 PM
If i still May ask, what is the best practice in my VI if i want to implement time related functions?
I used a separate while loop for my first time-related function, frequently checking the values from all sensors.
The time interval is a lot bigger then that of the CAN while loop, seconds vs. milliseconds. Wouldn't the timer with the bigger interval not prevent the timer with the smaller interval to stop the CAN while loop, if i had placed the sensor function in the CAN loop?
I have more functions (ex. touch dimmer) to code that are time depended, where would I best place them?
12-27-2016 04:13 PM
Don't think of using timers that take a long time and prevent other code from running. Use things like the Elapsed Time Express VI which let's you check if a certain amount of time has passed. If it has, then execute more commands in a case structure. If it hasn't the False case passes through reference and error wires onto other parts of the code that do their thing.
01-07-2017 02:21 PM
Is it possible to reset the elapsed timer while it is running?
I tried it in several ways but the vi doesn't reset while it's counting the time.
It should reset every time the pir sensor function is called.
01-07-2017 04:00 PM
To reset an Elapsed Time Timer, just send a True into its Reset input.
I'm a bit worried about your architecture. There are a lot of sequence structures that are unnecessary, and a lot of local variables. The way there are a lot of parallel case structures each operating on an individual boolean. To me that looks like you should have an event structure in your code where each event handles the true case for one of the buttons.
01-09-2017 01:41 AM
I thought about your remark ‘There are a lot of sequence structures that are unnecessary, and a lot of local variables.’ I don’t see that can cause a lot of parallel cases. I made the program so only one CAN message is been handled at once, am I wrong that this is excluding any chance of parallel operating cases, except for the timed ones of course.
I am not very sure about what you exactly mean , yes I do use a lot of local variables but when I need to save the last value of message, how can I not use a local value then. I used one for every case when I needed a Boolean that acts like a latch. Perhaps I am missing a big concept of labview programming, please advice.
I would like my program not to stop when I unplug the usb plug from the CAN module, so I made the VI not to handle errors automatically. Besides that I putted the CAN configuration in a case structure so it will be possible to call the configuration in case of an error. I noticed that this configuration is also called every time the vi is started.
The code of the error is ‘1074388957’, so I would like to sponge away this error and let the program try to configure CAN again, until the usb is plugged in again. It would be even nicer if a message is been shown (Simple Error Handler VI), and when the user presses ok, the program try to configure the CAN module again.
01-09-2017 09:32 AM
Are you sure? What happens if you have two booleans true at the same time?
There are way too many embedded structures, and case structures that do the same thing in each case. If you are writing a True to something whether the case structure is True or False, then you don't need to put that in both cases. Just put it outside the case structure.
Needing to use local variables to reset a boolean that would otherwise be a latched boolean isn't the big problem. If that is what you need to do, then do it. But it is still an indication of a problem of the overall architecture. What is worse is having something like Data to Wire being written to in mulitple difference parallel case structures. That leads to race conditions. Which one wins if they all execute?
And the fact that you are trying to creating an event driven architecture without using an event structure, or perhaps a Producer/Consumer (Events) architecture is a very unmaintainable VI you have there. It feels hacked together. For instance, you are writing Data To Write in multiple places, but that never really gets written until the next iteration, and if you happen to also force another boolean to be true. And that only gets written assuming that a race condition elsewhere didn't happen to stick different data in.
Overall, what you have is very fragile and even if you think it is working for you now, it is eventually going to fall apart when you need to add more features to it. Overuse of sequence structures and local variables are at the minimum a symptom of a problem architecture, but are also usually the problems.
If you have an error you want to clear, then use Clear Specific Error.
01-19-2017 01:13 AM
I made some changes to avoid race conditions and also tryed to follow your advice to avoid writing the same code in several sequences.
Now i am really struggling with a funtion to compare a timestamp with the current time.
I unbundled both so i can compare the hours and minutes but this doesn't seem to work.
I'm out of options and time, please advice.
01-19-2017 08:10 AM
In what way doesn't that work?
It looks like if the hour and minute of the two are the same, then the boolean lights up. Beyond that I'm not sure what you are trying to do. You have an event structure in there which means the comparison happens and it won't move to the next frame of that sequence structure until one of the events you have in the event structure has happened.
01-19-2017 09:52 AM
When one of the timestamps in the timestamps array is the same as the current time.
Then the event structure should do its thing, preparing the array so a message can be send.
I chose for an event structure because this will only run the code inside of it only once when a value change happend.
Still i'm not sure what that means because there is a change at the rising edge but also on the falling edge.
Besides that when a timestamp is equal, then it will be so for a whole minute, what should i do to avoid running the code thousends of time?
In short when one of the timestamps compares with the current time then the data in the lights array with the same index of the timestamps should be send, is the function lights ON then the second byte in the array is 1, otherwise it is 0(check if index is even). Only the first byte needs to be changed (the number of the particular light). When the for loop has done its thing then a 3 by 8 array should be passed to 'data to write' and the squence should go on.
While there is no timestamp equal to the current time the loop should, every 10ms, compare one of the timestamps from the timestamps array with the current time(icrement index). The whole loop can only work when sequence is 1.