Overview
This tutorial is the second one in the series corresponding to the Sunbrella project for the Sensing the City course taught by Allison Lassiter for students in University of Pennsylvania’s Department of City and Regional Planning.
This tutorial will focus on how to use photoresistors and a servo motor to make a single axis solar tracker. The mechanism aims to adjust the angle of a solar panel throughout the day (from East to West) to maximize energy production. The intention is for the device to work autonomously and be powered by a battery fed by the panel. This tutorial does not cover the use of the solar panel itself, just how to adjust its position. For instructions on how to charge the battery using the solar panel please see the tutorial by Laura Frances: Using a solar cell and rechargeable battery to power a servo motor.
Acknowledgements and sources
This tutorial is based on the following resources:
Arduino Solar Tracker: Open hardware/software test bench for solar tracker with virtual instrumentation, by Aboubakr_Elhammoumi and motahhir, published on April 10, 2020; available at https://projecthub.arduino.cc/Aboubakr_Elhammoumi/77347b69-2ade-4a44-b724-3bb91e954188
How to Make Solar Tracker with Arduino Uno R3, by ICV Creative, published on April 7, 2021; available at https://www.youtube.com/watch?v=dP6gO19t2pk
ChatGPT version Match 14, 2023 was also used to modify the code.
Parts
Photoresistor (light dependent resistor – LDR), 5 Mohm (verify) – 2 pieces
Power source (could be a battery, I powered this with my laptop).
Software
Arduino IDE (version 2.0.3)
Libraries: Servo.h
Mechanical design
The solar panel is mounted on an horizontal axis and attached to a servomotor that adjusts the panel’s angle. (When the device is placed in the sunlight the axis supporting the panel should have a North-South orientation, so that by rotating in place it will cause the panel to turn from East to West). LDRs are mounted on opposing panel edges, along the servo’s range of movement. For our project is it also preferable to constrain the panel’s range of movement to 90 degrees.
Function
The LDRs and the servo are wired to the Arduino Uno board, which can be powered either by a battery or by other energy sources. Each LDR sends analog signals to the arduino board, feeding information about the intensity of the light being measured. LDRs act like resistors but the resistance changes depending on how much light they receive. This information is conveyed to the arduino board as an analog signal. The board compares the analog signals being received and the difference in the intensity of light being measured by each LDR. Based on that it instructs the servo to move in the direction of the LDR that is receiving less light. Once the servo has adjusted the panel’s angle to a sufficient degree, both LDRs will be similarly exposed to sunlight and this will be reflected in the information being fed to the board. When the information being fed to the board indicates that both LDRs receive the same light intensity the servo no longer has instructions to move, and the position will be maintained until new adjustments are needed based on the sun’s movement.
A default fully horizontal position and average ranges of light radiation are determined, so that when the LDRs are exposed to light below this minimum (basically, at night when it is dark), the servos will be instructed to move the panel back to its default position. (We find it preferable to set the default position as fully horizontal because for our main project there are more situations where it is preferable for the panel to be in a fully horizontal position rather than tilted toward the East.)
Wiring diagram
Wiring
- Set up the breadboard with a connection to a ground pin and teh 5 V pin.
- For each photoresistor, set a line of the breadboard with the wire connecting to the ground, a 220 Ohm resistor, and a wire connecting to pin A0 or A1 accordingly
- Use male-female wires to wire the 2 photoresistors. Attach at opposite ends of the photovoltaic panel (in this case, this is a smaller model and I did not have small photovoltaic cells, so this is replaced by the piece of cardboard). Consider how you will mount this later on so that the wires will not obstruct the movement or come loose.
- Attach your photovoltaic panel or replacement to the arms of the servo at the end of the axis of rotation (in my case, along the middle) mount the servo on the mechanical support structure you are using. This could be a proper support with bearings, in my case I balanced it on a metal frame.
- Connect the servo’s 5 V and ground cables to the breadboard. Connect the other wire directly to the Arduino board pin 6.
- Connect the photoresistors to the breadboard (one cable to the 5V row and the other to the line selected for that photoresistor, next to the wires connecting to pin A0 or A1 accordingly).
- Now all parts are wired, connect the Arduino to the laptop.
- Time to upload the code and test different lighting conditions. 🙂
Picture of the testing prototype
Code
The code below is used to process the information from the LDRs and control de servo. The code initializes a variable for a pin and assigns the value 6. The setup initializes pin 6 as an output. The loop then sends and stops voltage from pin 6 with breaks before repeating.
Connect the hardware components before uploading the code to the arduino board. You can test the functionality by using a lamp to shine a light on your model from different angles and activating the servo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
/* Using photoresistors and a servo motor to make a single axis solar tracker by Delfina Vildosola This is a provisional version subject to adjustments. Code based on coding by Aboubakr_Elhammoumi and motahhir, published on April 10, 2020; available at https://projecthub.arduino.cc/Aboubakr_Elhammoumi/77347b69-2ade-4a44-b724-3bb91e954188 This code is a simplified model that uses on 2 photoresistors and a single axis of movement. The range of movement for the servos has been constrained, as this is a necessary feature for the final project where the motor would be moving the roof of a bus shelter. Additional adjustments in the code also regulate the speed of the movement. */ //Servo motor library #include <Servo.h> //Initialize variables int ldrright = A0; // right LDR pin int ldrleft = A1; // left LDR pin int topl = 0; int topr = 0; //Declare servo Servo servo_rightleft; int threshold_value = 1; //measurement sensitivity void setup() { Serial.begin(9600); //serial connection setup //opens serial port, sets data rate to 9600 bps Serial.println("CLEARDATA"); //clear all data that’s been place in already Serial.println("LABEL,t,voltage,current,power,Mode"); //define the column headings (PLX-DAQ command) servo_rightleft.attach(6); //Servo motor right-left movement } void loop() { // Call automatic solar tracker function automaticsolartracker(); } void automaticsolartracker() { //capturing analog values of each LDR topr = analogRead(ldrright); //capturing analog value of right LDR topl = analogRead(ldrleft); //capturing analog value of left LDR //Get the difference int diffazi = topl - topr; //Get the difference in average between the right and left LDRs //left-right movement of solar tracker if (abs(diffazi) >= threshold_value) { //Change position only if light difference is bigger then the threshold_value int targetPos = 0; if (diffazi > 0) { targetPos = -45; } else { targetPos = 45; } int currentPos = servo_rightleft.read(); int increment = (targetPos - currentPos) / 100; for (int i = 0; i < 10; i++) { currentPos += increment; servo_rightleft.write(currentPos); delay(500); // Adjust this delay to make the movement slower or faster } } } |
Video
This short clip shows the panel moving to its initial position and then slowly adjusting its angle in response to the feedback from the photoresistors.