Good Day…
I have been developing this project for about a month now and thought I would share and hopefully get some feedback.
The idea is that it will track the sun and just wait for morning to realign again. No counting steps or any other absolute positioning required. Set it up, connect it to a battery, and walk away.
I have built a mock on the breadboard and successfully driven the gear motors as intended with the schematic shown below. Was hoping to get some peer review/proofing of the schematic and code before finalizing the design and committing to the actual build.
Thanks
Still need to incorporate battery charging circuitry and probably some fuse/overload protection also.
Readable PDF File:
http://www.gertweb.com/images/Solar%20Tracker.pdf
Initial Design Concept
Early design layouts of drive mechanism.
On the left a $7.00 Gear Motor. On the right a $25.00 Stepper Motor.
Hmmmm
Testing some “recycled” relays to reverse motor direction.
Uses the 5v from the microcontroller output pin to drive the relays controlling the 12v to the motors.
Truth Table
J1 Low + J2 Low = Armature Grounded
J1 Low + J2 High = Rotate Right
J1 High + J2 Low = Rotate Left
The drive motors and design configuration I intend to use.
The gearbox gives an 8 to 1 gear ratio and it has a lot more torque than one might think. (a good thing)
Rev 4 of the prototype circuit board.
The more I contemplate the design the more I realize it will probably need an additional position sensor.
IE: How do you get it to turn and face East for the morning sun? Tracking the sun itself is easy.
But not getting it positioned correctly to start with could mean the panels will track facing directly away from the sun. Thoup!!
The chip will be programmed on the Arduino board and then transplanted to the solar assembly.
By doing this I freed up a lot of real-estate on the proto-board.
Built a quick mock up to program, test, and debug the sensor array.
Some Aluminum tubing, Styrofoam hamburger tray, a little masking tape, and a chunk of 7 wire cable.
(Who’s your daddy MacGyver?)
The un-calibrated sensor readings feed a much larger, more precise, data set to the microcontroller (as was expected). By skipping the calibration process I can remove a large layer of complexity from the design solution. The down side to this is that it is way more precise than need be. To get the sensor array I built to work correctly it needs to be within about ¼ to an 1/8 of a degree perpendicular to the sun. This will cause a large number of motor steps to keep alignment throughout the day. Great tracking performance (if you want to shoot down missiles), but poor utilization of collected solar energy. Tradeoffs are needed.
Using a solar cell and a volt meter I found I need to be within about plus or minus 5 degrees of perpendicularity for best collector efficiency. Instead of trying to tweak the design parameters with the software it will be easier to alter the array to give a bit more freedom to the perpendicularity tolerance.
Of Interest…
I was reading Wikipedia after writing the above comments and it stated that a plus minus 5 degree angle will be greater than 99.6% efficient. It turns out the rod in my eye is a pretty accurate protractor. (grin)
The redesigned sensor array. I went with a plus minus 6 degree variance. This is probably still more accurate than need be.
Baby Steps…
I started developing the software by just acquiring the sensor data. Next, using that data, I wrote the code to compare values and turn switches on and off accordingly. The next step will be to actually wire relays in place of the indicator LED’s and drive the motors. I was pleasantly surprised when I realized I had 80% of the code done in one afternoon.
The code
/*
Solar Tracker (Preliminary Example Code)
Uses 3 photoresistors to track the suns movement.
The microcontroller evaluates the photoresistor values and
drives the appropriate positioning motor for correct alignment.
created 28 Jul 2012
By David A Smith
modified 28 Jul 2012
By David A Smith
This code is in the public domain.
*/
// These constants won't change:
const int sensorPinA0 = A0; // pin that the Bottom/Left sensor is attached to
const int sensorPinA1 = A1; // pin that the Right sensor is attached to
const int sensorPinA2 = A2; // pin that the Top sensor is attached to
//const int pmotorPinA0 = 11; // pin that the pan motor relay is attached to
//const int pmotorPinA1 = 10; // pin that the pan motor relay is attached to
//const int tmotorPinA0 = 9; // pin that the tilt motor relay is attached to
//const int tmotorPinA2 = 8; // pin that the tilt motor relay is attached to
// variables:
int sensorValueA0 = 0; // Bottom/Left photoresistor
int sensorValueA1 = 0; // Right photoresistor
int sensorValueA2 = 0; // Top photoresistor
int panDelay = 1000; // The amount of time the pan and tilt motor will run
int tiltDelay = 1000; // this will vary depending on motor and drive train
void setup() {
// Send debugging information via the Serial monitor
Serial.begin(9600);
//Assign and set motor driver pins to low
pinMode(11, OUTPUT);
digitalWrite(11, LOW);
pinMode(10, OUTPUT);
digitalWrite(10, LOW);
pinMode(9, OUTPUT);
digitalWrite(9, LOW);
pinMode(8, OUTPUT);
digitalWrite(8, LOW);
}
void loop() {
// read the sensor:
sensorValueA0 = analogRead(sensorPinA0);
sensorValueA1 = analogRead(sensorPinA1);
sensorValueA2 = analogRead(sensorPinA2);
// Compare sensor readings and drive pan motor left or right
// If the sensor values are equal (what we want) it will skip adjusting the pan motor
// Pan Right
if (sensorValueA0 > sensorValueA1){
digitalWrite(11, HIGH);
delay(panDelay);
digitalWrite(11, LOW);
}
// Pan Left
if (sensorValueA0 < sensorValueA1){
digitalWrite(10, HIGH);
delay(panDelay);
digitalWrite(10, LOW);
}
// Compare sensor readings and drive tilt motor up or down
// If the sensor values are equal (what we want) it will skip adjusting the tilt motor
// Tilt Down
if (sensorValueA0 > sensorValueA2){
digitalWrite(9, HIGH);
delay(tiltDelay);
digitalWrite(9, LOW);
}
// Tilt Up
if (sensorValueA0 < sensorValueA2){
digitalWrite(8, HIGH);
delay(tiltDelay);
digitalWrite(8, LOW);
}
//Print debugging information
Serial.print("Left/Bottom reading = ");
Serial.println(sensorValueA0); // the left/bottom sensor analog reading
Serial.print("Right reading = ");
Serial.println(sensorValueA1); // the right sensor analog reading
Serial.print("Top reading = ");
Serial.println(sensorValueA2); // the top sensor analog reading
delay(1000);
}
Nothing I have presented here is finalized and all information is for review and informational purposes only.
For a more in-depth look at the development stages of this and other related projects visit my Facebook page.
(New friend requests are always welcome)
http://www.facebook.com/media/set/?set=a.445878665445702.103623.100000707171935&type=3&l=bfcf6b8267
EDIT 8-19-2012
Updated my personal web page to include this and other projects.
http://www.gertweb.com/arduino.html