The code looks good with respect to sync and timing dependency issues. I have just one suggestion which isn't *necessary* for this app, but I'd recommend it as a good habit.
In your AI call to DAQmx Read, I'd wire in the # samples to read rather than leaving it unwired. Unwired will use the default value of -1, which carries the special meaning, "read all available samples from the buffer (that haven't previously been read already". In this particular app, the finite pulse train and your sequencing controls the # samples so you'll end up getting the correct #. But I find it helpful to wire in values explicitly to make sure I pause and think about what behavior I really want.
One common AI DAQ pattern is to call DAQmx Read in a loop. Wiring in a # samples will act to control the iteration timing of the loop. Leaving it unwired allows the loop to iterate as fast as the other code in the loop can stand for. A common mistake found in postings here are when people leave the # samples value unwired in the loop. As a result, the loop iterates as fast as it can, and may sometimes find 0 available new samples to read, leading to various kinds of data problems.
So I think it's best to make the habit of wiring a value explicitly, even if the value you wire is the default value -1.
Thanks for the reply. I just saw now that you actually answered to my last post.
In the actual program there is no AI function. I just put it here as a test. I first apply and then directly read the applied voltages. I understand your point though and will try to remember it next time I actually use an AI function 🙂