You are on page 1of 9

ME

4234 Final Project Report / Page 1

Sun-Tracking Solar Panel

Figure 1. Test setup

Figure 2. Servo motor attachment


ME 4234 Final Project Report / Page 2

Description:

I enjoy outdoor activities such as camping, hiking, and kayaking. One of the aspects that makes these
activities special is isolation from modern information technology that can feel overwhelming at times.
However, from the perspective of safety, one should keep his cell phone charged in case of an
emergency. Also, technology like cameras and GoPros help preserve memories made during such
activities. A challenge arises during multi-day outdoor trips when these devices deplete their battery
charge. One solution is to employ a small solar panel to charge the equipment.

Small, off-the-shelf solar panels are capable of producing adequate voltage, but charge batteries very
slowly due to low current. For example, Apple iPhones charge on 5 volts and 1 amp through their wall
charger, or 5 volts and 0.5 amp via USB [1]. The off-the-shelf solar panel used for this project produced
20 volts during a peak sunlight test, but with current in the range of milliamps, depending on the load it
was applied to. Therefore a solar panel could be used to “trickle-charge” a battery over the course of a
day. As mentioned, the panel performs best at peak sunlight, with the panel’s surface perpendicular to
the incident solar rays. Since a long period of time is required to trickle-charge a battery, a solar panel
which tracks the sun is an obvious benefit.

In order to make the problem manageable for this project, I made the following simplifications:

1. The solar panel will only rotate about one axis. A production design should feature two axes of
rotation, since the sun’s angle in the sky changes throughout the year.
2. The ability of the solar panel to charge a battery will not be tested. Rather than test the off-the-
shelf panel’s performance, the purpose of this project is to demonstrate an actuation system.

Inputs:

The voltage produced by the solar panel is the only input to the system. Because the panel produced up
to 20 volts during testing, the voltage is reduced through a 5-to-1 voltage divider so that the Arduino’s 5
volt input limit is not exceeded. The signal enters the Arduino’s analog input A1 port, where 0-5 volts is
interpreted as an integer between 0-1023, or 10-bit resolution [2]. This integer is labeled “V1.”

Outputs:

The output of the system is the actuation of the servo motor. Its physical function is to rotate the solar
panel to the desired position. The output signal is sent via the “Servo.h” Ardiuino library and PWM
digital output 9 on the Arduino directly to the servo’s orange signal wire. The motor is labeled “servo1.”

Functions:

The system is intended to perform the following sequence of tasks:


1. *Sweep solar panel from 20 to 160 degrees while recording V1’s value in an array for each degree.
2. Move solar panel back to the position with the highest recorded V1 value.
3. **If V1 drops less than 10% of its max value, perform a ±10 degree sweep/record; return to step 2.

ME 4234 Final Project Report / Page 3

Notes:
*In step 1, the 20 to 160 degree range was chosen based on the physical system of the solar panel. Any
further rotation would result in the panel colliding with its stands.
**Step 3 was not able to be completed due to poor performance by the servo motor. See Results.

Design:

Figure 3. Schematic

Measurements and Calculations:

As described in the Inputs section, a 5-to-1 voltage divider is used to protect the Arduino, which can
receive a maximum of 5 volts in its analog inputs ports. With the divider in place, the solar panel’s
maximum tested output of 20 volts will enter the port as a safe 4 volts.

Description Value
V1 0-4 V
V+ (solar panel’s voltage) 0-20 V
Resistors’ impedance 10 kΩ

%&
𝑉1 = ( )𝑉'
%& '%(

Where R0 is the four parallel resistors’ equivalent resistance, and RS is the single resistor.
*& ,-
%& .
= *& ,- = 0.2
%& '%( '/0 12
.

𝑉1 = 0.2𝑉'
ME 4234 Final Project Report / Page 4

Results:

The system was tested in different lighting conditions and with different primary light sources.
Conditions tested include a well-lit room with one ceiling light source, a well-lit room with a flashlight, a
well-lit room with a desk lamp, a dark room with a flashlight, and a dark room with a desk lamp. In all
situations, the system was able to aim the panel at the intended primary light source.

However, the panel was unable to perform the smaller, 20 degree sweep necessary to track a moving
light source. The inexpensive servo motor used in the system would begin rotation with a jerk
approximately 50% of the time. When this occurred, the servo would overshoot the desired angle and
“lose track” of the light source. Thus the fine-tracking step was removed from the code in the
demonstrated version.

A video demonstration may be viewed at: https://youtu.be/c-RsI6OEOYk

Discussion:

Based on test performance, the sun-tracking solar panel met its goal of aiming the panel perpendicular
to the sun or other primary light source. If a higher quality servo motor was implemented, the system
could meet its goal of finely tracking the light source as well. Initial testing showed a drastic increase in
voltage if the solar panel was aimed perpendicular to the sun, which demonstrated the need for a panel
to be properly positioned. As implemented, the project proved both the benefit and possibility of a sun-
tracking solar panel.

Improvements and Extensions:

As previously noted, the system’s ability to finely track the sun was compromised by the use of an
inexpensive servo motor. The implementation of a high quality servo would remedy this problem and
further prove the concept.

Two simplifications were made in order to make this project feasible. The first was rotation about one
axis instead of two. The one-axis rotation demonstrated by this project proves the concept, and a
second axis would follow a similar tracking method. A second servo motor and corresponding
mechanical system would need to be added. Like the demonstration, the second axis would only need
to find the sun initially, since the earth’s daily rotation is the only motion that would need to be tracked
beyond initialization. An even simpler, lower-cost alternative would be to forgo the second servo motor
and require the user to position the panel’s secondary axis. This would not be an unreasonable
requirement, since the secondary axis only needs positioned once, during initialization.

The second simplification made was the omission of a load. This omission was acceptable because it did
not affect the sun tracking capability, which was the purpose of the project. A production version of the
solar panel would have a USB port, since most modern electronics can charge through a USB cable. The
port would be used for charging only; no data would be transferred. The Arduino would read the panel’s
produced voltage through a parallel connection. Like a voltmeter, the Arduino’s analog input has very
high impedance and would not significantly affect current to the battery being charged.
ME 4234 Final Project Report / Page 5

Like any consumer product, a production version’s physical design would need carefully considered for
its intended use and cost-effectiveness. A rugged plastic exterior shell could protect the mechanical
apparatus, including the servo motor(s), from impact, water, and debris. The off-the-shelf solar panel
used in this project is encased in waterproof plastic; such a panel should also be used for the consumer
version. The entire design should be packaged to take up minimal space when not in use, so that it could
be transported in a backpack. As with any design, economical manufacturability should be considered,
so that the panel could sell at a reasonable retail price.

References:

1. Finch, Lawrence. “Everything you wanted to know about charging your iPhone or iPad.” Apple
Support Communities. 3 May 2012. <https://discussions.apple.com/docs/DOC-3511>
2. “Analog Input.” Arduino Learning Examples. <http://arduino.cc/en/Tutorial/AnalogInput>

Arduino Code:

1. Functional code without fine sweep:

#include <Servo.h>

Servo servo1;

void setup()
{
Serial.begin(9600);
servo1.attach(9);
}

void loop()
{
int V1;
int V1Array[140];
int position;

servo1.write(90);
delay(5000);

for(position = 90; position >= 20; position --)


{
servo1.write(position);
delay(50);
}

Serial.println("sweep");
for(position = 20; position < 160; position ++)
{
int i = position - 20;
V1 = analogRead(A1);
servo1.write(position);
V1Array[i] = V1;
delay(100);
}

int max = V1Array[0];


int imax = 0;
int maxpos;
ME 4234 Final Project Report / Page 6

for(int i = 1; i < 140; i++)


{
if(V1Array[i] > max)
{
max = V1Array[i];
imax = i;
}
}

maxpos = imax + 20;


Serial.println("max position (deg)=");
Serial.println(maxpos);

float VSPmax = max * (5.0 / 1024.0) * 5;


Serial.println("max voltage (V)=");
Serial.println(VSPmax);

for(position = 160; position >= maxpos; position --)


{
servo1.write(position);
delay(50);
}

delay(10000);

if(maxpos < 90)


{
for(position = maxpos; position <= 90; position ++)
{
servo1.write(position);
delay(50);
}
}

else
{
for(position = maxpos; position >= 90; position --)
{
servo1.write(position);
delay(50);
}
}

Serial.println("complete");
delay(5000);
}

2. Code with fine sweep (not used in demonstration due to hardware issue):

#include <Servo.h>
Servo servo1;

int V1;
int position;
int max;
int imax;
int maxpos;

void setup()
{
Serial.begin(9600);
servo1.attach(9);
ME 4234 Final Project Report / Page 7

Serial.println("project_rev2");

//temp
Serial.println("setup");

int V1Array[140];

servo1.write(90);
delay(5000);

for(position = 90; position >= 20; position -= 1)


{
servo1.write(position);
delay(50);
}

Serial.println("initial sweep");

for(position = 20; position < 160; position += 1)


{
int i = position - 20;
V1 = analogRead(A1);
servo1.write(position);
V1Array[i] = V1;
delay(100);
}

max = V1Array[0];
imax = 0;

for(int i = 1; i < 140; i++)


{
if(V1Array[i] > max)
{
max = V1Array[i];
imax = i;
}
}

maxpos = imax + 20;


Serial.println("max position (deg) =");
Serial.println(maxpos);

float VSPmax = max * (5.0 / 1024.0) * 5;


Serial.println("max voltage (V) =");
Serial.println(VSPmax);

for(position = 160; position >= maxpos; position -= 1)


{
servo1.write(position);
delay(50);
}

// temp
Serial.println("max=");
Serial.println(max);

delay(5000);
}

void loop()
ME 4234 Final Project Report / Page 8

{
//temp
Serial.println("loop");

V1 = analogRead(A1);
int max10m = max - max * 0.10;
int V1SmArray[21];

// temp
Serial.println("max=");
Serial.println(max);
Serial.println("max10m=");
Serial.println(max10m);
Serial.println("V1=");
Serial.println(V1);

if(V1 < max10m)


{
if(maxpos > 30 && maxpos < 150)
{
for(position = maxpos; position >= (maxpos - 10); position -= 1)
{
servo1.write(position);
delay(100);
}

Serial.println("re-sweep");

for(position = (maxpos - 10); position <= (maxpos + 10); position += 1)


{
int i = 0;
V1 = analogRead(A1);
servo1.write(position);
V1SmArray[i] = V1;
delay(100);
}

max = V1SmArray[0];
imax = 0;

for(int i = 1; i < 21; i++)


{
if(V1SmArray[i] > max)
{
max = V1SmArray[i];
imax = i;
}
}

maxpos = maxpos - 10 + imax;


Serial.println("max position (deg) =");
Serial.println(maxpos);

float VSPmax = max * (5.0 / 1024.0) * 5;


Serial.println("max voltage (V) =");
Serial.println(VSPmax);
}

if(maxpos <= 30 || maxpos >= 150)


{
//temp
Serial.println("re-sweep out of range");
ME 4234 Final Project Report / Page 9

}
}

delay(5000);
}

You might also like