Zeroing the axes.
When the system is started up, the actuator could be in any position. That is why it first needs to be zeroed out.
The main program has this little snippet:
When the zero A button is pressed (on the left), the "control stepper" subroutine is given the command to keep going until the pillar is at zero position. Then the pillarA counter is set to zero.
At the start of the program, the pillarA counter is set to -1 and the zeroA button is set programmatically, so that immediately, the system goes to the zero position. When the position is at -1, the system knows not to try to adjust anything automatically based on the angle program (from the program.csv file), but wait for a rezero-ing to happen first, otherwise things may break.
At any point in time, the user can zero the system by pressing the zero A button. But the user should not have to get involved.
The same code is of course used for pillarB, so I won't repeat that.
Determining which program point should be active
In order to determine which program point is now active, the program data is read, and the current time is sampled.
Then it is determined which time stamps have NOT been done yet, and the first of those timestamps is selected by going back one step. The GUI is updated, and the new pillar data is updated.
The picture above should give you a better idea. The current time is shown, and the program has determined that all the datapoints with a time earlier than the current time have been done. The active entry is 2, and its target positions are 2000 and 700 for pillar A and B respectively.
Driving the motors to get on target
The pillar A and pillar B targets which were generated in the previously discussed block are used to drive the motors to the correct positions:
If the "zeroA" function is not active of course. We don't want zeroing and driving the motor to the programmed position to be active at the same time!
This bit of code should be easy to understand: if the target value is unequal to the position, the loop is activated. If the target value is larger than the position value, then the stepper motor is extended, and otherwise retracted. The pillarA position is of course updated.
Needless to say, the same code is repeated for the pillar B, and I won't repeat that again.
So I've discussed all the program features!
1) upon startup, zero the pillar A and pillar B by extending until the limit switches are activated. This will reset the position counter.
2) upon startup, the program is also loaded, from a CSV file.
When the program runs:
3) from the program data, the active program entry is determined and the targets updated
4) the targets are compared hundreds of time per second with the actual position and the position is automatically updated.
It does require the user to set the appropriate targets. This can be done by controlling the actuator positions within the program, and writing down in the CSV file what the position should be at what time of the day.
This is what the program GUI looks like just after startup. Both zeroA and zeroB are active, although zeroB waits for zeroA to finish before zeroing - to ensure minimal interference.
After zeroing, the pillar A at Zero Pos will momentarily be lit, but immediately, the program is analysed, the active entry determined, and the pillar A and pillar B targets determined. Here also, pillar B waits for pillar A to finish moving.