Microsoft Word - Solar Tracker
Microsoft Word - Solar Tracker
TRACKER
How to Build a Dual Axis Sun
Tracking System
__________
by Michael T. Mruzek
BUILD A SOLAR TRACKER
Copyright © 2016 by Michael T. Mruzek
ISBN 978-0-9971958-0-4
2
Dedication
3
Table of Contents
4
About the Author
5
Preface
Building solar trackers has been part of our life for approximately the
last fifteen years. What began as a hobby has eventually become a small
business: MTM Scientific, Inc. Our business specialty has included
helping technically inclined individuals build and operate their own solar
trackers. In that time we have accumulated a wealth of experience and
"hands-on" knowledge of the craft with the assistance of our capable and
creative customers. We hope to share that knowledge and experience in
this book.
Our goal is to describe a dual axis solar tracker design with sufficient
detail that the reader has the tools and understanding to modify the
design for their own purposes. We can’t wait to see where it goes from
here!
6
Introduction
7
8
Chapter 1: Solar Tracker Basics
In this chapter, we will discuss single and dual axis tracking, with an
emphasis on various strategies for finding the Sun in the sky. We will
explain how our dual axis tracker finds the Sun by using a sensor, and
then storing certain information to make the next search faster. At the
end of this chapter we list the specifications for the dual axis tracker we
are building, with some photographs, to provide a project overview.
The Sun appears to move in the sky, tracing out a daily path from
East to West. The Sun starts at the horizon at dawn, reaches a high point
at solar noon in the middle of the day, and returns to the horizon at
sunset. In addition to the daily motion, there is also a seasonal variation.
In the Northern Hemisphere, the Sun is higher in the sky in Summer and
lower in Winter. But despite these variations, the Sun's apparent path
from one day to the next day is pretty nearly identical: We know the Sun
will rise in the East, reach the highest point in the sky towards the South
at solar noon, and set in the West. This typical day is shown graphically
in Figure 1-1.
Suppose we used a watch and clipboard to record the position of the
Sun. On the first day, we watch and wait for the Sun to rise to its highest
point in the sky to the South and record the time. The next day we do the
same thing. Would the recorded times be the same? No. The times
would be different, but not by very much... perhaps by 30 seconds.
Astronomers tell us the time difference depends on the time of year and
location of the observer, and the exact time difference is precisely
described by a formula known as the “equation of time”.
9
Figure 1-1. Path of the Sun in the sky on a typical day.
10
Some payloads are absolutely ideal for dual axis solar tracking
applications. These payloads typically use optical methods to concentrate
sunlight, such as parabolic dishes and lenses. With these applications,
consideration must be given to the tradeoff between automated dual axis
tracking versus manual or single axis tracking. However, these
applications tend to have a unique aspect to them, due to the spectacular
results of concentrating sunlight, especially in large amounts and at high
temperatures.
We do not use the “calculate and aim” method of solar tracking for
this project, but we will briefly describe the approach and explain why
it’s not used here.
Considered from a purely theoretical point of view, the apparent
position of the Sun in the sky depends upon the observer’s location, time
and date. The Sun’s position can then be accurately determined by a
mathematical formula which uses the location, time, and date
information to perform an aiming calculation. The basic idea with this
approach is to create a tracker controller with the ability to calculate the
Sun’s position, and then precisely aim the solar tracker at that calculated
position in the sky. This is much more difficult to accomplish than you
might think!
For this approach to work you must have the following information:
1) The latitude and longitude of the location, 2) The correct time, 3) The
correct date, and 4) Real-time feedback of the actual aiming coordinates
from the solar tracker. Additionally, the accuracy of each of these pieces
of information, including the accuracy of the equation and the calculating
engine, all directly impact the final quality of the “blind” aim.
The usual approach with this method is to use a computing
microcontroller with a battery-driven real time clock (RTC) module. The
operator provides the latitude, longitude, time and date to the software in
the microcontroller via a user interface. Additionally, the microcontroller
11
has data acquisition capability, such that sensors on the tracker can report
the real-time aiming information back to the controller.
This approach has several practical difficulties: 1) User input at
startup is required to provide the position, time and date, 2) Battery
backup and maintenance is required for the real time clock, 3) The real-
time clock must maintain accuracy over long time spans, potentially
measured in years, and 4) Sensors on the tracker must have the ability
and absolute accuracy to report the spatial aim in three dimensional
space.
Faced with these technical challenges, the usual course of action (to
address these issues) is to include additional technology in the design.
For example, a Global Positioning System (GPS) module can be
included as part of the control system. Another possibility is to network
the tracker controller using 3G, 4G or WiFi communication. However,
the pitfall with including additional technology is the introduction of
additional dependencies on other complex systems. For example, GPS
depends not only on the existence of multiple satellites in the sky; it also
depends on the long term stability of the signal protocol being used for
the GPS beacon signal. (Imagine a vintage solar tracker that comically
attempts to use a dialup modem to connect with "America Online" to get
the time and date.)
Our design goal is a solar tracking controller with absolutely no
dependencies on external systems. Stated a different way: Our goal is a
solar tracker controller which can be stored away for decades and put
back into service, at any location, at a moment’s notice, and with no need
of external inputs from the user or other technical systems. We want a
solar tracker that simply finds the Sun. Additionally, we might hope for a
tracker which can “learn” over the course of time, and find the Sun faster
and faster as the days go by.
13
Searching for the Sun in the sky using a sensor has several
advantages. With a sensor, the controller has real time feedback about
the quality of the aim. That feedback can therefore be used to improve
the aim. And although the Sun must be present for the sensor method to
work, it really isn’t much of an issue since we don’t usually need to aim
the tracker if the Sun isn’t shining.
14
The only real disadvantage of this approach is the requirement to
find the Sun using a sky search, which may require more movement and
articulation of the solar tracker compared to a definite aiming direction
provided by a calculation. However, that disadvantage only exists to the
extent that we aren’t able to quickly and efficiently find the Sun based on
the sensor system signal. As we shall see, with the right choice of sensor
and software logic, finding the Sun in the sky is actually pretty easy to
do. In fact, we can almost get to the point of moving directly to the
correct sky location by devising an optimized searching strategy.
Therefore, our solar tracker project uses a sensor to find the Sun. But
our solar tracker also has a clever twist: Remembering where the Sun
was found. In this project, the tracker controller maintains an internal
clock based on solar time, and records the position of the Sun after it is
found. The Sun position data is logged into a database, and the data is
later used to find the Sun more quickly and efficiently, on the following
days. In some ways, our solar tracker incorporates the best features of
both Sun tracking methods.
However, for this method to work well, we need to incorporate a
very specific style of solar tracker mounting structure. We call this
mechanical style the "tilt-tilt" tracker approach. We will say more about
this in the next chapter when we discuss the mechanical design in detail.
This book focuses on building a dual axis solar tracker with specific
design guidelines and directions. We realize that many people will make
changes and modify the design for their own purposes. In fact we fully
expect that! But, we have to start somewhere. We start with a solar
tracker called our “baseline design”. The key components in the baseline
design are shown and labeled in Figure 1-3, and the technical
specifications are listed in Figure 1-4.
15
Figure 1-4. Specifications of the “baseline” dual axis solar tracker.
16
Chapter Two: Mechanical Design
17
platform moves, either East-West or North-South, an angle meter will
detect a change. However, with the same angle meters on the tilt-rotate
tracker only the North-South motion is detectable. The East-West
rotational motion cannot be detected by angle meters which use gravity
as a reference. Here’s the bottom line: If we design the mechanical
structure to move with a tilt-tilt motion we can use a special low-cost
angle sensor to monitor the tracker's aim simply and accurately.
Figure 2-1. Tilting is okay, but rotating around the vertical is not.
19
Figure 2-3. A tilt-tilt frame built using 80/20 structural framing.
20
Figure 2-4. Parts list for the 80/20 tilt-tilt frame.
21
Figure 2-5. Isometric view of the 80/20 frame.
22
called an "economy nut", as shown in Figure 2-9. These fasteners are
easily assembled using a ball end Allen driver, as shown in Figure 2-7.
The flanges used for connecting the structural frame together are also
a standardized design, and are generally referred to with descriptive
names that reference the number of holes in them.
23
The dynamic parts of the structural elements are called "hinges".
This solar tracker design uses two different hinge types. Both types are
referred to as “living hinges”, and they are shown in greater detail in
Figure 2-8. The hinges should be carefully assembled according to the
instructions included with them by 80/20. This assures proper operation.
The hinge hardware is designed with optimal mechanical clearances,
such that the fasteners can by “tightened down” without binding the
action of the hinge. Correct assembly of the hinge hardware is very
important.
24
angle sensor must be on the moving tilt-tilt frame to measure the aiming
direction of the solar tracker.
Figure 2-9. Button head socket cap screw with economy nut.
25
Figure 2-10. Details of the 80/20 base frame.
26
An end view of the 1010 extrusion profile is shown in Figure 2-12.
The slots in the extrusion are made to hold the economy nuts. The
economy nuts slide into the slots for easy positioning, but are prevented
from rotating for the actual “tightening-down”. This is a great
convenience for adjusting the structure’s range of motion. The
adjustments can be made quickly and easily using simple hand tools on
the fly.
If at some point in the project you decide a more permanent
mounting method is desirable, we’d like to mention that 80/20 offers an
accessory for that purpose, as shown in Figure 2-13. This part is called
the "Floor Mount Base", and is identified as Part #2380 by 80/20. In
practice, we have mounted this base to a wooden platform by simply
using ordinary wood screws.
27
Sun Pointer
The quality of aim of your solar tracker with respect to the location
of the Sun in the sky can be difficult to judge when you are doing field
work. Fortunately, the quality of aim can be rapidly and precisely
determined with the aid of a simple tool. You will find it helpful to
include a Sun pointer on your solar tracker, as shown in Figure 2-14. The
Sun pointer consists of a threaded bolt stud, 3 inches long that has been
attached to the frame using an economy nut, fender washer and flanged
nut. The circular shadow plate is nothing more than a CD-ROM disk
with a white top face.
28
Enclosure
29
Figure 2-14. Short threaded rod and CD disk used as a Sun pointer.
30
Mechanical Parts List
31
Figure 2-16. Mechanical parts required to build the tracker.
32
The barebones parts are used to create an upright beam, North-South
pivot and East-West pivot. With this approach, you can start with a
minimum of purchased 80/20 items, and add the other 80/20 parts as you
proceed with the project. Nothing is wasted. Of course, you must also
improvise a base for mounting the setup. But that can be something as
simple as a piece of wood or even a large vise or clamp.
33
34
Chapter Three: Electrical Design
Linear Actuators
36
also have the benefit of being adjustable in regards to position. These
brackets are often available from the supplier of the linear actuators, and
they also can be widely found on Ebay.
The electrical connections for actuators are simple. There are only
two wires. Usually the wires are color-coded red and black, to indicate
positive and negative polarity. The wires are attached directly to the
controller using simple screw terminals on the PCB. If during testing a
linear actuator is moving in the wrong direction (i.e. West instead of
East) simply swap the positive and negative leads at the screw terminal
connector.
Figure 3-2. Clevis brackets secure the linear actuator to the frame.
This solar tracker project uses 12VDC as the main electrical power
source. The 12VDC can be supplied by a standard power supply or a
battery. We suggest using a standard power supply during the testing
phase. Power supplies suitable for this project are inexpensive, reliable
and readily available. We have found that a 12VDC supply with a 2 amp
output rating works great in this application. Some examples of suitable
power supplies are shown in Figure 3-4. The type of 12VDC power
37
supply that plugs directly into a 120VAC household power outlet is
ideal.
The linear actuators operate directly from the 12VDC power. The
same 12VDC power also feeds a circuit for creating 5VDC power. The
5VDC power is used for operating various controller electronics, such as
the microcontroller and digital electronics.
The 12VDC power supply circuit is shown in Figure 3-4. The circuit
design includes several important safety features. The first precaution is
a fuse. Generally, good operating practice is to use the smallest amperage
fuse which works reliably in the application. In that regard, we have
found a 2 amp fuse works well for this project. The largest possible fuse
size is 8 amps. (The relays used in the controller have a maximum
current rating of 8 amps.) When selecting a fuse type we suggest using a
“slow-blow” fuse, which you will find has been specified in the parts list.
The 12VDC power supply circuit also has input polarity protection
as a safety feature. Whenever DC power is applied to a circuit, it is
38
always possible for the polarity to be accidently applied in reverse. A
polarity protection diode is included in the 12VDC power supply circuit.
That’s the purpose of the 10A10 diode. So, if you accidentally reverse
the positive and negative leads of the input power supply, circuit damage
will be avoided. In that case, the controller won’t “power-up” and it
should be a simple matter to find the mistake.
The solar tracker circuit design includes a 5VDC power supply. The
5VDC power supply is derived from the main 12VDC power supply. The
circuit details of the power supply circuit are shown in Figure 3-5. The
5VDC supply provides power to the controller electronics, such as the
microcontroller, watchdog timer circuit, and most of the sensors.
The 5VDC power supply circuit is designed to generate a precise and
stable voltage reference source. Also, special emphasis has been placed
on preventing noise spikes in the power supply. Noise spikes could
potentially affect sensitive electrical components in the controller, such
as the microcontroller and other digital devices.
The LM7805 is an integrated circuit (IC) voltage regulator which
converts 12VDC input power to 5VDC output power. The LM7805 is a
simple device with only three connections: voltage input, ground
39
connection and stable 5VDC output. The output of the LM7805 voltage
regulator is additionally stabilized with a large 470uF electrolytic
capacitor.
Watchdog Timer
41
Figure 3-7. Circuit diagram of the watchdog timer.
42
Relay Operation
Figure 3-8. Standard industrial relay with coil, spring and contacts.
43
The relays used in our project are identical internally to the example
we’ve described, but they have a plastic protective case to prevent
damage to the parts, as shown in Figure 3-9. We have also chosen relays
which have sockets available for them. The sockets make it very easy to
replace the relays in the future, if maintenance or repair should ever be
necessary.
Relay Circuit
Figure 3-9. Relays and sockets used in the solar tracker controller.
The Picaxe output channels are not directly connected to the relay
coils. The Picaxe output channels are first buffered using small signal
transistors. The transistors buffer and amplify the electrical signal for
44
actuation of the relay coils. The transistors are a general purpose 2N3904
type, technically called an NPN bipolar junction semiconductor. Notice
that one transistor is used for each of the four relay coils. Each signal line
from the Picaxe includes a 10K resistor as a buffer to protect the Picaxe
output pin, since preventing damage to the microcontroller is a high
priority.
Because the actuator coils in the relays are inductive, and because we
are switching the coils with transistors, special care must be taken to
handle the inductive “kickback” from the coils. That is the purpose of the
diodes connected across the relay coil leads. The diodes are type
1N4002. These diodes are very important. Without the diodes, the “make
and break” of the relay coils would induce voltage spikes and damage the
switching transistors.
The relay circuit includes toggle switches for actuating the relays
manually, as shown in Figure 3-10. This feature is especially useful
during initial setup and testing of the solar tracker. The manual switches
are a convenient method for verifying that the polarity of the linear
actuator connections are correct. The switches are also convenient for
adjusting the travel limits of the actuators. You can use the switches to
extend and retract the actuators while checking their mechanical action.
The manual switches will work without the microcontroller installed, so
you can check this part of the setup early in your project. This is perfect
for making adjustments and setting the limits of travel on the tilt-tilt
frame, before proceeding to automatic control with the solar tracker
controller.
A printed circuit board is available for this project, and using the
PCB will generally be the quickest, easiest and least expensive path to
building this project. However, we will provide some additional
information about printed circuit boards, since we suspect some project
builders will have an interest in modifying the design, or creating their
own PCB.
In the past, printed circuit boards were fairly difficult to design and
construct because the design process was done manually on a drafting
board using black tracing tape and a knife edge. And creating the artwork
was only part of the challenge. Special equipment and chemicals were
also required to etch the copper traces onto the board. Optionally, the
boards could be fabricated by a commercial supply house, but that was
generally an expensive proposition, especially in small hobby-sized
quantities.
46
Figure 3-11. Relay circuit for the North-South linear actuator.
47
Figure 3-12. The PCB mounted inside the watertight enclosure.
48
You can become an effective user of their design software with only a
few hours of dedicated study and practice.
The PCB for this project has been created as a two-sided board using
traditional through-hole components. That means there are circuit traces
on both the top and bottom of the board. Connections between the top
and bottom layers are generally made at the same locations where the
component leads pass through the board. In some situations, a circuit
trace may need to pass from top to bottom through a special conductive
pathway called a “via”. A via is really nothing more than a plated-
through hole in the PCB.
There is printed text and artwork on the top of the PCB to aid in
indentifying and placing the various components. This is called the
"silkscreen layer" because a silkscreen process was originally used to
apply the artwork. Good design practice is to include useful and pertinent
information on the silkscreen layer. The written information is an aid to
anyone that might be examining the device in the field, such as for repair
or troubleshooting.
The printed circuit board and all the electronic components required
for assembly of the controller are shown in Figure 3-15. The assembled
circuit board is shown in Figure 3-16. Notice that the PCB has an arrow
to indicate the Southern direction, which is for proper mounting and
50
setup on the tilt-tilt tracker frame. (We’ll say more about tracker setup
later.)
52
Figure 3-16. View of assembled printed circuit board.
53
Figure 3-17. Capacitor, regulator and transistor PCB mounting.
54
Figure 3-18. Diode and LED mounting on PCB
55
PCB because it’s designed to be replaceable. As shown in Figure 3-19,
the module is attached to the printed circuit board using dual standoff
headers. Notice that the text on the PCB artwork is similar to the text on
the module, which will match when the module is installed correctly.
Take care that you don’t install the accelerometer module in reverse.
We use several integrated circuits in this circuit, and one of the most
common and destructive assembly mistakes is backwards installation.
There are only two ways an IC can be mounted in a socket, but mounting
the wrong way will usually damage the device. The most common
method to indicate pin number “1” on an IC is with a small dot or
indentation, as shown in Figure 3-20. Also, notice how the IC case has a
notch on one end. That notch should agree with the identical notch on the
PCB artwork, as shown in Figure 3-21. Additionally, you will find that
the solder pad for pin “1” is square, while the other solder pads for the IC
pins are round. All of the integrated circuits in this project are socketed,
to facilitate easy replacement should that ever be necessary.
56
Figure 3-20. IC Pin #1 is marked at top left corner on these devices.
Resistor Identification
57
Figure 3-21. The IC case-notch aligns with the artwork notch.
58
Figure 3-22. Digital multimeter for checking resistor values.
Electrical Feedthrough
Figure 3-23. Feedthrough for routing cables and wires to the PCB
60
Complete Circuit Schematic
The complete parts list for populating the printed circuit board is
provided in Figure 3-25. We have included part numbers from the
original manufacturers, and also from suggested part suppliers. We have
provided two references for the electronic parts to facilitate sourcing the
parts from other suppliers. Most of the electrical parts are available
directly from Digi-Key, Inc. The bare PCB can be purchased from MTM
Scientific, Inc. MTM Scientific, Inc. also offers a complete kit with all
the electronic parts, for a quick start on the project.
You may have an interest in studying the technical specifications of
individual components in the parts list. A simple way to find
manufacturer datasheets is by searching for the generic component name
on a supplier’s website (i.e. Digi-Key). The search will provide a page of
relevant results, with hot links taking you directly to the full datasheets in
PDF format.
61
Figure 3-25. Complete parts list to populate the PCB.
62
Figure 3-26. Complete schematic of the solar tracker controller.
63
64
Chapter Four: Sensors
Analog-to-Digital Conversion
65
Let’s do an example calculation. Suppose we are told that an A/D
converter is doing a 10 bit conversion with a 5VDC reference voltage
and reports the integer number 338. What is the corresponding voltage
it’s measuring? The answer is simply 338 x 0.004883 = 1.650 VDC.
The Picaxe microcontroller has a total of eleven analog-to-digital
converters. Each A/D converter is associated with a different input pin.
All of the A/D converters are designed for measuring voltage signals.
The general data acquisition approach, therefore, is to select the
appropriate sensors capable of converting our measurement of interest
into a voltage signal. That’s because sensors with voltage outputs are
suitable for the A/D converters on the Picaxe microcontroller.
One more important point about A/D conversion: A single A/D
conversion will always be subject to the possibility of electrical noise in
the signal, as well as some natural variation in the signal for physical
reasons. Fortunately, those issues are easily addressed by taking multiple
A/D readings and averaging the result. When you examine the source
code for the tracker software program, you will see that whenever any
A/D conversion is made we always acquire multiple readings and
calculate an average. The Picaxe microcontroller can acquire the A/D
readings, perform the mathematical averaging, and report the final result
very quickly.
Sunlight Sensors
Another type of sensor which has been quite popular with various
solar trackers is the simple light emitting diode (LED). These sensors
have the great advantage of being inexpensive and fairly sensitive to
sunlight and are packaged for rough use. The typical LED has a small
active area near the bottom of the plastic case. The active area responds
to sunlight by producing a voltage signal.
We experimented with many different styles and types of LED
sensors and found that one of the most suitable is a simple 5 mm size (T-
1 3/4), designed to produce yellow light, with a clear plastic encasement.
There was only one problem with the stock LED types: We found that
they are unpredictably sensitive to off-axis sunlight. In other words they
68
suffered from “false peaks” due to internal reflections created by
sideways-sunlight impinging on the active area.
69
Figure 4-4. Abrasive scuffing of the LED improves performance.
70
Figure 4-6. Actual response of improved LED Sun sensor.
72
Figure 4-9. Mount the sensor in the top lid of the enclosure.
Current Sensor
Temperature Sensor
74
transistor, is actually a calibrated temperature sensor with built-in
linearization, and the ability to communicate with the Picaxe
microcontroller using a communication protocol known as the 1-Wire®
interface. For our purposes, we don’t need to know much more about the
internal workings of this sensor, although there is much more
information available in the device’s datasheet if you would like to know
more. Suffice to say, we can directly connect the sensor to the Picaxe and
read temperature with a simple software command. We use the sensor for
reading temperatures in the range of 0 to 127 degrees C. The temperature
measurement circuit is shown in Figure 4-12.
Voltage Sensor
75
Figure 4-12. Temperature sensor connection to a PICAXE-20X2.
76
Angle Sensors
77
should ever be a need. The active element inside the sensor is a
micromachined mechanical beam structure which deflects as it is moved
and rotated in a gravitational field. The interior deflections are measured
using a capacitive technique, and the resulting electrical signal is
conditioned with an internal amplifier and buffer circuit. If you are
interested in knowing more about the internal workings of the
MMA7361 active element, there is much more information available in
the manufacturer’s datasheets and application notes.
The angle sensor module is designed to measure angles in 3
orthogonal directions; however we use only two of the directions: X &
Y. The X channel is used to measure the East-West tilt angle, and the Y
channel is used to measure the North-South tilt angle. The output of the
module for both the channels is a voltage signal proportional to angle.
The voltage signal is sent to the Picaxe, where an analog-to-digital
converter reads the signal and reports the result in ADC count units, as
shown in Figure 4-17. It is not necessary for us to convert the ADC
counts to angular degrees. Instead, we find it’s easier and more
convenient to work directly with the signal in the native ADC units, as
reported by the Picaxe.
When the payload platform of the dual axis solar tracker is level,
both the East-West and North-South position reports are reported as 338
ADC counts. The Park position for the solar tracker is with the East-
West tilt at level, and the North-South tilt aimed toward the horizon at a
45 degree angle. In that case, the position is reported as North-South =
455 ADC counts and East-West = 338 ADC counts. Note that the North-
South ADC counts increase as the tilt axis moves Southward.
Figure 4-15. Lookup table for ADC counts from the angle sensor.
78
Figure 4-16. Map of allowed tilt locations, in ADC count units.
79
Figure 4-17. Accelerometer connection to a PICAXE-20X2.
Limit Switches
Readers who are familiar with building solar trackers, whether they
are single axis or dual axis, may be familiar with the practice of
incorporating limit switches to control the range of motion of the solar
tracker hardware. Limit switches are present in this solar tracker design,
in the sense that we are using the limit switches which are already
included inside the linear actuators. The mechanical range of motion of
the tracker hardware coincides with the range of motion of the linear
actuators.
80
However, because we have included a dual axis angle measurement
system for sensing the directional aim of the solar tracker, we can
leverage that angular position information to add some useful safety
features to our design.
Referring back to Figure 4-16, we see a map of ADC counts for the
East-West and North-South motion as the tracker changes position. In
effect, we have a map of “allowed” motion space. We can certainly use
that position information in our software code to verify the solar tracker
is always working in the correct angle motion space.
What are some examples of why that might not be occurring? Well,
consider what would happen if the wind happened to blow over the solar
tracker frame. At that point, how would the software know that
something is wrong and to stop moving? The solution is to include a
simple limit test on the ADC position readings, such that we verify the
readings are in the allowed space before any movement is initiated.
Incidentally, this feature was added after that very event happened during
the development of the solar tracker! This safety check is the purpose of
the subroutine called "Range_Check" in the software code.
Just one more comment about limit switches: If for some reason you
would like to include a limit switch, or any type of switch for that matter,
you might consider using the option jumper inputs, as described in the
next section. Of course, modification of the software would also be
required to make the additional switches functional.
Option Jumpers
85
The pinout for the Picaxe microcontroller is shown in Figure 5-1.
Two pins are reserved for the 5VDC power supply and ground
connections. Two more pins are reserved for the serial communication
input and output (I/O) connections. The balance of the pins are
multipurpose, and they can each be individually configured per the
options listed for the specific pin. An efficient project strategy is to use
the digital pins for simple I/O, and to use the ADC pins for physical
measurements. Also, it is important to know that these pins must be
configured in the software code. You will find the pin configuration
commands in the source code as part of the "Initialization" subroutine.
Building this dual axis solar tracker requires the use of a Picaxe
microcontroller which has been programmed with the solar tracker
controller source code. If you decide to do the programming yourself, it's
relatively easy to accomplish. The software application for programming
the Picaxe is available free of charge from Revolution Education, Ltd. A
nice feature of the Picaxe devices is that you don't need a special IC
programming machine. The Picaxe can be programmed using an RS-232
serial connection combined with a few simple circuit components. The
same serial connection used for programming can also be used to
communicate with the solar tracker controller while it's operating.
The software programmed into the microcontroller is stored in non-
volatile memory. That means the controller program is not erased when
the power is removed. It also means you must reprogram the Picaxe if
you want to change anything regarding the solar tracker software.
The Picaxe operating system uses variables of different sizes. Flags
are single “bit” variables which are either true (1) or false (0). Larger in
size, “byte” variables consist of eight bits. The byte variable has a valid
range of zero to 255. Even larger in size, the “word” variable consists of
16 bits. The word variable has a valid range of zero to 65535. The Picaxe
variables are summarized in Figure 5-2.
It is important to know and remember that the Picaxe microcontroller
is only capable of performing integer math. The Picaxe microcontroller
is not able to do math calculations with decimal numbers or with
86
negative numbers. All Picaxe math calculations must be performed using
variables which represent positive integers. The requirement to use
integer math is one of the most important characteristics with respect to
writing software source code for the Picaxe microcontroller. The
requirement to perform all of our math calculations using positive
integers is not much of a limitation. In fact, it turns out to be very easy to
accomplish all of our computational goals using only integer math.
88
or settings in the source code, in which case the memory organization
likely won’t need to be changed at all.
Variable Space
89
variable is the ideal way to store the information because it has only two
states: "True"=1 or "False"=0.
Suppose we want to store a piece of information which is an integer
number with a maximum value of 255. Well, in that case a byte variable
is ideal because it can range anywhere from 0 up to 255.
In the same way, suppose we want to store a piece of information
that is an integer number with a maximum value of 65535. In that case,
a word variable is ideal because it can range anywhere from 0 up to
65535.
The bottom line is that we want to assign variable space to hold
information according to the size of the information. Of course, we can
always store a small number in a large variable space, but doing so
wastes some of the memory space. In a microcontroller, the memory
space is limited and we don’t want to waste it.
The variable space allocations for our solar tracker software program
are made in the source code, which is provided in the appendix. Variable
declarations are one of the first tasks of writing a computer program.
Upon examination you will find that the variable declarations are at the
beginning of the program. Our computer program uses all of the
available memory space for making variable assignments. Some of the
memory space is used for bit variables, some is used for byte variables,
and the balance is used for word variables.
Program Space
90
The Picaxe provides 4096 bytes of space for the program and we use
much of it for this project. However, there remains enough space
available for additional minor changes and modifications, if desired. It is
important to remember that when a program is downloaded to the Picaxe,
it will remain in the device after the power is turned “OFF”. When
starting with a brand new PICAXE-20X2, you must first load a software
program into the device to begin useful operation. After loading, the
program will remain in memory indefinitely, until the device is loaded
with something different.
System Memory
Project Computer
As you might expect, this project uses a computer. So, let's briefly
discuss some of the considerations in regard to selecting a project
computer. Now, your first inclination might be to use a computer which
you already have available... possibly the "family" computer somewhere
around the home. Another thought might be to try to adapt a small
92
handheld device, such as a tablet or phone, for this project. Although
every situation is different, we’d like to suggest that you consider
purchasing and dedicating a computer especially for this project.
Not only will you be doing hardware and software development with
the computer, you will also be using it in the field when the solar tracker
becomes operational. In addition, the easiest method to communicate
with and program the Picaxe microcontroller is with good, old-fashioned
RS-232 serial communication using a nine pin serial port connector.
However, most new computers today don't have a nine pin serial port.
Today, most new computers have a USB type serial port instead.
Here is our suggested course of action: obtain, purchase or refurbish
an old computer specifically for this project. For example, consider the
lowly laptop, as shown in Figure 5-5. A simple search on Ebay will turn-
up literally tens of thousands of used laptops for sale, with many at
practically giveaway prices. In addition, many of those older laptops
have a built-in nine pin serial port.
Acquiring and using an old laptop actually solves several problems
at once: You will have a dedicated-use computer for the project, the
computer is easily portable, the computer has a display, the computer can
operate on battery power, the computer can run the software we plan to
use, and the computer has a built-in means of communication with our
project hardware. All this in a device which can easily be found for less
than $50. It is even possible that you may already have one, or know
someone that will give you such a computer for free. Similar computers
can often be found at yard sales or even at second hand thrift stores.
Although many laptop computers will work in this application, we
can suggest a few common models that work well and are readily
available on Ebay. For example, this book was typed on a Dell Latitude
D530 laptop computer. We purchased this computer on Ebay, postage
paid for $35. It came preloaded with Windows XP, which although an
older operating system, is stable and capable. Another model to consider
might be a Dell Latitude D600, which not only has a serial port, but is
the last laptop model from Dell that has a good old-fashioned printer
port.
93
Figure 5-4. Organization of the non-volatile memory storage.
94
Figure 5-5. A Dell brand laptop computer with a 9 pin serial port.
95
Now, we know what you may be thinking: “I already have a
computer, and I can simply use a USB to Serial converter.” Yes, we
know the converter should work in theory. Unfortunately, there is a
problem with the practical execution of this approach. The USB
converters use internal software coding to emulate the RS-232 serial
port. The unfortunate fact is that, although they might work for some
applications, we will be using several RS-232 commands which are often
not coded correctly in the USB converter. In that case the converter
simply doesn’t work. Of course, you could purchase and test USB
converters until you find one that does the serial port emulation totally
correctly... But ask yourself a simple question: Would you rather be
doing that, or start building the solar tracker?
Finally, there is one other option you might consider if you have a
desktop computer available and would like to use it as the project
computer. You can purchase an “adapter card” which installs inside the
computer to provide a nine pin serial port. The only challenge to this
approach is ascertaining what make and model of computer card to
purchase. Generally, many modern computers will accept a PCI or PCI-E
card, while older computers may require an ISA card. Any of these
cards can be purchased on Ebay for less than $10. Installing an adapter
96
card to provide a nine pin serial card works great for this application.
Keep in mind, though, that by using a desktop computer you will not
have portability of the test setup for doing your field work.
Software Tools
97
Figure 5-8. The four software applications useful for this project.
98
other using digital signals. This communication protocol has been around
for decades, and the history of serial communication goes back to the
days of teletypes. Establishing basic serial communication between two
devices only requires a three wire connection: That's two signal wires
(receive and transmit) and a third wire to establish a common ground.
We are going to establish serial communication between your project
computer and the PICAXE-20X2 microcontroller. The setup to operate a
Picaxe microcontroller with serial communication is amazingly simple.
The circuit diagram is shown in Figure 5-10. We recommend completing
this starter project before doing any work with the printed circuit board.
This will verify your project computer, serial communication program
and Picaxe software programming application are all working correctly.
99
you start with the direct wiring as shown. Direct wiring will eliminate the
cable variable in your starting setup.
The software code listing for the test program which is loaded into
the PICAXE-20X2 is shown in Figure 5-12. The program consists of
eight lines of text, and actually only five of those lines are active
program code instructions. (The other lines are simply comments.) The
five active code lines are:
loop1:
sertxd (“hello”,13,10)
pause 1000
goto loop1
end
100
Figure 5-11 Parts list for building serial port project
Begin building this test setup by obtaining the electrical parts and
connecting them together, preferably with a solderless breadboard, as
shown in Figure 5-9. Next, type the program listing into the computer
using the Picaxe Programming Editor software, as shown in Figure 5-12.
After typing the program you can check for typing mistakes by clicking
on the "Syntax" button in the header. You may also want to save the
program at this point by clicking on the “Save” button in the header.
101
Next, connect your computer to the test setup using the serial port
connector. Power is applied to the PICAXE-20X2 by connecting the 9V
battery snap. Immediately after applying power to the Picaxe, quickly
engage the "Program" option in the software by hitting the "F5" function
key. It is very important to start programming immediately after power is
applied to the Picaxe because the Picaxe "looks" for a new program
when power is first applied. You should see a software download
progress bar. The Picaxe will be programmed after the progress bar
finishes scrolling.
After the microcontroller has been programmed, close the Picaxe
Programming Editor and open the Termite serial communication
program. (Note: Both programs cannot be open and using the serial port
at the same time.) Check to make sure the Termite communication
settings match what is shown in Figure 5-13. At this point, you should
see the "hello" message scrolling on the screen.
You have just programmed the Picaxe with your own program, and
established two way serial communication between the microcontroller
and your project computer. The serial communication test program will
remain in the Picaxe microcontroller until you download a new program.
Now might be a good time for you to explore writing additional
practice code using Picaxe BASIC. For example, by changing the text
inside the quotation marks (“hello”) you can instruct the program to send
a different message. There are numerous other programming examples in
the Picaxe manuals. You can view the Picaxe manuals by clicking the
“Help” button in the header of the Picaxe Programming Editor.
We see that the transmission of the letter "M" begins with a bit to
indicate the start, and a trail of bits to close out the message. Now let’s
104
try something a little bit more complicated and send the longer message
"MTM", as shown in Figure 5-15.
We see that the three letters “MTM” are indeed transmitted in
sequence. There is a small gap between each of the letters, which
incidentally is called the stop bit. We note that each character consists of
8 bits, which comprises a byte. And at the end we see the same 8 bit
sequence that was at the end of our single letter "M" transmission. (By
the way, that end sequence is "00001010" and when read in reverse,
equals decimal "10", which equals "Line Feed (New Line)" in the ASCII
table. So it all makes sense!)
Now, we have actually made quite a few arbitrary decisions about
our serial communication protocol, including: speed, size of data, start
signal, end signal, polarity and how to signal the end-of-message. This
actually is not the end of the list, and other serial communication options
include error detection and error correction protocols, just to name a few
possible differences.
105
Serial communication is used for this project because: The Picaxe
microcontroller has the capability built-in, host computers can easily run
software to communicate using the method, and most importantly the
transmission mode is very robust against electrical noise. In fact, running
a serial cable for 100 feet (or more) is usually not a problem, and we did
just that for the early development phase of this project. With serial
communication and a long cable you can work with your computer
anywhere that’s convenient, while your solar tracker is busy tracking the
Sun outdoors.
106
Chapter Six: Software Control
107
shows something computer programmers call a "state machine". The
state machine controls the flow of the main program, while subroutines
handle specific tasks in support of the main program.
Picaxe BASIC is very similar to other computer languages with the
word "BASIC" as part of their names. Picaxe BASIC is a computer
language for performing logical comparisons, simple integer math and
basic input and output (I/O). Picaxe BASIC is produced and distributed
by Revolution Education, Ltd in England. If you are already familiar
with some variant of BASIC it will be very easy for you to understand
and start programming in Picaxe BASIC.
Picaxe BASIC uses only integer math. This means that numbers can
only be represented by whole integers which are equal to or greater than
zero. (e.g. 0, 1, 2, 3, 4...) At first this may seem like a major limitation,
but actually integer math works quite well for this application.
Software programs usually include “comments” in the code listing to
help explain the logical flow. The comments are an aid to the
programmer. The Picaxe controller does not read or use the comments.
Adding descriptive comments to your computer source code is very
important. Detailed comments allow you to return to a coding project and
pickup where you left off, which sometimes can be years later. Good
comments allow other programmers to understand your code. Comments
are also an excellent method to record the change history. In Picaxe
BASIC all comments start with a single quotation mark. Watch for them
as you examine the code. We try to include comments as often as
possible, especially since you will be reading the code for the first time.
Subroutines
Subroutines are code segments which are called by the main program
to accomplish specific tasks. In practice, subroutines are called, perform
a task, and then return control to the main program. Besides improving
the clarity of logical control in a program, subroutines have the
additional advantage of reusing code. This avoids listing the same code
over-and-over again in the program, thereby saving program memory
108
space. The vast majority of the source code for operating the solar
tracker consists of numerous subroutines, each of which has a specific
name and purpose.
109
There are a few best practices which should be used when writing a
subroutine. To begin with, it is very helpful to give the subroutine a
descriptive name. There is no memory penalty for using long names in
the Picaxe BASIC source code listing. Comments and long names don’t
get loaded into program memory. Only the working commands are
loaded into the Picaxe memory.
Another best practice for subroutines is to end the code segment with
a return back to the calling code. This establishes each subroutine as
merely a specialized service for performing a dedicated function.
Subroutines always return control back to the main program when they
are finished.
110
Another good practice is to include descriptive comments at the start
of a subroutine to clearly describe exactly what will be done in the code.
Likewise, a description of the conditions the subroutine expects to have
“setup” prior to being called should be included. For example,
sometimes a variable should be initialized before a subroutine is called to
perform a calculation using the variable.
An example of a subroutine to measure the North-South and East-
West angular position is shown in Figure 6-2. The subroutine begins
with a descriptive name, as denoted by the colon. Next, we find several
explanatory comments describing the subroutine, as marked by the single
quotation mark at the start of each line. Then, we initialize several
variables that will be used to dynamically store data while we make
multiple readings in a loop, and which will be subsequently averaged.
After the data acquisition loop segment we calculate the averages for
both the North-South and East-West angular positions. Finally, we return
control back to the calling code, because the subroutine has done its job
and it’s time to return control back to the main program.
Main Program
113
Serial Input/Output
Timekeeping
The Picaxe chip has the ability to measure elapsed time, but it does
not have a Real Time Clock (RTC) for maintaining the global date and
time. This leads to a broader question of how we will reckon time in the
solar tracker software. The first thought might be to include a standard
real time clock module for measuring time. Such clocks are readily
available as compact modules. The clock modules also have battery
backup for maintaining the correct time, even when the microcontroller
is not energized.
We don’t include a real time clock (RTC) module in this design for
several reasons. 1) A clock module will only “know” the time if we set it
first. This forces the user to navigate a setup menu and user interface to
correctly communicate the local time. 2) Since the local time can change,
we need to consider the effect of differing time zones, and changes back-
115
and-forth to daylight savings time, etc. 3) Another pitfall is the
dependence on a battery for operating the clock. This effectively means
that the user must monitor the battery, and change the battery at regular
maintenance intervals. 4) We don’t know the accuracy of the RTC clock
over long periods of time, and whether the device requires adjustment to
compensate for long term drift.
116
position and the Sun aim would be nearly correct. What’s more, this
method would work even if the Sun was obscured by clouds.
We know that the Picaxe can measure elapsed time, but it would still
be helpful to have some sort of “universal” time marker from which to
reckon our timekeeping. That actually turns out to be fairly simple to
define, and also easy to determine when the tracker is operating.
Think about the path of the Sun in the sky... We know the Sun rises
in the East and sets in the West. We also know that at midday the Sun
will be halfway between sunrise and sunset. At midday the Sun will be at
the highest point in the sky. We also know that a solar tracker using the
tilt-tilt mechanism will be exactly level along the East-West tilt direction
at solar noon, provided the North-South axis has been correctly aligned
during setup. In that case, we can use our angle sensor to measure when
the East-West axis is (nearly exactly) level, and call that unique and
special time of day our "solar noon".
What’s unique about this approach is that we don’t need to determine
solar noon with respect to any type of standard clock time. We are, in
effect, establishing a local timeframe for our solar tracker that only
depends on measuring when the Sun is midway across the sky. The solar
noon detection is strictly device dependent, but that's okay because only
our solar tracker will be using the solar noon detection to set the local
time base reference.
The bottom line is that we can have a clock on the Picaxe that is
measuring time according to elapsed time, which is also being “reset” to
the correct time instance of solar noon during a normal tracking day.
Therefore, we now have a simple onboard clock that measures solar time
and also sets itself. A great advantage of the clock setting itself is that the
long term accuracy and stability of the time base is no longer much of an
issue. A similar example of timekeeping might be resetting your watch
to the correct time everyday at noon.
117
Figure 6-5. The East-West tilt axis is level at solar noon.
Interval Timekeeping
Having explained that we are not using a real time clock, but instead
we will be using elapsed time intervals to reckon time, we must devise a
system for exactly how we will mark time. This may seem a little bit
confusing at first, but the final solution turns out to be surprisingly
simple.
There are multiple aspects to the question of how to structure a
timekeeping system using intervals. We want the timekeeping to be
integer friendly and compatible with normal minutes, hours and days.
We also want to store the position of the Sun using the tilt sensor data
with the time marker we establish. We want to detect solar noon and use
that information to adjust the clock daily, if possible. We also want a
meaningful and useful time interval for pacing how often we move the
tracker to follow the Sun.
So here is the solution: We have defined a unit of time called a
"solex". A solex is a time interval of exactly six minutes. That means
there are 10 solexes in an hour and 240 solexes in a day. We decided to
start our day at midnight with the solex count equal to zero. We end the
118
day 24 hours later, when the solex count hits 240. At that time, the solex
count returns to zero. As a result, the solex count for solar noon is 120.
As you can see, this is very similar to time reckoning in a 24 hour
format, but simply removes the trailing zero (i.e. noon = 12:00 = 120
solexes). The result is a timekeeping system that meets our requirements,
and which is fairly easy to remember because it’s intuitive.
There is only one more consideration regarding timekeeping with
intervals. The solar tracker spends almost all day waiting to make its next
move. While it is waiting, we do the interval timekeeping. But what
about the time the tracker actually spends moving? It’s during those brief
time periods that timekeeping is not being done. As a result, we need to
make a small correction to the time intervals to account for the time lost
while doing movements. You will see a correction in the subroutine
"Wait_6_Min" for just this purpose. The correction was determined
experimentally by operating the tracker for several days and calculating
the clock offset due to the average time the tracker spent in motion.
Tracking Data
Shown in Figure 6-6 is an excerpt of actual data taken from the angle
tilt-tilt sensors while the solar tracker is following the Sun. Recall that
the time is measured in 6 minute increments, called solexes. Solar noon
is time 120. The units of measurement for both the tilt-tilt angles are in
direct ADC counts, as measured by the Picaxe microcontroller. This
particular data set was taken at 42 degrees North latitude in Summer.
An interesting pattern emerges when the Sun position data is graphed
and analyzed, as shown in Figure 6-7. We see that the East-West (E-W)
coordinate has a steady progression from sunrise to sunset during the
day. However, even more interesting is the shape of the line when the
data is carefully plotted on a graph. We find the East-West Sun position
data during a typical day is strongly linear.
The linearity of the East-West tracking rate actually makes sense if
we recall that the apparent position of the Sun rotates one complete
revolution per day. One revolution per day equals 360 degrees per day.
119
The linear trend line seen in Figure 6-7 suggests that we can track the
Sun in this example (to a very close approximation) by simply advancing
the solar tracker position at the same East-West rate.
The slope of the plotted East-West tilt axis data is the angular
tracking rate we want to implement. In this example, we see that the
East-West tilt is advancing at approximately 3.3 ADC counts per time
increment, per the trend line equation. (Remember that our increment of
time is every six minutes, a unit of measure we have defined as a
“solex”.)
The North-South tracking data does not show the same linear trend
line progression. Instead, the North-South data is dithering around a
nearly constant value for most of the day. This result is ideal for our
120
purposes, because the implication is that the North-South axis doesn't
require simultaneous adjustment for this tracking method to work.
Since we have determined the East-West advancement rate necessary
for following the Sun, we can implement this tracking rate whenever the
Sun is found. We then have a good probability of continuing to track the
Sun, without the requirement to make other adjustments, or to perform
additional sky searching.
The linear East-West tracking rate can be calculated theoretically
from first principles. The apparent East-West motion rate of the Sun is
360 degrees per day. This works out to 1.5 degrees per solex. From there
we need only determine how many ADC counts equal 1.5 degrees.
Unfortunately, the ADC count rate is somewhat dependent on the North-
South position. (See Figure 4-15.) We have found that 3.3 ADC counts
per solex is a reasonable average number for general purpose operations.
Figure 6-7. Plotting the E-W data shows a day-long linear trend line.
121
You might be wondering how we can implement this incremental
tracking method in software. One approach is simply increment the East-
West position by 3.3 ADC units every six minutes. We found that there
were two problems with this simple approach. Both of these problems
were solved with careful software programming, as can be seen in the
source code for the subroutine "Inc_EW" in the appendix.
The first issue is, since we are limited to integer math, we must select
the "closest" integer for the incremental move, which in this case is three.
That means every move would be slightly undersized, since the targeted
move amount is 3.3 ADC units. A small amount of misalignment can add
up when numerous small adjustments are being made. We work around
the integer math limitation with a periodic step size adjustment, which
can be found by examining the subroutine details in the source code.
The second issue with execution is more subtle. Our tracker is pretty
good at making small moves, but the slight amount of error present in
position measurements will accumulate if we always take the starting
position as the point to move “from”. We would be much better off
defining a home base position at the start of a tracking series, and doing
the addition with respect to home base as the tracks are progressing.
Actually, that is exactly what we do in the software, which you will see if
you examine the math coding method in the subroutine.
122
The manual mode menu is shown in Figure 6-8. The manual mode
basically offers two types of actions: Jump to any state in the state
machine, or execute one of several subroutines for reporting information
or moving the tracker. For example, by sending the number “2” the
software will jump to the “Park” segment of the state machine. In that
state, the solar tracker moves to the parked position. After executing any
state machine segment, the program control returns directly to the user
command console. From there, you can execute another command, or
exit manual mode and proceed to automatic mode by typing “Q”.
It is important to keep in mind that executing any of the numbered
states is limited only to the actions of that state. After the state action is
performed, software control always returns to the console.
In a similar way, the reporting of individual data readings is
accomplished by typing any of the individual letters listed. For example,
type “L” to read and report the Sun level.
123
The tracker can also be moved while in manual mode. Moving the
tracker is accomplished by typing the first letter of any principal compass
direction. For example, typing “N” will move (or jog) the tracker five
ADC units to the North.
The manual mode of operation can be exited at anytime by typing
“Q” for quit. Exiting manual mode will put the tracker into automatic
operation. At that point, the only way to return to manual mode is to
reboot the Picaxe controller by removing and restoring the 12VDC
power. (Note: Power must be removed for a minimum of 10 seconds to
trigger a reset.)
The manual mode of operation will be most useful when you begin
field testing with your tracker. Manual mode is also useful if you decide
to start making changes in the software. With manual mode, you can test
the new changes as they are implemented.
124
Chapter Seven: Tracker Operation
This chapter explains how to put your solar tracker into operation.
Once you have the solar tracker running, you will start seeing the
different Sun search processes firsthand. At that point you may start to
wonder how searching is being done. In this chapter, we explain with
greater detail the logic of how the software is actually working.
Putting your solar tracker into operation is a relatively simple
process, and the only real distinction is whether you are doing a
temporary or a permanent setup. During construction and initial field
testing your setups will largely be temporary. For example, you may be
placing the solar tracker outdoors on a lawn or driveway for some quick
tests. Later in the project, you may opt for a more permanent installation.
The solar tracker software expects the North-South axis of the
hardware to be approximately aligned with compass directions North and
South. This is generally quite easy to do by eye, although a small
magnetic compass can be used as an aid for doing the setup, as shown in
Figure 7-1. Axis alignment is not required if you are only doing a “quick
test”. However, careful alignment is important if you plan to run for an
extended time period. That's because Sun position data will eventually be
collected and saved in non-volatile memory.
125
The software is written to perform a special routine when power is
applied for the first time. In the most usual case we expect that a person
applying power to the controller wants to see the tracker immediately
start moving and looking for the Sun. Accordingly, that is exactly what
the software has been programmed to do. However, after that first search,
the tracker will proceed to normal operation, which requires the detection
of sunlight above a minimum threshold before Sun searching starts
again. (Note: You can always trigger another Sun search by removing
12VDC power, waiting 10 seconds, and reapplying power.)
One pitfall to watch for during initial testing is the possibility of the
linear actuator motions being reversed. This is possible based on the
native polarity of the actuators you are using. The simplest way to test
for polarity is to attach the linear actuators and use the toggle switches to
compare the actual direction of motion, versus the labels on the PCB. If
the motion directions happen to be opposite the PCB labels, simply
reverse the actuator leads going to the screw terminal connectors.
1) Place the solar tracker on a smooth level surface with the base of
the unit facing due South. A compass may help for alignment.
2) Plug the 120VAC power supply cord of the solar tracker power
supply into an appropriate electrical outlet.
3) After 15 seconds, an automatic sky search routine will begin
moving the solar tracker to find the Sun.
4) If the Sun is found in Step 3, the next aiming update will happen
in 6 minutes. If the Sun was not found in Step 3, the tracker will
go to the Park position and wait for the Sun.
5) At dusk the solar tracker controller will automatically park the
tracker by moving to the home position.
6) The next day the solar tracker will automatically begin tracking
the Sun, once the minimum sunlight threshold is detected.
126
7) Eventually solar noon will be detected. Thereafter, the Sun’s
position data will be recorded in non-volatile memory.
Figure 7-2. Serial output data from solar tracker finding the Sun.
128
Here, we make a few more comments about the serial output data,
since space is limited for adding descriptive text in Figure 7-2.
Lines 29 and 30 are reporting the status of the nine software flags.
The flag logical values are listed in line 29, and the names of the flags
are listed in line 30. We see that two flags are "True = 1". The true flags
are "Cold Start" and "Range". This means the last attempt at a Cold Start
worked okay. The Range variable means the tracker position is within
the allowed range of tilt-tilt position space.
Line 38 reports a running total of daily solar tracker actions. The
daily totals are reset to zero at solar midnight. In our case, there has been
one successful MS (MiniSky) search. Subsequently, we would expect the
solar tracker to begin making tracking movements every six minutes. As
the tracks are made, they will be totaled and displayed as a running total.
When you are interpreting the serial data stream output, careful
examination of the source code (in the appendix) will explain any
specific questions you may have. The native command for any serial
output line can easily be found by looking for the "Sertxd" command in
the source code, or by using the Picaxe Programming Editor application.
Simple Search
Let’s start with what would probably be the worst possible approach
to finding the Sun. Since we know the travel limits of the tracker, we
could create a software routine that basically moves and looks at every
possible location, records the level of sunlight, records the position, and
“remembers” where the sunlight was found to be the brightest. This
routine would finish by going to the aiming position that had the
brightest measured sunlight. Certainly, this method would be thorough,
but it would also have the great disadvantage of taking a really, really
long time to accomplish! Additionally, we would be moving the solar
tracker a large amount of the time, which directly reduces the time
available for solar energy collection, and also creates equipment wear
and tear.
Returning to the example of trying to find the peak of a hill inside a
bounded search area, the approach we just described corresponds to
pacing across every square foot of area inside the boundary, trying to
find the highest spot.
130
Slope Driven Search
131
devised exhibits the monotonic signal behavior quite nicely and works
very well with this method.
The slope driven search works quite well, and in the majority of
cases it finds the Sun quickly and efficiently. However, there are a few
special situations that require something more with regard to sky
searching. In our discussion of the slope driven search, we conveniently
skipped over one important point: Where do we start searching from, and
does it matter with respect to the final results we will achieve?
Let’s return to our earlier example of searching for the peak of a hill
within a boundary. Suppose that inside the boundary of our search area
there are actually two hills with differing heights, as shown in Figure 7-3.
This second peak might be something as simple as a bright cloud. In that
case, our slope driven search might start near the smaller peak, follow the
slope up the smaller hill, and then mistake it for the true peak. In that
case, the search routine would stop searching and miss the larger peak.
We must intervene to prevent that situation.
132
At that point how do we know to continue searching, even though we
have found a local peak? The solution is to measure the height of the
peak and compare the result with a known minimum acceptable height.
In other words, we set a minimum Sun level that must be detected before
Sun searching is halted. That is the reason we have defined the variable
"Full_Sun". If the level is below the threshold, we simply don't stop
there. Instead, we continue looking for a peak that meets the minimum
required height.
But, if we are at a peak, even though it’s small, the simple slope
searching is not going to work. So what to do? Well, this is a case were
we must expand our search area and look over the full range, moving
from boundary to boundary over the full search area.
That is exactly the purpose of a full sky search. The full sky search is
designed to canvas the terrain within the boundary of the entire area. The
full sky search moves from boundary to boundary for both of the tilt-tilt
directions. The idea of this search is to make sure a local peak is not
mistaken for the highest true peak.
And so, while a full sky search is in progress, the computer software
is recording the sunlight readings and keeping a record of where the Sun
measured brightest. After the full search is done, the tracker returns to
that brightest location. This type of search takes longer, but is more
thorough. When the Sun is found, we can record the time and location,
and then in the future it is more likely that we can simply go to the
historical location. Recording the Sun’s location helps us avoid the
requirement of doing lengthy full sky searches in the future.
134
This is actually a part of the software that might be an opportunity for
other clever programming solutions based on historical averaging.
Stall Detection
Just because the linear trackers are sent a signal to move does not
mean the motion will start and continue indefinitely. Recall that the
linear actuators have internal limit switches, and they will stop if either
limit is reached. When a linear actuator stops at a limit switch, the only
direction of motion that is allowed is reversing course, in other words
going the other way.
So the question arises, how can we detect that the linear actuator
motion has stopped? Well, the first approach might be to measure the tilt
axis position, and then check the position again (at a later time) to see if
it has changed. This method works, but there are several significant
pitfalls in the practical execution:
Here is a full list of all the subroutines used in the software source
code, listed in alphabetical order. We also provide a short description of
each subroutine after the name. Full details for subroutines are in the
source code listing in the appendix.
Asterisk_Line: This subroutine prints the header name and date
message.
Auto_Level: This subroutine adjusts the Full_Sun variable setting to
accommodate local conditions that may be changing. The allowed range
of the Full_Sun variable is 150 to 200 ADC counts.
Check_Store_Data: This subroutine checks to determine if all the
necessary conditions have been met to store data in non-volatile memory.
Cold_Start: This subroutine finds the Sun without using any position
data from memory. The search is completely based on sunlight detection.
Counter_Reset: This subroutine resets the counter to zero on the
watchdog timer. (This is sometimes called "kicking the dog".)
Detect_Solar_Noon: This subroutine determines if all the conditions
have been met to declare that solar noon is now being detected.
Find_Integral: This subroutine steps through data indexes looking for
the next 30 minute multiple.
Full_Sky_Search: This subroutine moves the tracker to the limits of
travel for both tilt-tilt axes looking for, and recording, the location of
peak measured sunlight.
Full_Stop: This subroutine stops all motion in all directions.
136
Inc_EW: This subroutine incrementally moves the East-West tilt axis
another 3.3 ADC units from the last established home base position.
Initialize: This subroutine initializes the PICAXE-20X2 input and
output pins, and also initializes variables used in the program.
Integral_Test: This subroutine tests a data index to determine if it is
on a 30 minute boundary.
Jog_East: Moves the East-West tilt axis 5 ADC counts to the East.
Jog_EW: Moves the East-West tilt axis by the number of ADC
counts specified by the calling code.
Jog_North: Moves the North-South tilt axis 5 ADC counts to the
North.
Jog_NS: Moves the North-South tilt axis by the number of ADC
counts specified by the calling code.
Jog_South: Moves the North-South tilt axis 5 ADC counts to the
South.
Jog_West: Moves the East-West tilt axis 5 ADC counts to the West.
Keep_Time: This subroutine advances the clock one unit, and rolls
over to the next day if needed.
Mini_Sky_Search: This subroutine searches for the Sun. This
subroutine makes 2 attempts at slope-driven sky searching.
Mode_Check: This subroutine returns control to the serial port
console if manual mode is engaged, after a state or action is performed.
Move_East: This subroutine moves directly to a user specified
position, which is to the East from the present position.
Move_East_or_West: This subroutine decides whether the
Move_East or the Move_West subroutine should be called to make a
move.
Move_North: This subroutine moves directly to a user specified
position, which is to the North from the present position.
Move_North_or_South: This subroutine decides whether the
Move_North or the Move_South subroutine should be called to make a
move.
Move_South: This subroutine moves directly to a user specified
position, which is to the South from the present position.
137
Move_West: This subroutine moves directly to a user specified
position, which is to the West from the present position.
Park: This subroutine parks the solar tracker pointing to the South,
and at a 45 degree angle to the horizontal.
Peak_Detect: This subroutine compares the last Sun level reading to
the recorded peak level and updates the peak number if it is greater.
Range_Check: This subroutine makes sure the present tracker
position is within a range considered normal. No motion is allowed if
range is not normal.
Read_Current: This subroutine reads the voltage from the current
shunt and calculates current draw in units of milliamps.
Read_Data: This subroutine reads position data from the non-volatile
memory area based on the data index it is provided.
Read_Level: This subroutine reads the adjustable potentiometer on
the PCB. This is an 8 bit reading and is reported as ADC counts.
Read_Position: This subroutine reads the East-West and North-South
position from the accelerometer module and reports in ADC counts.
Read_Sun: This subroutine reads the sunlight level from the LED
sensor and reports in ADC counts.
Read_Temp: This subroutine reads the temperature from the sensor
on the PCB and reports in degrees Celsius with a range of 0 to 127 C.
Read_Voltage: This subroutine reads the power supply input voltage
using the voltage divider and reports in units of volts. This is an 8 bit
reading.
Report_Current: Sends a serial message reporting current level in
units of milliamps.
Report_Data: Calls the transmit data subroutine.
Report_Degrees_C: Sends a serial message reporting the temperature
in units of degrees Celsius.
Report_Flags: Sends a serial message reporting the status of all the 1
bit flags used by the controller program.
Report_Full_Sun: Sends a serial message reporting the current value
of the Full_Sun variable in units of ADC counts.
138
Report_Jumpers: Sends a serial message reporting the status of each
of the four option jumpers.
Report_Position: Sends a serial message reporting the current
position of the East-West and North-South tilt axes in units of ADC
counts.
Report_Pot_Level: Sends a serial message reporting the present
reading from the potentiometer. This is an 8 bit reading in ADC counts.
Report_Sun_Level: Sends a serial message reporting the present
reading of the LED sunlight sensor in units of ADC counts.
Report_Time: Sends a serial message reporting the present time as
measured by the solar clock.
Report_Totals: Sends a serial message reporting the number of Full
Sky Searches, Mini Sky Searches and Tracks that have been successful
today.
Report_Voltage: Sends a serial message reporting the present
reading from the voltage supply sensor in units of volts.
Serial_Com: This subroutine is the engine that drives the serial
communication interface. This interface is used during manual control
mode.
Serial_Report: This subroutine sends a serial message reporting all
the parameters which are available for transmission. This is basically a
serial output data dump.
Set_Home_Base: This subroutine reads the current tilt-tilt axis
positions and establishes the position as the home base for subsequent
tracking steps.
Slope_Detect: This subroutine performs dynamic testing of sunlight
level while the tracker is moving. The motion stops if the sunlight level
decreases.
Stall_Detect: This subroutine determines if the solar tracker may
have stalled during movement. Two criteria are checked: The rate of tilt-
tilt position change and the power supply current draw.
Store_Data: This subroutine stores data in non-volatile memory
using the time as a data index for the storage location.
139
Track: This subroutine tracks the Sun using incremental movements
of the East-West axis, and continues as long as the process is working.
Transmit_Data: This subroutine sends a serial message containing all
the non-zero data in the non-volatile memory storage array.
Wait_6_Min: This subroutine goes into a 6 minute wait state.
Wait_30_Min: This subroutine goes into a 30 minute wait state.
Wait_for_Sun: This subroutine checks the Sun level repeatedly,
waiting for the level to meet or exceed the minimum threshold to start
searching for the Sun.
Warm_Start: This subroutine attempts to find the Sun by using
historical data based on the solar time, using data from non-volatile
memory.
140
Chapter Eight: Payloads
141
Another payload that works well with a two axis solar tracker is a
solar oven. A solar oven is essentially an insulated box with a set of
reflectors for concentrating sunlight into a forward-facing clear window.
The box interior quickly becomes quite hot, such that it can be used to
cook the normal types of food suitable for an oven. An example of a
commercially available solar oven is shown in Figure 8-2. There are
numerous plans and projects available for building your own solar oven
using common everyday materials such as wood, window glass,
insulation and aluminum reflectors. This particular solar oven is
manufactured by American Educational Products, LLC.
Another payload that is ideal for a dual axis solar tracker is a Fresnel
lens. The Fresnel lens is a special type of optical concentrator, which
essentially is a flat sheet of clear plastic with concentric annular grooves.
142
Each groove is an individual optical facet that bends sunlight to a
common optical focus. Because of their construction, these lenses tend to
be fairly inexpensive. The effects of the focused sunlight can be quite
amazing. Fresnel lenses can be used with such things as thermoelectric
generators, or with special solar cells designed for use with concentrated
sunlight. Fresnel lenses can also be used for fabrication processes, such
as soldering and brazing. Artistic projects are another possibility with
Fresnel lenses, such as jewelry making or wood burning. A photo of a
Fresnel lens is shown in Figure 8-3. This particular lens was purchased
from D&D Surplus.
143
depends on the exact design of the parabola. You may already be
familiar with the parabola shape, since it is often used for satellite
television antennas. These antennas focus radio energy to a point, which
is where the receiving elements are usually located. We have even seen
some experimenters modify existing satellite dish TV antennas to work
as parabolic solar reflectors, as shown in Figure 8-4.
144
Another interesting class of solar payloads are the “vacuum tube”
style of thermal cooking containers. These devices are basically a
vacuum insulated glass flask with clear walls, designed such that
incoming sunlight is trapped inside by the black walls of the interior
cooking chamber, as shown in Figure 8-6. This type of collector could
easily be placed at the focus of a reflective collector, such as a parabolic
trough. Actually, the example in the photo would be almost a perfect fit
for the standard payload platform. Solid food or liquids can be placed
inside the container, since the capacity is approximately one gallon. The
glass walls facilitate easy cleaning. This particular device was
manufactured by Rand Solar, and was purchased on Ebay.
145
Another interesting class of solar tracker payloads are thermoelectric
generators. These devices convert heat directly into electricity using the
thermoelectric effect. An example of a thermoelectric generator,
originally intended for operation with a candle, is shown in Figure 8-7.
The thermoelectric element, which generates the electricity, is
sandwiched between the upper heat source and the lower heat sink. The
candle is the intended source of heat in this example, but the candle
could easily be replaced with focused sunlight, such as from a Fresnel
lens.
Solar electric panels are another common payload for solar trackers.
Precision aiming is generally not required for solar panels, however there
are some applications where early morning or late day sunlight collection
is especially important. Solar panels have the additional advantage of
directly producing DC electrical power. The generated power can be
used to operate the tracker. We show an example of a solar panel
mounted to a reduced-size payload platform in Figure 8-8.
146
Figure 8-8. Solar electric panel for generating electricity.
Whichever payload you choose to use with your dual solar axis
tracker, the flexibility and adaptability of the 80/20 structural framing
system simplifies construction. You will find an almost unimaginable
assortment and variety of structural framing options available. We have
installed and used 80/20 components outdoors in Michigan weather for
several years without adverse corrosion or deterioration.
147
148
Chapter Nine: New Directions
Now that you have mastered the basics of a dual axis solar tracker
design, we are guessing you are already considering new ideas and
directions for additional exploration. Let us help with some ideas for
your consideration.
There are numerous areas for investigation and improvement in the
operation of the baseline dual axis solar tracker. Here are a few ideas for
things to explore:
1) There are various parameters in the source code that are assigned
constant values during the "Initialize" routine. It’s possible these
values could be tweaked to improve the overall performance of
the solar tracker.
2) The routine for finding the Sun from a cold start is a combination
of slope-driven searching, full-sky searching and optimization
jogging. There is nothing especially unique about our choices
for doing the searches, and you may have some ideas for
improvements, such as the search order, motion ranges and
methods of searching.
3) We have not done everything possible with the information
provided by the various sensors. For example, the current
readings, temperature readings and voltage readings are all
available. The information the sensors provide might be used for
various other useful purposes. An automatic “low voltage
shutdown” is one possibility, and an automatic “high
temperature shutdown” is another possible improvement.
4) Build a bigger solar tracker! Actually, that is pretty easy to do,
since we have built the tracker in this book using the 1010
extrusion from 80/20. They offer a very similar extrusion called
“1515” extrusion, which is 50% larger. They also have other
structural elements for building something even larger than that.
5) Connect the solar tracker to a network. Since we have included
the basic serial communication capability, an interesting project
149
would be to design a computer interface on a host computer that
is web-enabled, or has other intelligent features.
6) Build a Heliostat. This is certainly in the category of an
advanced project, but the basic hardware and sensors are there to
make it possible. You have the hardware to move the tracker
remotely, and the sensor system in place to know the aiming
direction. For example, a host computer could calculate the
Heliostat aim required and remotely instruct the tracker to move
to those coordinates.
7) Since you can communicate with the solar tracker using serial
communication, it is certainly possible to use alternative
handheld devices for the interface. For example, it should be
possible to use any handheld device that is capable of emulating
serial communication, such as a tablet, netbook, or even an LCD
serial display.
8) Think “out of the box” with respect to the payloads. There are an
abundance of possibilities worth considering, such as
thermoelectric generators, solar furnaces, heat engines, cookers,
ovens, lenses, optical elements, reflectors, absorption
refrigerators, molten heat storage salts, etc.
9) Build an array of trackers. There are many possibilities with this
idea. When you think about it, with an array of these trackers
you could have one unit as a “master” controller, and “slave” the
other trackers to the main controller for working in unison. (i.e.
One tracker finds the Sun, and the other trackers are sent to the
same aiming coordinates.)
10) Add some additional inputs to the controller. For example, there
are two option jumpers on the PCB that are not used by the
software. These could be used to adjust operational settings.
Another idea would be connecting switches to the option
jumpers. For example, you could add a “wind paddle” that trips a
switch during high wind conditions to safely park the tracker.
11) The data section of the non-volatile memory is filled by the
controller software as the Sun is detected and tracked during
150
normal operation. The data accumulates over successive days. In
principle the data area could be “programmed” at the same time
the source code program is downloaded to the IC. You might
consider logging the data and saving it in a file for that purpose.
In essence, you would be getting a “jump start” on the Sun
position learning process.
12) Use the potentiometer to set a working variable related to tracker
operation. Our original thought was the potentiometer could be
used to set the default "Full_Sun" variable. That would be an
easy way to make the Sun detection searching more or less
sensitive.
13) The accelerometer module is presently only used for two axis
readings, but there is also a third axis available from the device.
It is possible to mathematically combine all three readings for
improved angular position accuracy. (See the application notes
available from the IC manufacturers.) The details get
complicated, but the potential is definitely there to make some
improvements.
14) We have chosen the PICAXE-20X2 microcontroller for this
project, but there are other Picaxe devices available with
different capabilities. By starting from this basic framework it
would be fairly easy to move up to a different device with
increased computational power, or other useful features.
15) Create a stand-alone program on a host computer for monitoring
and controlling the solar tracker. An example of a prototype user
interface for such a program in shown in Figure 9-1. In this
example, you will see we have real-time reporting of aim, solar
time, sun level, temperature, voltage and other information.
16) Consider using a different microcontroller which has the ability
to do floating point math. In that case, you might decide to
include calculations involving the equation of time, astronomical
coordinates, global positioning, etc. One possibility is the
PIC18F4550 microcontroller from Microchip Technology, Inc in
Chandler, Arizona. One very capable version of BASIC for
151
programming this particular device is the "Proton BASIC
Compiler" from Crownhill Associates, Ltd in the United
Kingdom.
17) The linear tracking adjustment rate of 3.3 ADC units per solex is
an “average” working value. This tracking adjustment rate can
also be calculated theoretically. The software could certainly be
improved to include a variable tracking rate which is dependent
upon the North-South tilt platform position.
Our hope is that this solar tracker project will form the basis for
additional exploration and development. As you make changes and
improvements you may want to share your ideas and progress with other
hobbyists. In that case, please consider sharing the information with us,
so we can post the details on our website.
Also, we always enjoy seeing photos of your projects. One thing we
have learned over the years is that our customers are really smart people!
We are constantly amazed at what is achieved and the level of detail,
152
precision and thought our customers put into their projects. We look
forward to seeing all the new directions this project will take.
153
154
Chapter Ten: Special Information
Troubleshooting
This book would not be complete without saying a few things about
troubleshooting. The science of analyzing symptoms and finding failure
modes is a special branch of Engineering called “Failure Analysis
Engineering”.
Briefly, the approach to fixing something that’s not working
correctly comes down to identifying the symptom, and then exploring the
possible failure modes that could be the cause of the symptom. Let’s
look at a few examples of things to double-check and watch out for:
1) Does anything look or smell wrong on the controller board? That
may seem like a silly question, but really, it's amazing the number of
things that can be detected simply by looking carefully. The same goes
for electrical components damaged by heat. Overheated components
often have a characteristic smell which can point you to the problem.
2) Are you sure the controller is receiving power? The green LED on
the PCB indicates power status. The green LED will only illuminate
when three conditions are true: a) The 12VDC power is available, b) The
5VDC supply circuit is working and, c) The reset circuit is working
properly. Use a multimeter to check each of the subsystems if the green
LED is not illuminated.
155
3) Make sure that you have not left either of the toggle switches in an
"ON" position. A misplaced toggle switch setting will cause the axis in
question to stop working correctly with the controller.
4) Don't forget to use the toggle switches to double-check that you
have the polarity of the linear actuators connected correctly.
5) Be careful connecting the wiring to the green screw terminals for
the linear actuators, LED sensor and 12VDC power supply. It’s possible
for the wires to appear as if they are inserted correctly, when in fact they
aren’t actually making electrical contact. This happens more frequently
than you might expect.
6) If necessary, enter the manual mode on the controller and try a
few simple motions, and check the data reporting as part of the
diagnostics. The manual mode is available for the first 15 seconds after
the controller is energized. Enter manual mode by sending the "M"
command using the serial communication console.
7) Carefully examine the serial output log from the controller. The
output log uses shorthand notations, as has been previously explained.
Also, don't hesitate to add additional lines of code to report additional
information if you think it may help. Verbose diagnostic output
commands can always be removed later (or commented-out) after having
served their diagnostic purpose.
IC Datasheets
Southern Hemisphere
List of Suppliers
We are going to assume you are on a budget and want to build this
project with a minimum of expense. Some of the least expensive sources
157
for items can be found by doing online searches at marketplaces such as
Ebay and Amazon. Although this is often the best way to get the lowest
price, it also can introduce delays in shipping, especially if the parts are
coming from faraway geographical locations. Also, substituting parts
always leads to the question of whether the parts are truly “equivalent”,
especially if you start running into problems of some sort.
At the same time, we don’t want to list short-lived companies that
may exist when we go to press, but soon disappear and become a dead-
end source for you. Therefore, we are going to list some well-known
companies that can be relied on to source the parts needed for this
project, and then allow you to make substitutions as desired, and as the
situation warrants.
158
Pololu Corporation of Las Vegas, Nevada. This company
specializes in mechanical parts for robots, which includes linear
actuators and actuator brackets. Visit them online at
http://www.pololu.com
Phanderson.com of Bel Air, Maryland. This company specializes
in electronic components and kits, with an emphasis on the
Picaxe line of microcontrollers. Visit them online at
http://www.phanderson.com
Harbor Freight Tools of Calabasas, California. This company
specializes in inexpensive tools. They offer an inexpensive
multimeter, which sometimes is offered free with any purchase.
Visit them online at http://www.harborfreight.com
Mouser Electronics, Inc. of Mansfield, Texas. This company
specializes in electronic components. Visit them online at
http://www.mouser.com
CompuPhase (Informatie-Technologisch Bureau CompuPhase)
of Bussum, Netherlands. This company offers the free Termite
serial communication software. Visit them online at
http://www.compuphase.com
Revolution Education, LLC of England. This company offers the
Picaxe Programming Editor Software, and other items related to
the Picaxe devices. Visit them online at: http://www.picaxe.com
MTM Scientific, Inc. of Clinton, Michigan. This company
specializes in scientific kits and supplies for technical hobbyists,
with a special focus on solar tracker kits and other items related
to the project described in this book. Visit them online at
http://www.mtmscientific.com
159
160
Chapter Eleven: Project Quick Start
Building a dual axis solar tracker is a major project, and it may help
to breakdown the project execution into manageable tasks. Here we
present a specific plan of action. The following activities are the steps we
suggest you take to proceed in an orderly way with the construction of
your dual axis solar tracker project.
In this step, you want to make sure the limits of travel of the
actuators can safely be used with your tilt-tilt frame. The motion of the
actuators should be adjusted by moving the bracket locations. Adjust the
mounting brackets such that the linear actuators stop before they run into
something, at either limit of travel. During this phase you can run the
actuators to-and-fro using whatever 12VDC battery or power supply you
161
may have available. You don’t need a controller for this activity: Simply
use the bare wire leads. The actuators are rugged devices, and they aren’t
easily damaged.
This is going to be the main computer you use for the project. We
suggest using an older laptop with a built-in 9 pin serial port. You can
use an old desktop computer if you prefer. You need to load the
following software on the computer: Picaxe Programming Editor, and
Termite Serial Port Monitor. The Expresspcb software is also useful if
you plan to design your own circuit board or create electrical schematics.
The circuit board is the way to go for this part of the project. Another
workable (but more difficult) option is to assemble the circuit using a
162
prototype board. Another option is to lay out your own printed circuit
board design using the electrical schematic we’ve provided in Figure 3-
26.
Now is the time to establish two way serial communication with the
Picaxe microcontroller on the printed circuit board. After communication
is established, use the serial link to download the operating program.
Once this is established, you can test the operation of the board by
entering manual mode on the software. The manual mode option is only
offered during the first 15 seconds after power is applied to the
controller.
Your first test combining the controller with the frame can be quite
basic. It is not necessary to have an enclosure for this part of the testing,
but make sure that no electrical parts on the PCB are “shorting out” by
contacting the metal frame. The first test is to make sure the wiring to the
actuators is correct by using the toggle switches. From there, you can
connect a computer and test the operation using the manual mode and
serial communication.
163
Ruggedize Solar Tracker
In this step, you add the enclosure and other parts to protect your
solar tracker from the weather. The circuit board must be protected from
the weather. You can also route the wiring to be neat and tidy, with
cables and wiring secured using cable ties, etc.
Add Payload
In this step, you attach your payload to the frame. If you have started
with only the "barebones" frame, you may want to upgrade to a full
platform at this point, or switch to a custom platform based on your
intended payload and design goals
At this point it is almost inevitable that you will have ideas about
changing or modifying the software. That’s absolutely no problem, and
it is actually easy to do by using the serial communication you have
incorporated. Always keep plenty of source code backups so you can
return to an earlier version if you make a mistake.
If you do improve the code, please send a copy and description of the
improvements to us, so we can make it available to the wider solar
tracker project development community.
164
Appendix: Source Code Listing
This appendix contains the complete source code listing of the dual
solar tracker control program for the PICAXE-20X2 microcontroller.
Note: You can also download a source code listing of this file from:
http://www.mtmscientific.com/stmax.html
165
Symbol Position_EW_Max = W12 'Location of Max Sun Sense in EW tilt axis
Symbol Data_Index = B26 'Used for data read/write in nonvolatile memory
Symbol Half_Hour_Index = B27 'Index for 30 Min Wait
Symbol Mini_Sky_Pause = W14 'Time delay to implement at various phases of searches
Symbol Position_NS_Start = W15 'Start Position for Searching on NS tilt axis
Symbol Position_EW_Start = W16 'Start Position for Searching on EW tilt axis
Symbol Sun_Sense_Max = W17 'Value of Max Sun Sense during a search
Symbol Solar_Clock = B36 'Time. Reckoned in 'solexes' (6 minutes), Noon=120
Symbol Voltage = B37 'Power Supply Voltage, Max 255, Units of Volts
Symbol Sun_Sense_Base = W19 'Sun Level baseline comparison when optimizing
Symbol Jog_Increment = B40 'Motion increment for Jogging search, Max 255
Symbol Full_Sky_Increment = B41 'Motion increment for Full Sky search, Max 255
Symbol Original_Increment = B42 'Place for temporary storage of regular Jog increment
Symbol Level = B43 'Used to read the ADC level of the Potentiometer, Max 255
Symbol Inc_Index = B44 'Variable used for sub-integer incremental tracking moves
Symbol Index = B45 'General purpose index for loops, Max 255
Symbol Dusk_Sun = B46 'This sun level must be exceeded to exit waiting for sun
Symbol ADC_Loops = B47 'Used as # Readings for ADC averaging (Unless Specified)
Symbol ADC_Sum_1 = W24 'Used as running total for ADC reading averages
Symbol ADC_Sum_2 = W25 'Used as running total for ADC reading averages
Symbol Stall_Index = B52 'Loop Index when checking for stalled motion
Symbol Command = B53 'Used to store received Command Character (Single Character!)
Symbol Full_Sun = W27 'Threshold for storing data and detecting Solar Noon
'Note: W27 was the last available normal variable memory space!
Symbol Mini_Skys = S_W0 'System Variable Word, Temporary use
Symbol Full_Skys = S_W1 'System Variable Word, Temporary use
Symbol Tracks = S_W2 'System Variable Word, Temporary use
Symbol Move_N = C.0 'Relay control channel
Symbol Move_S = C.1 'Relay control channel
Symbol Move_E = C.2 'Relay control channel
Symbol Move_W = C.3 'Relay control channel
Symbol Watchdog_Reset = B.7 'Counter Reset (Watchdog Timer)
'Note: Jumper pin inputs & default variables names are assigned during Initialize Routine
'**********************************************************************
'This is the main state machine program segment for automatic tracking.
'See book "Build a Solar Tracker" for flowchart and details of routine.
'**********************************************************************
166
State_1:
Call Initialize
Call Mode_Check 'Exits if Manual Mode
State_2:
'Note: If tracker is already close to Park, this motion is skipped.
Call Park
Call Mode_Check 'Exits if Manual Mode
State_3:
Call Wait_for_Sun
'Note: At 1st power sun waiting is skipped (Tracker moves when plugged-in)
Call Mode_Check 'Exits if Manual Mode
State_4:
Call Warm_Start 'At return if Warm_Start_Flag=1 was OK (Sun was found)
Call Mode_Check 'Exits if Manual Mode
If Warm_Start_Flag = 1 then call Set_Home_Base 'Position used for subsequent Tracking
If Warm_Start_Flag = 1 then goto State_6 'Skip Cold Start if OK
State_5:
Call Cold_Start 'If Cold_Start_Flag = 1 was OK (Sun Detected)
If Cold_Start_Flag = 1 then call Set_Home_Base 'Position used for subsequent tracking
Call Mode_Check 'Exits if Manual Mode
State_6:
Call Detect_Solar_Noon
Call Mode_Check 'Exits if Manual Mode
State_7:
Call Check_Store_Data
Call Mode_Check 'Exits if Manual Mode
State_8:
If PINC.4 = 1 then call Wait_6_Min 'No Jumper, High = 1 = Normal
If PINC.4 = 0 then call Wait_30_Min 'With Jumper, Low = 0 = Slow
'Install Option Jumper 4 to make less frequent motion updates....
'Note that above does not affect the Wait for Sun checking rate. (Variable)
'Note that above does not affect the behavior when first energizing tracker.
Call Mode_Check
If Warm_Start_Flag = 0 AND Cold_Start_Flag = 0 then goto State_2
'Above test should be OK while tracking, since Warm/Cold flags will not be changed...
'Note that Tracking does not start unless there has been successful sun detection...
State_9:
Call Track 'If Track_Flag = 1 unit is Tracking sun OK (Sun Detected)
Call Mode_Check 'Note that in Manual Mode Tracking is 1 iteration
'Don't be too quick departing Tracking routine. Sun was recently detected!
'Make several attempts to continue with tracking to avoid Full Sky Searches
If Track_Flag = 0 then
Track_Attempts = Track_Attempts + 1
If Track_Attempts = 3 then
167
Track_Attempts = 0 'Reset for next instance of Tracking loop
Goto State_2 'Exit tracking after 3 attempts.. Go to Cold/Warm Starts
Endif
Goto State_6 'Try to continue Tracking until maximum Track Attempts
Endif
'*************************************************************************
'End of Main State Machine. Here are subroutines and other support code.
'*************************************************************************
Asterisk_Line:
Sertxd("*STMAX by MTM VER:2-17-2016*",13,10)
'Date is included for software revision control
Return
Auto_Level:
'This routine automatically adjusts the Full_Sun light level variable
'This routine resets to initial conditions when Dusk_Sun is detected.
'Note that initial conditions must agree in 2 places in this code!
'This subroutine is called whenever a light level measurement is made
'Note that Dusk_Sun and Full_Sun are set at power-on by Initialize subroutine
'Dynamically setting sun level goal higher prevents early search terminations
'Resets Full_Sun level to initial condition if Dusk_Sun is detected (Night, etc)
If Sun_Sense <= Dusk_Sun then
Full_Sun = 150
Endif
'Can't do scratchpad math with Sun_Sense (Called by Sun_Sense)
'Note that this routine allows Full_Sun to decrease in 1/3 window
If Sun_Sense > Full_Sun then
Full_Sun = Sun_Sense * 2
Full_Sun = Full_Sun / 3
Endif
'Impose allowable range limits for Full_Sun (150-200)
If Full_Sun < 150 then
Full_Sun = 150
Endif
If Full_Sun > 200 then
Full_Sun = 200
Endif
168
Return
Check_Store_Data:
Sertxd("Chk_Str_Dat", 13, 10)
'This subroutine determines if all conditions have been met to store data...
'First, check if the Solar Clock has been set since power applied
If Clock_Set = 0 then goto Check_Store_Data_Exit
'Second, check if the time is an increment of 30 minutes (5 multiple)
Data_Index = Solar_Clock 'Integral Test uses Data_Index. Hence assignment...
Call Integral_Test
If Integral = 0 then goto Check_Store_Data_Exit
'Third, check if threshold for full sun has been attained
Call Read_Sun
If Sun_Sense < Full_Sun then goto Check_Store_Data_Exit
'All conditions have been met. Proceed to store information
Call Store_Data
Return
Check_Store_Data_Exit:
Return
Cold_Start:
Sertxd("C_Start", 13, 10)
'This subroutine starts from scratch. No time and position data to leverage
'Note: Either of these routines must find sun to be successful and set flag
'Cold Start uses 2 methods to find sun: Mini_Sky_Search & Full_Sky_Search
'Mini_Sky is simplistic: 2 passes. Slope driven optimization on both axes
'Full_Sky_Search moves full range on both axes. Records peak and returns to it.
Cold_Start_Flag = 0
Mini_Sky_Pause = 900 'The 1st pass uses a coarse grid method to search
Sertxd("M_S 1st", 13, 10)
Call Mini_Sky_Search 'This is a Slope-Driven search that may or may not work
Call Read_Sun 'Skip 2nd Pass if 1st Pass works OK
If Sun_Sense > Full_Sun then goto Skip_2nd_Pass
Mini_Sky_Pause = 450 'The 2nd pass uses a finer grid method to search
Sertxd("M_S 2nd", 13, 10)
Call Mini_Sky_2nd_Pass 'Note that the 2nd pass does NOT start from Park
Call Read_Sun
'Note: Optionally more Mini_Sky passes could be added to fine-tune aiming
If Sun_Sense < Full_Sun then goto Mini_Sky_Search_Failure
Skip_2nd_Pass:
Cold_Start_Flag = 1 'All conditions OK: Mini Sky Cold Start Search worked!
Mini_Skys = Mini_Skys + 1 'Running Total of Mini Sky Starts
Sertxd("M_S OK", 13, 10)
Return
169
Mini_Sky_Search_Failure:
Sertxd("M_S Fail", 13, 10)
Call Full_Sky_Search 'Note: Performs full E/W then full N/S motion pattern...
'After Full_Sky_Search we may do a small dither around position for peaking.
'This Jogging is an aim tweak. Skip Jogging if Full Sky has found Full Sun
Call Read_Sun
If Sun_Sense > Full_Sun then goto Skip_Jogging
Call Jog_EW
Call Jog_NS
Skip_Jogging:
Call Read_Sun
If Sun_Sense < Full_Sun then goto Cold_Start_Exit
Cold_Start_Flag = 1 'All conditions OK: Cold Start worked!
Full_Skys = Full_Skys + 1 'Running Total of Full Sky Starts
Return
Cold_Start_Exit:
Return
Counter_Reset:
'This routine resets the counter on the Watchdog Timer
High Watchdog_Reset
Pause 10 'Pause for 10 Milliseconds
Low Watchdog_Reset
Return
Detect_Solar_Noon:
Sertxd("Det_S_Noon", 13, 10)
'This subroutine determines whether Solar Noon has been detected and sets clock
'It is always possible to detect and set the clock for Solar Noon
'Which means: A Cold Start, A Warm Start, or while Tracking
'Window for Solar Noon is near level for E/W tilt axis on tracker
'Initialize Solar Noon Flag as false.
Solar_Noon = 0
'FIRST check if Sun Level is above threshold for detection
Call Read_Sun
If Sun_Sense < Full_Sun then goto Detect_Solar_Noon_Exit
'SECOND, check if E/W position is near level (Level = 338)
'Note: Limits for detect range are hard-coded here (333 & 343)
'Result is a Solar Noon window of +/- 5 ADC counts for E/W
Call Read_Position
If Position_EW < 333 OR Position_EW > 343 then goto Detect_Solar_Noon_Exit
'THIRD, Solar Noon has been detected, therefore set the clock and flags
Sertxd("Noon OK", 13,10)
Solar_Clock = 120 'Solar Noon is 120
170
Solar_Noon = 1 'Solar Noon has been detected
Clock_Set = 1 'Clock has been set since power applied
Return
Detect_Solar_Noon_Exit:
Sertxd("Noon Fail",13,10)
Call Report_Position
Call Report_Sun_Level
Return
Find_Integral:
'This subroutine finds the next Data_Index that is a 30 minute Integral
'This routine should always result in finding an Integral Data Index
For Index= 1 to 4
Call Integral_Test
If Integral = 1 then goto Find_Integral_Exit
Data_Index = Data_Index + 1
If Data_Index >= 240 then goto Zero_Exit
Next Index
Find_Integral_Exit:
Return
Zero_Exit:
Data_Index = 0
Return
Full_Sky_Search:
Sertxd("F_S Search", 13, 10)
'This subroutine does a programmed search over full sky
'This subroutine is simply a Jog with larger increments & starts from Home
'This subroutine always finishes by moving to the peak detected sun position
'Note: We always start a Full Sky Search from the Parked position
Call Park
Original_Increment = Jog_Increment
Jog_Increment = Full_Sky_Increment
'Start with E/W portion of Full Sky Search
'There is more room to move EW. Increase motion for E/W: Hard Coded
Jog_Increment = Jog_Increment + 60
Call Jog_EW
'Proceed with N/S portion of Full Sky Search
'There is less room to move NS. Decrease motion for N/S to Original.
Jog_Increment = Jog_Increment - 60
Call Jog_NS
Full_Sky_Search_Exit:
'Return Jog Increment to original value
Jog_Increment = Original_Increment
171
Return
Full_Stop:
'This subroutine stops the Solar Tracker & pauses briefly
Low Move_N
Low Move_S
Low Move_E
Low Move_W
'Provide a short pause for motion to stop as safety precaution
Pause 200 'This is 200 milliseconds
Return
Inc_EW:
Sertxd("Inc_EW", 13, 10)
'This subroutine moves 3.3 ADC units West from the home base position
'This subroutine moves East if the Option Jumper 5 is present on PCB
'Note: The direction of movement depends on the Option Jumper 5 setting
'No Jumper PINC.5=1 (Northern) & With Jumper PINC.5=0 (Southern)
Call Read_Position
Position_NS_Start = Position_NS
Position_EW_Start = Position_EW
If PINC.5 = 1 Then
Position_EW_Target = Position_Track_Home_Base + 3 'Ideally 3.3 / See 'If' below...
End If
If PINC.5 = 0 Then
Position_EW_Target = Position_Track_Home_Base - 3 'Ideally 3.3 / See 'If' below...
End If
Inc_Index = Inc_Index + 1 'Incremental index used for sub-integer moves
If Inc_Index = 3 Then
Inc_Index = 0 'Every 3rd pass, reset the index
If PINC.5 = 1 Then
Position_EW_Target = Position_EW_Target + 1 'This is the 3rd pass tweak
End If
If PINC.5 = 0 Then
Position_EW_Target = Position_EW_Target - 1 'This is the 3rd pass tweak
End If
End If
Call Move_East_or_West
Return
Initialize:
Sertxd("Init", 13, 10)
'Setup Inputs, Outputs and ADC Channels for Picaxe-20X2 microprocessor
'Refer to Revolution Education, LLC data sheets to understand this process.
172
Input C.4, C.5, C.6, C.7 'These are Jumper Inputs (4,5,6 & 7 as Variables PINC.4, etc)
'PINC.4: 6 MIN=True=No Jumper=High=1 & 30 MIN=False=With Jumper=Low=0
'PINC.5: Not Used
'PINC.6: Not Used
'PINC.7: Not Used
Output C.0, C.1, C.2, C.3, B.7 'These are the 4 relays and Reset Pin
Let Adcsetup = %0000010001110110 'ADC 1,2,4,5,6,10 - B.0,B.1,B.2,B.3,B.4,B.5
Sun_Sense_Max = 0
Solar_Clock = 0
Clock_Set = 0 'Clock has not been set yet
Jog_Increment = 15 'How many ADC counts to move during a Jog Search
Full_Sky_Increment = 65 'How many ADC counts to move during a Full Sky Search
Full_Sun = 150'Threshold for storing data and detecting Solar Noon
'Note that Full_Sun number 150 is also hard coded in Auto_Level subroutine
Dusk_Sun = 20 'When waiting for sun this level must be exceeded to start
ADC_Loops = 5 'Number of ADC readings to acquire and average for any measurement
ADC_Sum_1 = 0 'Running total during ADC readings
ADC_Sum_2 = 0 'Running total during ADC readings
Stall_Index = 0 'Index for Stall Detection
Inc_Index = 0 'Index used for sub-integer tracking moves
Track_Attempts = 0 'Number of consecutive Tracking attempts
Boot_Flag = 1 'System always starts as freshly booted, False after first sun detect
Range_Flag = 1 'True if N/S and E/W position readings are within range
Park_Flag = 0 'Set to True at first Park, Set False by any N,S,E or W motion
Mini_Skys = 0 'Number of Mini Sky Searches that were OK
Full_Skys = 0 'Number of Full Sky Searches that were OK
Tracks = 0 'Number of Track movements that were OK
Return
Integral_Test:
'This subroutine tests if time is an integral of 30 minutes
'Note that the test is performed on variable Data_Index
Integral = 0
For Index = 0 to 240 Step 5
If Data_Index = Index then goto True
Next
Return
True:
Integral = 1
Return
Jog_East:
'This is used for Manual Mode jogging (Serial Command)
Call Read_Position
173
Position_EW_Target = Position_EW - 5
Call Move_East_or_West
Call Mode_Check 'Returns to Command Prompt
Return
Jog_EW:
Sertxd("J_EW", 13, 10)
'This subroutine always jogs from the present position...
'This subroutine always moves to the peak detected sun position
'The Sun level at start position is taken as baseline for improvement
Call Read_Position
Position_NS_Start = Position_NS
Position_EW_Start = Position_EW
'Establish baseline for Sun level we are attempting to increase
Call Read_Sun
Sun_Sense_Base = Sun_Sense
Sun_Sense_Max = Sun_Sense_Base
'Jog to the East first
Position_EW_Target = Position_EW_Start - Jog_Increment
Call Move_East_or_West
'Jog to the West second
Position_EW_Target = Position_EW_Start + Jog_Increment
Call Move_East_or_West
If Sun_Sense_Max > Sun_Sense_Base then goto Move_to_Peak_EW
'Return back to starting position if no improved sun level position found
Position_EW_Target = Position_EW_Start
Call Move_East_or_West
Return
'Move to the new position when an improved sun level position is found
Move_to_Peak_EW:
Position_EW_Target = Position_EW_Max
Call Move_East_or_West
Return
Jog_North:
'This is used for Manual Mode jogging (Serial Command)
Call Read_Position
Position_NS_Target = Position_NS - 5
Call Move_North_or_South
Call Mode_Check 'Returns to Command Prompt
Return
Jog_NS:
Sertxd("J_NS", 13, 10)
174
'This subroutine always Jogs from the position it is at now...
'This subroutine always moves to the peak detected sun position
'Sun level at starting position is taken as baseline for improvement
'Limits of Jog can vary based on calling routine via Jog_Increment adjustment
Call Read_Position
Position_NS_Start = Position_NS
Position_EW_Start = Position_EW
'Establish baseline for Sun level attempting to increase
Call Read_Sun
Sun_Sense_Base = Sun_Sense
Sun_Sense_Max = Sun_Sense_Base
'Jog to the North first
Position_NS_Target = Position_NS_Start - Jog_Increment
Call Move_North_or_South
'Jog to the South second
Position_NS_Target = Position_NS_Start + Jog_Increment
Call Move_North_or_South
If Sun_Sense_Max > Sun_Sense_Base then goto Move_to_Peak_NS
'Return back to starting position if no improved sun level position found
Position_NS_Target = Position_NS_Start
Call Move_North_or_South
Return
'Move to the new position when an improved sun level position is found
Move_to_Peak_NS:
Position_NS_Target = Position_NS_Max
Call Move_North_or_South
Return
Jog_South:
'This is used for Manual Mode jogging (Serial Command)
Call Read_Position
Position_NS_Target = Position_NS + 5
Call Move_North_or_South
Call Mode_Check 'Returns to Command Prompt
Return
Jog_West:
'This is used for Manual Mode jogging (Serial Command)
Call Read_Position
Position_EW_Target = Position_EW + 5
Call Move_East_or_West
Call Mode_Check 'Returns to Command Prompt
Return
175
Keep_Time:
Sertxd("Keep_Time", 13, 10)
'This subroutine advances clock and rolls over the day if needed
'Midnight is 0, Solar Noon is 120 (Measured in solexes = 6 minute)
'See book for a full discussion of timekeeping and units.
Solar_Clock = Solar_Clock + 1
If Solar_Clock = 240 then goto Rollover
Return
Rollover:
Solar_Clock = 0
'This would be place to insert a variable for counting number of days
Return
Mini_Sky_Search:
Sertxd("M_Sky",13,10)
Call Park
'First pass of Mini_Sky is from the Parked Position
'Start motion and continue motion while sun increases, with a double-back to be sure
'This process is strictly Slope-Driven. Note However: Motion Stalls are detected.
Mini_Sky_2nd_Pass: 'Entry point for the 2nd Pass
'Note: 2nd Pass of Mini_Sky is from the ending location of 1st Pass
'2nd Pass is skipped in calling routine if Sun_Level is greater than Full_Sun
Sertxd("MSN", 13, 10)
Park_Flag = 0 'Motion imminent
High Move_N
Call Slope_Detect
Call Read_Sun
Sertxd("MSS", 13, 10)
Park_Flag = 0 'Motion imminent
High Move_S
Call Slope_Detect
Call Read_Sun
Sertxd("MSE", 13, 10)
Park_Flag = 0 'Motion imminent
High Move_E
Call Slope_Detect
Call Read_Sun
Sertxd("MSW", 13, 10)
Park_Flag = 0 'Motion imminent
High Move_W
Call Slope_Detect
Mini_Sky_Exit:
Return
176
Slope_Detect:
'This routine is always entered with tracker motion in progress!
'This routine always exits with the tracker motion fully stopped
'Exit Cases: 1)Motion stalled 2) Full Sun detected 3) Negative Sun step
Stall_Index = 0 'Set Stall Index for counting in Stall_Detect
Call Read_Sun 'Establish sunlight baseline
If Sun_Sense > Full_Sun then goto Trigger_Test
Do
'This offset in Sun_Sense_Base is allowance for noise in Sun_Sense signal
Sun_Sense_Base = Sun_Sense - 1
Pause Mini_Sky_Pause 'Time delay to allow tracker motion & Sun_Sense change
Call Stall_Detect
If Stall = 1 then goto Slope_Detect_Exit 'Exit Case 1
Call Read_Sun
If Sun_Sense > Full_Sun then goto Trigger_Test 'Exit Case 2
Loop While Sun_Sense >= Sun_Sense_Base 'Exit Case 3
Slope_Detect_Exit:
Call Full_Stop 'Stops N,S,E and West (All Cases)
Return
Trigger_Test:
'This routine rapidly tests Sun_Sense Level for improved exit point
'(This routine provides possibility of doing better than Full_Sun level)
Sun_Sense_Base = Sun_Sense
Pause 100 'Use a short time delay for rapid sun reads, trending and exit
Call Read_Sun
If Sun_Sense > Sun_Sense_Base then goto Trigger_Test 'Keep looping only if...
Goto Slope_Detect_Exit
Mode_Check:
'This subroutine exits State Machine when Manual Mode is engaged.
If Manual_Mode = 1 then goto Command_Prompt
Return
Move_East:
Sertxd("Move_E", 13, 10)
'This subroutine moves to East to given position, exits if stalled
'Subroutine is always looking for brighter sunlight
Call Full_Stop
Call Range_Check 'No motion if position is out of normal range
If Range_Flag = 0 then goto End_East
Call Read_Position
Stall_Index = 0
If Position_EW_Target >= Position_EW then goto End_East
'Relay actuation must be for minimum amount of time
177
Park_Flag = 0 'Motion imminent
High Move_E
Pause 35 '35 Milliseconds
'Note: Pause also minimizes starting transients in Accelerometer
'Note: This also determines the 'minimum move'.
Do While Position_EW_Target < Position_EW
High Move_E
Call Peak_Detect
Call Stall_Detect
If Stall = 1 then goto End_East
Call Read_Position
Loop
End_East:
Call Full_Stop
Return
Move_East_or_West:
Sertxd("Move_EW", 13, 10)
'This subroutine moves East or West to given target position
'Detection of Solar Noon is always attempted after any E/W move
Call Full_Stop
Call Read_Position
'Here is a logical decision tree to decide which way to move...
If Position_EW_Target > Position_EW then goto Move_West
If Position_EW_Target < Position_EW then goto Move_East
Call Full_Stop
Call Detect_Solar_Noon
Return
Move_North:
Sertxd("Move_N", 13, 10)
'This subroutine moves to North to given position, exits if stalled
'Subroutine is always looking for brighter sunlight
Call Full_Stop
Call Range_Check 'No motion if position is out of normal range
If Range_Flag = 0 then goto End_North
Call Read_Position
Stall_Index = 0
If Position_NS_Target >= Position_NS then goto End_North
'Relay actuation must be for minimum amount of time
Park_Flag = 0 'Motion imminent
High Move_N
Pause 35 '35 Milliseconds
'Note: Pause also minimizes starting transients in Accelerometer
178
Do While Position_NS_Target < Position_NS
High Move_N
Call Peak_Detect
Call Stall_Detect
If Stall = 1 then goto End_North
Call Read_Position
Loop
End_North:
Call Full_Stop
Return
Move_North_or_South:
Sertxd("Move_NS", 13, 10)
'This subroutine moves North or South to given position
Call Full_Stop
Call Read_Position
If Position_NS_Target > Position_NS then goto Move_South
If Position_NS_Target < Position_NS then goto Move_North
Call Full_Stop
Return
Move_South:
Sertxd("Move S", 13, 10)
'This subroutine moves to South to given position, exits if stalled
'Subroutine is always looking for brighter sunlight
Call Full_Stop
Call Range_Check 'No motion if position is out of normal range
If Range_Flag = 0 then goto End_South
Call Read_Position
Stall_Index = 0
If Position_NS_Target <= Position_NS then goto End_South
'Relay actuation must be for minimum amount of time
Park_Flag = 0 'Motion imminent
High Move_S
Pause 35 '35 Milliseconds
'Note: Pause also minimizes starting transients in Accelerometer
Do While Position_NS_Target > Position_NS
'Sertxd("DoS", 13, 10)
High Move_S
Call Peak_Detect
Call Stall_Detect
If Stall = 1 then goto End_South
Call Read_Position
Loop
179
End_South:
Call Full_Stop
Return
Move_West:
Sertxd("Move_W", 13, 10)
'This subroutine moves to West to given position, exits if stalled
'Subroutine is always looking for brighter sunlight
Call Full_Stop
Call Range_Check 'No motion if position is out of normal range
If Range_Flag = 0 then goto End_West
Call Read_Position
Stall_Index = 0
If Position_EW_Target <= Position_EW then goto End_West
'Relay actuation must be for minimum amount of time
Park_Flag = 0 'Motion imminent
High Move_W
Pause 35 '35 Milliseconds
'Note: Pause also minimizes starting transients in Accelerometer
'Note: This also determines the 'minimum move'.
Do While Position_EW_Target > Position_EW
High Move_W
Call Peak_Detect
Call Stall_Detect
If Stall = 1 then goto End_West
Call Read_Position
Loop
End_West:
Call Full_Stop
Return
Park:
Sertxd("Park", 13, 10)
'This subroutine Parks tracker at Home Position (E/W at Level & N/S at 45 South)
'Home: N/S at 45 Degrees South and E/W Level (Can be changed as needed!)
'Parking motion is skipped for N/S or E/W within +/- 4 units of target
If Park_Flag = 1 then goto Park_Exit 'Skip Park if previously Parked & no motion since
Position_NS_Target = 435 '~45 Degrees South
Position_EW_Target = 338 'Level
Call Read_Position
If Position_NS > 430 AND Position_NS < 440 then goto Park_NS_Exit
Call Move_North_or_South
Park_NS_Exit:
Call Read_Position
180
If Position_EW > 333 AND Position_EW < 343 then goto Park_EW_Exit
Call Move_East_or_West
Park_EW_Exit:
Park_Exit:
Call Full_Stop
Park_Flag = 1 'Set Park Flag (Set back to 0 for any subsequent N,S,E,W motion)
Return
Peak_Detect:
'This subroutine checks for peak Sun_Sense and records position
Call Read_Sun
If Sun_Sense > Sun_Sense_Max then goto Peak_Detected
Return
Peak_Detected:
Call Read_Position
Position_NS_Max = Position_NS
Position_EW_Max = Position_EW
Sun_Sense_Max = Sun_Sense
Return
Range_Check:
'This routine is opportunity to check position parameters are in an acceptable range
'Presently only position is checked: Optional are voltage, temperature, etc.
'This routine checks to make sure N/S and E/W position readings are in normal range
'This routine can be used to prevent motion...after a tip-over, damage, improper setup
'Output of routine is a flag. True = 1 if within range. False = 0 if out of range
'These ranges are hard coded. Can be changed or modified as needed by user
Range_Flag = 1
Call Read_Position
If Position_NS > 550 OR Position_NS < 325 then goto Range_Check_Fail
If Position_EW > 500 OR Position_EW < 175 then goto Range_Check_Fail
Return
Range_Check_Fail:
Range_Flag = 0
Return
Read_Current:
'This subroutine reads the Shunt for Current flow & calculates Current in MA
'Shunt is 0.100 Ohms, so ADC Counts x 49 for results in MA
'Note that results are significantly dependent on whether motion is in progress
Current = 0
ADC_Sum_1 = 0
For Index=1 to ADC_Loops
READADC10 B.4, Current
181
ADC_Sum_1=ADC_Sum_1 + Current
Next
Current = ADC_Sum_1 / ADC_Loops
Current = Current * 49
Return
Read_Data:
'This subroutine reads position and time data from nonvolatile memory
'Reading is done using same format as when the data was stored
'User must set Data_Index to Solar_Clock as warranted!
Read Data_Index, Word Position_NS_Target, Word Position_EW_Target
Return
Read_Level:
'This subroutine reads the adjustable potentiometer
'The reading is reported as an ADC count
'Note that Level is an 8 bit variable. READADC is command for 8 bit ADC read
Level = 0
ADC_Sum_1 = 0
For Index = 1 to ADC_Loops
READADC B.0, Level
ADC_Sum_1 = ADC_Sum_1 + Level
Next
Level = ADC_Sum_1 / ADC_Loops
'Level is reported as simple ADC count, Max 255
Return
Read_Position:
'This subroutine reads the G sensor for E/W and N/S position
'N/S is input to ADC2 (B.2) & E/W is input to ADC3 (B.3)
Position_NS = 0
Position_EW = 0
ADC_Sum_1 = 0
ADC_Sum_2 = 0
For Index = 1 to ADC_Loops
READADC10 B.2, Position_NS
ADC_Sum_1 = ADC_Sum_1 + Position_NS
READADC10 B.3, Position_EW
ADC_Sum_2 = ADC_Sum_2 + Position_EW
Next
Position_NS = ADC_Sum_1 / ADC_Loops
Position_EW = ADC_Sum_2 / ADC_Loops
Return
182
Read_Sun:
'This subroutine reads the LED sensor for sunlight level
'The LED sensor is input into ADC1 at B.1
Sun_Sense = 0
ADC_Sum_1 = 0
For Index = 1 to ADC_Loops
READADC10 B.1, Sun_Sense
ADC_Sum_1 = ADC_Sum_1 + Sun_Sense
Next
Sun_Sense = ADC_Sum_1 / ADC_Loops
Call Auto_Level 'This subroutine dynamically sets Full_Sun variable
Return
Read_Temp:
'This subroutine reads the Digital IC Sensor DS18B20 for Temperature
'Temperature is measured in Degrees C. Note input pin is setup for digital
'Range is 0-127 Degrees C (Negative readings are not allowed)
'See Revolution Education, LLC data sheets and manuals for more information
READTEMP B.6, Temperature
If Temperature > 127 then 'Return 0 for negative temperature values
Temperature = 0 'Set equal to zero
Endif
Return
Read_Voltage:
'This subroutine reads the Divider for Voltage level & calculates Voltage in V
'Voltage variable is byte. Max 255. Approximate reading only
'Use increased ADC Loops so integer division is more accurate: SPECIAL
Voltage = 0
ADC_Sum_1 = 0
For Index = 1 to ADC_Loops
READADC B.5, Voltage
ADC_Sum_1 = ADC_Sum_1 + Voltage
Next
Voltage = ADC_Sum_1 / 23 'Avoids double low resolution division
'Note: Voltage Divider 11X, Averaged ADC Counts / 4.6 for Volts
Return
Report_Current:
Call Read_Current
Sertxd("I(MA)=", #Current,32,13,10)
Call Mode_Check
Return
183
Report_Data:
Call Transmit_Data
Call Mode_Check
Return
Report_Degrees_C:
Call Read_Temp
Sertxd("T(C)=", #Temperature,32,13,10)
Call Mode_Check
Return
Report_Flags:
Sertxd("Flags=", #BIT0,#BIT1,#BIT2,#BIT3,#BIT4,#BIT5,#BIT6,#BIT7,#BIT9,13,10)
Sertxd("Noon, Stall, Clock Set, Integral, Warm, Cold, Tracking, Manual, Range",13,10)
Call Mode_Check
Return
Report_Full_Sun:
Sertxd("Full_Sun=", #Full_Sun,32,13,10)
Return
Report_Jumpers:
Sertxd("J4,J5,J6,J7=", #PINC.4, #PINC.5, #PINC.6, #PINC.7,32,13,10)
Call Mode_Check 'Returns to Command Prompt
Return
Report_Position:
Call Read_Position
Sertxd("Pos N/S=", #Position_NS, " Pos E/W=", #Position_EW,32,13,10)
Call Mode_Check
Return
Report_Pot_Level:
Call Read_Level
Sertxd("Level(ADC)=", #Level,32,13,10)
Call Mode_Check
Return
Report_Sun_Level:
Call Read_Sun
Sertxd("Sun Lev(ADC)=", #Sun_Sense,32,13,10)
Call Mode_Check
Return
184
Report_Time:
Sertxd("Time=",#Solar_Clock,32,13,10)
Return
Report_Totals:
'This routine reports: Mini Sky Starts, Full Sky Starts and Tracks
'The totals are for operations that worked OK when called during day
'Reporting totals is useful to see progress during a day of tracking
Sertxd("#MS=", #Mini_Skys," #FS=", #Full_Skys," #T=", #Tracks,32,13,10)
Return
Report_Voltage:
Call Read_Voltage
Sertxd("Volts(V)=", #Voltage,32,13,10)
Call Mode_Check
Return
Serial_Com:
'This code allows full RS-232 communication (9600, N, 8, 1) with User
'This code allows Manual Control of STMAX .vs. Automatic Control
'Note that this code is NOT a subroutine. (Hard jump for exit)
Call Asterisk_Line
Sertxd("Manual:Type M, Auto:15 S",13,10)
Serrxd[15000, State_1], Command
If Command != "M" then goto Quit_Auto
Manual_Mode = 1 'Tracker is now in Manual Mode. Set Manual Mode Flag
Call Initialize 'Do a standard Initialize when entering Manual Mode
Command_Prompt:
Sertxd("Manual Mode: Type 1:Initialize 2:Park 3:Wait Sun Q:Quit",13,10)
Sertxd("4:Hot Start 5:Cold Start 6:NoonDetect 7:Data 8:Wait 9:Track ",13,10)
Sertxd("REPORT V:Vlts T:DegC C:Cur K:Knob L:SunLev P:Pos J:Jmps F:Flgs D:Dat",13,10)
Sertxd("JOG 5 N:North S:South E:East W:West",13,10)
Serial_Listen:
Serrxd[15000, Time_Out], Command '15 Sec timeout.Resets Counter.Waits for Command
Character
If Command = "1" then goto State_1
If Command = "2" then goto State_2
If Command = "3" then goto State_3
If Command = "4" then goto State_4
If Command = "5" then goto State_5
If Command = "6" then goto State_6
If Command = "7" then goto State_7
If Command = "8" then goto State_8
If Command = "9" then goto State_9
185
If Command = "Q" then goto Quit_Auto
'Following Commands are not states, but rather reporting subroutines...
If Command = "V" then goto Report_Voltage
If Command = "T" then goto Report_Degrees_C
If Command = "C" then goto Report_Current
If Command = "K" then goto Report_Pot_Level 'From Potentiometer
If Command = "L" then goto Report_Sun_Level
If Command = "P" then goto Report_Position
If Command = "J" then goto Report_Jumpers
If Command = "F" then goto Report_Flags
If Command = "D" then goto Report_Data
'Following Commands are all compass motions for Jogging 5 ADC units
If Command = "N" then goto Jog_North
If Command = "S" then goto Jog_South
If Command = "E" then goto Jog_East
If Command = "W" then goto Jog_West
'If Command Character is not recognized then send the User Prompt again...
Goto Command_Prompt
Quit_Auto:
Sertxd ("Auto Mode:NO SERIAL COM",13,10)
Manual_Mode = 0
Reconnect 'Reconnect allows remote program downloads
Goto State_1 'Return to Automatic Mode. This is a hard jump.
Time_Out:
Call Counter_Reset 'Resets the counter
Goto Serial_Listen 'Return to listen for Command
Serial_Report:
'This subroutine reports system information via RS-232 serial connection
'Parameters are 9600 Baud, N,8,1 (8 Data Bits, 1 Stop bit, No Parity, No Flow)
'Reporting is generally done at start of any call to a 6 minute wait.
Call Asterisk_Line
Call Report_Current
Call Report_Degrees_C
Call Report_Flags
Call Report_Full_Sun
Call Report_Jumpers
Call Report_Position
Call Report_Pot_Level
Call Report_Sun_Level
Call Report_Time
Call Report_Voltage
Call Report_Totals
Return
186
Set_Home_Base:
'This routine reads current position and sets home base for subsequent tracking
Call Read_Position
Position_Track_Home_Base = Position_EW
Return
Stall_Detect:
'Sertxd("Stall_Detect ", 13, 10)
'This subroutine detects if movement is stalled and sets a flag
'This routines uses 2 different criterion: Position and Current Draw (Min & Max)
'Routine initializes on 1st loop and checks for position stall on 20th loop
'As written (1/20 sec with 20 loops) position stall checking is every 1 second
'The 2nd criterion of current/amps detection works well and is fast
'See discussion in book for full explanation of this process.
Stall = 0
'Note that calling routines should always initialize Stall_Index before call
Stall_Index = Stall_Index + 1
If Stall_Index = 1 then goto Baseline 'Note: Add time delay either case
If Stall_Index > 1 then goto Check 'Note: Add time delay either case
Baseline:
Call Read_Position
Position_NS_Old = Position_NS
Position_EW_Old = Position_EW
Pause 50 'Provides 1/20 second delay for motion to happen
Return 'Baseline position has been established
Check:
'The check for a current/amperage stall-obstruction is performed every call
Call Read_Current
If Current < 50 then goto Set_Stall 'Limit switch tripped. No current
If Current > 2000 then goto Set_Stall 'Overcurrent: Obstruction, etc.
'Check for motion stall is only performed each 20th call.
Pause 50 'Provides 1/20 second delay for motion to happen
If Stall_Index = 20 then
Stall_Index = 0 'Resets the Stall Index for next set of iterations
Call Read_Position
If Position_NS = Position_NS_Old AND Position_EW = Position_EW_Old then goto Set_Stall
Endif
Return
Set_Stall:
Stall = 1
Sertxd ("STALL",13,10)
Return
187
Store_Data:
'This subroutine stores position & time data in nonvolatile memory for future reference
'Format: Position N/S, Position E/W while using the Solar Clock as the Index
'Note that 4 bytes are used... spare byte at end of data is for future use (Day, Month, etc.)
'See book for discussion of the data format used for non-volatile string data
Call Read_Position
Write Data_Index,Word Position_NS, Word Position_EW
Return
Track:
Sertxd("Track", 13, 10)
'This subroutine tracks the sun after successful Warm or Cold Start
'Note: Must continue finding sun to be successful and continue setting flag
'Home Base is used for tracking reference
'Home Base reference avoids error accumulation of small incremental movements
'Home Base must be updated whenever aim optimization is done (Jog, CS, WS)
Track_Flag = 0
'First try an incremental move, which theoretically should work OK
'Incremental move also 'centers' position to theoretical for search baseline
Call Inc_EW
Call Read_Sun
If Sun_Sense > Full_Sun then goto Set_Flag
'Simple Incremental did not work...resort to a jogging search pattern (with peaking)
'Note that this will require using a new Home Base for tracking
Call Jog_NS
Call Jog_EW
Call Read_Sun
If Sun_Sense < Full_Sun then goto Track_Exit
Call Set_Home_Base 'Must reset Home Base because of the Jog motion
Set_Flag:
Track_Flag = 1 'All conditions OK: Tracking worked!(Inc or Jog)
Tracks = Tracks + 1 'Running Total of Tracks
Return
Track_Exit:
Return
Transmit_Data:
'This subroutine transmits stored non-volatile data out via the Serial Port
'This subroutine only transmits data which is non-zero
'Note: Data is stored only every 5 solexes (30 minutes)
Sertxd("Transmit Data", 13, 10)
For Index =0 to 239 Step 5
Read Index, Word Position_NS, Word Position_EW
If Position_NS=0 AND Position_EW=0 then goto Do_Not_Print
188
Sertxd("Time= ",#Index,44,32,"NS= ",#Position_NS,44,32,"EW=
",#Position_EW,44,32,13,10)
Do_Not_Print:
Next
'Read position now to force variables to have the current E/W & N/S position
Call Read_Position
Return
Wait_6_Min:
Sertxd("W_6_Min", 13, 10)
'This subroutine waits 6 minutes. No exit until then. Advances clock.
'Serial reporting is done here. This limits report frequency to 6 minutes
'This subroutine also resets the Watchdog Timer every minute ('Kicks the Dog')
'Subtracting correction offset of 1260 msec per minute based on tests.
'See book for discussion of incremental timekeeping and the correction offset
Call Serial_Report
Call Transmit_Data
For Index = 1 to 6
Call Counter_Reset 'High on Pin B.7, Symbol Watchdog_Reset
'Per bench testing: Watchdog must be reset every 17.5 minutes, or less
Pause 58740 'Note: Ignores the 10 Milliseconds used for Watchdog Timer Reset
Next Index
'Advance the clock
Call Keep_Time
Return
Wait_30_Min:
Sertxd("W_30_Min", 13, 10)
'This subroutine waits 30 minutes. No exit unless the data boundary detected
'Purpose of boundary exit is to keep motion interval aligned with data interval
For Half_Hour_Index = 1 to 5
Call Wait_6_Min
'Perform test for 1/2 hour time synchronization with data logging
Data_Index = Solar_Clock 'Integral Test uses Data_Index
Call Integral_Test 'Test to determine time is 30 min integral
If Integral = 1 then goto Exit_Wait_30_Min
Next Half_Hour_Index
Exit_Wait_30_Min:
Return
Wait_for_Sun:
Sertxd("Wait_Sun", 13, 10)
Sun_Wait_Continue:
'This subroutine waits for the sun during the night, cloudy periods, etc.
189
'Special Case: At 1st Powerup Wait_for_Sun is skipped (Tracker moves when plugged-in)
'The dusk sun checks are done every 6 minutes, except for Special Case above.
Call Read_Sun
If Sun_Sense > Dusk_Sun then goto Exit_Wait_for_Sun
If Boot_Flag = 1 then goto Exit_Wait_for_Sun
Call Wait_6_Min 'The Counter Reset for Watchdog Timer is in the 1 minute loop
GoTo Sun_Wait_Continue 'Looping point chosen to skip serial port transmissions
Exit_Wait_for_Sun:
Boot_Flag = 0 'Wait_for_Sun is only skipped at 1st power
Return
Warm_Start:
Sertxd("W_Start", 13, 10)
'This subroutine attempts to use existing time and position data
'Note: Must find sun to be successful and set the flag
Warm_Start_Flag = 0
'FIRST, see if the clock has been set since powerup
If Clock_Set = 0 then goto Warm_Start_Exit
'SECOND, Find Data_Index of closest integral time (30 min)
Data_Index = Solar_Clock
Call Find_Integral
'THIRD, see if there is non-zero data in EEPROM location at the location
'Data_Index is used when reading data, and will be an integral 30 min
Call Read_Data
If Position_NS_Target = 0 then goto Warm_Start_Exit
If Position_EW_Target = 0 then goto Warm_Start_Exit
'FOURTH, move to EEPROM position. N/S then E/W
Call Move_North_or_South
Call Move_East_or_West
Call Read_Sun
If Sun_Sense < Full_Sun then goto Warm_Start_Exit
Warm_Start_Flag = 1 'All conditions OK: Warm Start worked!
Return
Warm_Start_Exit:
Return
190
Index
1N4002, 45 hinges, 24
2N3904, 45 IC Datasheets, 156
80/20, 20, 158 integer math, 86
accelerometer module, 55 integrated circuits, 56
adapter card, 96 Interval Timekeeping, 118
American Educational Products, Jameco Electronics, 158
142 LED, 55, 68
analog-to-digital, 65 limit switches, 80
ASCII, 103 linear actuator, 35
averaging, 66 LM7805, 39
barebones, 31 LT1006, 71
brackets, 36 Manual Mode, 122
BS250, 41 McMaster-Carr, 158
comments, 108 memory organization, 88
compass, 125 MEMS, 77
CompuPhase, 159 Microchip Technology, Inc, 151
D&D Surplus, 143 MMA7361, 77
Dell Latitude, 93 Mouser Electronics, 159
Digi-Key, 61, 156, 158 MTM Scientific, Inc, 159
Diodes, 54 multimeter, 57
DS18B20., 74 N-8-1, 104
electrolytic capacitor, 53 non-volatile data, 91
enclosure, 29 Null Modem, 99
Expresspcb, 158 option jumpers, 81
ExpressPCB, 97 parabola, 143
ExpressSCH, 97 Park position, 78
feedthrough, 59 parts list, 21, 61
Floor Mount Base, 27 payloads, 141
Fresnel lens, 142 Phanderson.com, 159
Full Sky Search, 132 PIC18F4550, 151
Full Sun, 133 Picaxe, 98
fuse, 38 Picaxe BASIC, 108
Harbor Freight Tools, 159 Picaxe Programming Editor, 97
191
PICAXE-20X2, 85 solex, 118
polarity protection, 38 source code, 165
Pololu Corporation, 159 Southern Hemisphere, 157
potentiometer, 82 specifications, 15
power supply, 37 Stall Detection, 135
printed circuit board, 45 state machine, 108
program space, 90 Stirling engine, 141
Project Computer, 92 Subroutines, 108
Quick Start, 161 Subroutines: Full List, 136
Rand Solar, 145 Sun pointer, 28
real time clock, 115 Sun sensor, 66
relays, 43 Suppliers, 157
resistors, 57 System Memory, 92
Revolution Education, LLC, temperature sensor, 55
159 Termite, 97
ripple binary counter, 41 thermoelectric generators, 146
RS-232 serial communication, tilt-rotate, 17
87 tilt-tilt, 15
scuffing, 69 Timekeeping, 115
sensors, 65 toggle switches, 45
serial communication, 98 transistors, 54
shunt, 74 Troubleshooting, 155
silkscreen layer, 50 USB communication, 87
Simple Search, 130 USB to Serial converter, 96
Slope Driven Search, 131 variable space, 89
software applications, 97 variables, 86
solar cell, 67 voltage divider, 75
Solar Noon, 117 voltage regulator, 54
solar oven, 142 watchdog timer, 40
Soldering, 51
192