This section will discuss
the issues that related to controlling the tracker and how they were
resolved. These are issues that aside
from the actual tracking of the heat/light source.
The first action that must be taken is to find and set the range of the A/D converter. This was accomplished by the following code:
status =
ADC.find(255);
status used for error checking . . .
ADC.SetRange(4.096);
Where ADC.find() returns the address of the parallel port (0x378) and ADC.SetRange() sets the reference voltage of the A/D converter. The A/D converter is 12 bit, so the range results in a resolution of 1mV.
The main loop will run continuously until the tracker is turned off or it travels out of its range and trips one of the limit switches. The loop needed to be paused because the keypad on the tracker latches and if the software keeps reading the input channel the tracker would keep repeating the same procedure over and over again. A loop to check for a different voltage from the keypad or an interrupt from the computer kept the main loop from repeating uncontrolled. See flowchart in appendix A.
kb_input
= ADC.ReadChan(4); kb_check
= kb_input; while(kb_check <= (kb_input+0.100) &&
kb_check >= (kb_input-0.100)) {
if(kbhit() != 0) {
count = find_angle(count); } kb_check = kb_input;
kb_input = ADC.ReadChan(4); }
The shutdown function will set the digital output for the motor step low and the rest of the pins high so that the motor will not move and that none of the other pins are receiving a random signal. The program then remains in a similar loop that is used in the main function to hold the program in the emergency shutdown condition, which will exit when a new button is pressed on the tracker. The program will then finish its current operation before continuing with the operation of the new button pressed. For example if the tracker is going to center and emergency shutdown is pressed the tracker head will stop immediately. If the initialize button is then pressed the tracker head will continue to the center before initializing. See flowchart in appendix A.
ADC.setDIO(0,0);
ADC.setDIO(1,1);
ADC.setDIO(2,1);
ADC.setDIO(3,1);
ADC.setDIO(4,1); ADC.setDIO(5,1);
ADC.setDIO(6,1);
ADC.setDIO(7,1); kb_input
= ADC.ReadChan(4); kb_check
= kb_input; while(kb_check <= (kb_input+0.100)
&& kb_check >= (kb_input-0.100)) { kb_check
= kb_input; kb_input
= ADC.ReadChan(4); }
The
function steps the motor back to the reference point. The optical sensor that
the blade passes through returns a voltage. The voltage to stop and initialize
at was chosen to be 2.5 Volts as using the maximum voltage would be unreliable.
The sensor will always let a little light to seep in even if the blade is
completely covering the sensor. See flowchart in appendix A.
Once the reference has been established the tracker backs off by one degree (8 steps of the motor). This will protect the tracker from going out of range if the initialize button is pressed again.
When tracking in the horizontal plane the altitude axis is also initialized in the same manner and then steps away from the reference 330 steps so that the tracker head is level in the horizontal plane. When tracking in both dimensions the altitude axis is initialized to the row number that the tracker will begin searching for the heat/light source.
for(count=0;count<=8;count++) { ADC.setDIO(0,0); delay(2); ADC.setDIO(0,1); //step motor delay(2); ADC.setDIO(0,0); }
The find center function will take in the current position of the tracker head, decide if it is right or left of the center and then move in the proper direction to center. During execution the function must keep track of the step count relative to the reference. See flowchart in appendix A.
|
Both of these functions take in the direction to step the motor and then issue a pulse to the motor. For both motors issuing the number 1 sets the direction towards the reference sensor and 0 sets the direction away the reference sensor. The delayed step function issues the same pulse but delays between line commands to slow the pulse down for the physical limitations of the motor.
This function takes in a letter as an argument and sets the multiplexor to the corresponding sensor channel so that the voltage can be read.
if(letter == 'a') { ADC.setDIO(3,1); ADC.setDIO(4,1); ADC.setDIO(5,1); }
Checking For Emergency Shutdown
In all of the functions the keypad input channel must constantly be polled to check if the emergency stop button has been pressed. If the emergency button is pressed the program calls the shutdown function. In all of the loops the following code is included:
emergency = ADC.ReadChan(4); if(emergency >= 0 && emergency <
0.5) { shutdown(); }
Signal Error
When
polling the keypad input channel the program has to check between a range of
voltages as the signal may fluctuate or have noise on it. The tracker
specifications require an allowance of ± 100mV. An example of how that is
accomplished is as follows.
else if(kb_input >= 0.90 && kb_input
<= 1.10)
Position of Tracker Head
The step count used throughout the program is derived from the specifications of each Stepper motor.
Azimuth motor
The specification states that the motor travels 2 degrees per step and has the ability to make 16 micro steps per step. This gives a total of 584 steps for the total 73-degree range of the tracker. One degree of movement requires 8 micro steps of the motor.
detector arrays 584 steps 292 steps 0 steps
![]()

Top down view of tracker head
Altitude motor
The specification states that the motor travels 1.8 degrees per step and has the ability to make 16 micro steps per step. This gives a total of 500 steps for the total 56-degree range of the tracker. One degree of movement requires approximately 9 micro steps of the motor (8.8 micro steps exactly but motor cannot step fractionally).
500 steps
300 steps
0 steps
![]()
![]()

Side view of tracker head
Random Operation at Startup
When the program is first started all of the output pins are sent high so as not to send random signals and adversely affecting the tracker before the system is initialized.
ADC.setDIO(0,1); ADC.setDIO(1,1); ADC.setDIO(2,1); ADC.setDIO(3,1); ADC.setDIO(4,1); ADC.setDIO(5,1); ADC.setDIO(6,1); ADC.setDIO(7,1);
Target and track function
This is the controlling function for finding and following the source. It allocates memory for the baseline and initialScan arrays and moves the tracker head to the 0 position to begin the tracking procedure.
The function scans across the horizontal plane. For this scan the tracking source is turned off so that the background conditions of the area can be scanned. At each step the voltage is read from sensors C, D and E and stored in the baseline[] array. Each sensor is read multiple times and averaged to reduce noise and erroneous readings.
Once the heat/light source has been turned on the tracker scans the horizontal plane again. The background is subtracted from the new scan to delete the background noise. Again the sensor is read multiple times to reduce noise and erroneous readings. This data is stored in the initialScan[] array.
The function first searches the initialScan[] array for the maximum signal and then moves the tracker head to that position. The tracking portion of the program will then run continuously until the emergency stop button is pressed.
Voltages are read from the three
sensors and compared. Click here for detector
profile graph
Detector E is read first to determine if the head is within range of the source (e.g. voltage is above 0.01 V). When using detector E for range also ensures that when reading the signals from C and D that the side lobes are not being read. The side lobes are created by light reflecting off of the surface of the shaft that the detector is placed inside of.
If it is determined that the head is within range detectors C and D are read and compared to each other to determine which signal is bigger. The tracker will then move using exponential proportional control to move in the direction of the larger signal.
if(leftC >
rightD) { error = rightD/leftC; if(error>0.7
&& error<=0.9) { stepDelayed(TOWARD); count--; } .
Sample code for proportional control
If the signal is lost the head will move in the direction it was moving when the source was lost until detector E receives a signal that is within range. If the tracker head reaches the limit of its range it will scan back and forth until it reacquires the source signal.
Find maximum function
The function will scan the area for the maximum signal (heat/light source). The value of each read is stored in a two dimensional array which is then scanned to find the maximum signal. When the maximum is found the tracker head will then move to that location.
Active scan function
The function will continue to run until the emergency stop button is pressed. While the voltage read from detector E is above 0.01 Volts the tracker searches a 10x10 box reading in voltages at each corner. The four points are compared and the head will move to the point of the maximum reading. If all four of the readings are below 0.01 Volts (signal is lost) the searchXY() function is called.
Search function
.
The tracker will begin searching in a box spiral pattern from
the point that the signal lost until the signal is reacquired or the range of
the tracker is reached. If the range limit is reached the tracker head will
move to the midpoints of both ranges and repeat the box spiral pattern until
the signal is reacquired. When the signal is reacquired the function returns to
the active scan
function.

Search pattern