Arduino Large and Productive Solar Tracker - Do It Yourself
Hi everyone! In this article we are going to see how to build a solar tracker that knows how to do the job and that is not just for illustrative purposes!
If you don't know what I'm talking about, I'll explain it to you right away: when you search in the internet for a solar tracker, the first thing that comes out is childish designs of stupid and small solar trackers with panels so small that they would struggle to power some LEDs. in series.
Then you think: "what the hell am I looking at, I want to see an example of a real solar tracker, one that has a solar panel mounted on it that can power (and charge the batteries of) at least a small garage!"
And since I totally agree with you, I built it and now I'll show you how!
Supplies
All the components you will need are in the photo, but in summary they are:
- 1x Aluminum square tube to make the frame of the structure
- 1x Solar panel (of course)
- 4x Photoresistors to measure the intensity of light
- 2x Powerful enough servo motors (the MG996Rs did their job) to move the panel
- 1x Arduino board of any type (it really doesn't matter; the program is very simple) to manage the electronics
- 4x 1000-ohm photoresistors
- Some x 3D printed components (if you don't have a 3d printer ... you'll make something up!)
- Some x Various components, usually consumables such as screws, bolts and so on
How It Works
When you move on to the next step you will understand what I am saying but for the moment you just need to know that there are 4 cross light sensors and there is a pillar that divides them.
That way, when one sensor is more exposed to sunlight, the other three likely experience the shadow of the pillar.
In the program that runs on the Arduino, I compare four directions of light: Above (averaging between the sensor at the top right and the sensor at the top left), Below (averaging between the sensor at the bottom right and the sensor in bottom left), left (averaging between the upper left sensor and the lower left sensor) and finally right (averaging between the upper right sensor and the lower right sensor)
By doing so, if, for example, I detect that there is lighter on the right (averaging between the sensor at the top right and the sensor at the bottom right), I make the servomotor move to the right.
With the same logic if, for example, I detect that there is lighter at the top, (taking the average between the sensor at the top right and the sensor at the top left), I move the servomotor of the vertical axis accordingly. that the panel faces the light.
By doing all the operations together, the way it works is very efficient.
Step 2: Build the Structure
For the construction of the structure there is not much to say, let's face it clearly ... do as you like.
But if you really want to replicate the project, I leave you a fusion 360 file (and also the link) to see the CAD structure that I designed (even if it actually turned out slightly different).
You only need a couple of 3D printed parts for the base frame and to mount the profiles at 90 degrees
Program Arduino and Test the Code
What's better than uploading the code to the Arduino, plug everything in and see it works? Nothing!
Then connect to your computer, copy this code, upload it to Arduino and that's it!
/*
Inseguitore Solare a due assi
Fa seguire ad un pannello solare ancorato a due motori la direzione del sole
by Maurizio Miscio - 12/05/2022*/
#include <Servo.h>
//inizializzo i servo nel programma
Servo ServoVeticale;
Servo ServoBase;
//inizializzo le variabili delle posizioni del servo
int PosServoVeticale = 90;
int PosServoBase = 90;
//inizializzo le variabili dei valori della fotoresistenze
int BassoSinistra;
int AltoDestra;
int BassoDestra;
int AltoSinistra;
//inizializzo le variabile che contengono la media dei valori delle fotoresistenze in alto e basso
int MediaAlto;
int MediaBasso;
//inizializzo le variabile che contengono la media dei valori delle fotoresistenze a destra e sinistra
int MediaSinistra;
int MediaDestra;
//inizializzo le variabili che contengono la differenza tra le due coppie di resistenze Alto e Basso
int Differenza1Veticale;
int Differenza2Veticale;
//inizializzo le variabili che contengono la differenza tra le due coppie di resistenze Destra e Sinistra
int Differenza1Base;
int Differenza2Base;
//inizializzo la variabile che contiene il valore di errore delle due coppie di fotoresistenze (valore trascurabile)
int errore = 40;
//comandi che si ripetono una sola volta in tutto lo sketch
void setup() {
Serial.begin(9600);
ServoVeticale.attach(9);
ServoBase.attach(10);
}
//comandi che si ripetono in loop
void loop() {
//leggo i valori analogici delle fotoresistenze e li assegno alle variabili corrispondenti
BassoSinistra = analogRead(A0);
AltoDestra = analogRead(A1);
BassoDestra = analogRead(A2);
AltoSinistra = analogRead(A3);
//imposto i limiti del servo verticale (e evito che il valore superi i MAX 180 gradi)
if (PosServoVeticale >= 160) {
PosServoVeticale = 160;
}
if (PosServoVeticale <= 0) {
PosServoVeticale = 0;
}
//imposto i limiti del servo alla base ( e evito che il valore superi i MAX 180 gradi)
if (PosServoBase >= 180) {
PosServoBase = 180;
}
if (PosServoBase <= 0) {
PosServoBase = 0;
}
//calcolo la media dei sensori a coppie per avere un solo valore medio
MediaAlto = (AltoDestra + AltoSinistra) / 2;
MediaBasso = (BassoSinistra + BassoDestra) / 2;
MediaSinistra = (AltoSinistra + BassoSinistra) / 2;
MediaDestra = (AltoDestra + BassoDestra) / 2;
//calcolo la differenza in valore assoluto tra le due coppie di sensori alto-basso e sinistra-destra
Differenza1Veticale = abs(MediaAlto - MediaBasso);
Differenza2Veticale = abs(MediaBasso - MediaAlto);
Differenza1Base = abs(MediaSinistra - MediaDestra);
Differenza2Base = abs(MediaDestra - MediaSinistra);
//pongo la condizione che solo se la differenza tra le due coppie di sensori è maggiore del valore di errore prestabilito...
if ((Differenza1Veticale <= errore) || (Differenza2Veticale <= errore)) {
} else {
//cambio (sommo o sotraggo "1") posizione del servo finchè i due sensori non hanno lo stesso valore
if (MediaBasso > MediaAlto) {
PosServoVeticale = PosServoVeticale + 1;
}
if (MediaAlto > MediaBasso) {
PosServoVeticale = PosServoVeticale - 1;
}
}
//pongo la condizione che solo se la differenza tra le due coppie di sensori è maggiore del valore di errore prestabilito...
if ((Differenza1Base <= errore) || (Differenza2Base <= errore)) {
} else {
//cambio (sommo o sotraggo "1") posizione del servo finchè i due sensori non hanno lo stesso valore
if (MediaSinistra > MediaDestra) {
PosServoBase = PosServoBase + 1;
}
if (MediaDestra > MediaSinistra) {
PosServoBase = PosServoBase - 1;
}
}
//stampo su una riga tutti i valori utili che mi serve leggere in tempo reale
Serial.print("SS: ");
Serial.print(BassoSinistra);
Serial.print(", ");
Serial.print("SD: ");
Serial.print(BassoDestra);
Serial.print(", ");
Serial.print("AS: ");
Serial.print(AltoSinistra);
Serial.print(", ");
Serial.print("AD: ");
Serial.print(AltoDestra);
Serial.print(", ");
Serial.print("MA: ");
Serial.print(MediaAlto);
Serial.print(", ");
Serial.print("MB: ");
Serial.print(MediaBasso);
Serial.print(", ");
Serial.print("MD: ");
Serial.print(MediaDestra);
Serial.print(", ");
Serial.print("MS: ");
Serial.print(MediaSinistra);
Serial.print(", ");
Serial.print("Servo: ");
Serial.println(PosServoVeticale);
//faccio muovere finalmente i servo alla loro posizione
ServoVeticale.write(PosServoVeticale);
ServoVeticale.write(PosServoBase);
}
Done!
Ok, now you can capture all the sun you want with your new solar tracker and don't worry, there is enough sun for everyone!
Have you ever noticed that sun rhymes with fun, in this case capturing the sun will have been fun.
/*
Inseguitore Solare a due assi
Fa seguire ad un pannello solare ancorato a due motori la direzione del sole
by Maurizio Miscio - 12/05/2022*/
#include <Servo.h>
//inizializzo i servo nel programma
Servo ServoVeticale;
Servo ServoBase;
//inizializzo le variabili delle posizioni del servo
int PosServoVeticale = 90;
int PosServoBase = 90;
//inizializzo le variabili dei valori della fotoresistenze
int BassoSinistra;
int AltoDestra;
int BassoDestra;
int AltoSinistra;
//inizializzo le variabile che contengono la media dei valori delle fotoresistenze in alto e basso
int MediaAlto;
int MediaBasso;
//inizializzo le variabile che contengono la media dei valori delle fotoresistenze a destra e sinistra
int MediaSinistra;
int MediaDestra;
//inizializzo le variabili che contengono la differenza tra le due coppie di resistenze Alto e Basso
int Differenza1Veticale;
int Differenza2Veticale;
//inizializzo le variabili che contengono la differenza tra le due coppie di resistenze Destra e Sinistra
int Differenza1Base;
int Differenza2Base;
//inizializzo la variabile che contiene il valore di errore delle due coppie di fotoresistenze (valore trascurabile)
int errore = 40;
//comandi che si ripetono una sola volta in tutto lo sketch
void setup() {
Serial.begin(9600);
ServoVeticale.attach(9);
ServoBase.attach(10);
}
//comandi che si ripetono in loop
void loop() {
//leggo i valori analogici delle fotoresistenze e li assegno alle variabili corrispondenti
BassoSinistra = analogRead(A0);
AltoDestra = analogRead(A1);
BassoDestra = analogRead(A2);
AltoSinistra = analogRead(A3);
//imposto i limiti del servo verticale (e evito che il valore superi i MAX 180 gradi)
if (PosServoVeticale >= 160) {
PosServoVeticale = 160;
}
if (PosServoVeticale <= 0) {
PosServoVeticale = 0;
}
//imposto i limiti del servo alla base ( e evito che il valore superi i MAX 180 gradi)
if (PosServoBase >= 180) {
PosServoBase = 180;
}
if (PosServoBase <= 0) {
PosServoBase = 0;
}
//calcolo la media dei sensori a coppie per avere un solo valore medio
MediaAlto = (AltoDestra + AltoSinistra) / 2;
MediaBasso = (BassoSinistra + BassoDestra) / 2;
MediaSinistra = (AltoSinistra + BassoSinistra) / 2;
MediaDestra = (AltoDestra + BassoDestra) / 2;
//calcolo la differenza in valore assoluto tra le due coppie di sensori alto-basso e sinistra-destra
Differenza1Veticale = abs(MediaAlto - MediaBasso);
Differenza2Veticale = abs(MediaBasso - MediaAlto);
Differenza1Base = abs(MediaSinistra - MediaDestra);
Differenza2Base = abs(MediaDestra - MediaSinistra);
//pongo la condizione che solo se la differenza tra le due coppie di sensori è maggiore del valore di errore prestabilito...
if ((Differenza1Veticale <= errore) || (Differenza2Veticale <= errore)) {
} else {
//cambio (sommo o sotraggo "1") posizione del servo finchè i due sensori non hanno lo stesso valore
if (MediaBasso > MediaAlto) {
PosServoVeticale = PosServoVeticale + 1;
}
if (MediaAlto > MediaBasso) {
PosServoVeticale = PosServoVeticale - 1;
}
}
//pongo la condizione che solo se la differenza tra le due coppie di sensori è maggiore del valore di errore prestabilito...
if ((Differenza1Base <= errore) || (Differenza2Base <= errore)) {
} else {
//cambio (sommo o sotraggo "1") posizione del servo finchè i due sensori non hanno lo stesso valore
if (MediaSinistra > MediaDestra) {
PosServoBase = PosServoBase + 1;
}
if (MediaDestra > MediaSinistra) {
PosServoBase = PosServoBase - 1;
}
}
//stampo su una riga tutti i valori utili che mi serve leggere in tempo reale
Serial.print("SS: ");
Serial.print(BassoSinistra);
Serial.print(", ");
Serial.print("SD: ");
Serial.print(BassoDestra);
Serial.print(", ");
Serial.print("AS: ");
Serial.print(AltoSinistra);
Serial.print(", ");
Serial.print("AD: ");
Serial.print(AltoDestra);
Serial.print(", ");
Serial.print("MA: ");
Serial.print(MediaAlto);
Serial.print(", ");
Serial.print("MB: ");
Serial.print(MediaBasso);
Serial.print(", ");
Serial.print("MD: ");
Serial.print(MediaDestra);
Serial.print(", ");
Serial.print("MS: ");
Serial.print(MediaSinistra);
Serial.print(", ");
Serial.print("Servo: ");
Serial.println(PosServoVeticale);
//faccio muovere finalmente i servo alla loro posizione
ServoVeticale.write(PosServoVeticale);
ServoVeticale.write(PosServoBase);
}
Arduino Large and Productive Solar Tracker - Do It Yourself
- Comments(0)
- Likes(1)
- Engineer Mar 14,2024
- 0 USER VOTES
- YOUR VOTE 0.00 0.00
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
More by Maurizio Miscio
- DIY UPS (Emergency Battery) for Routers So It Won't Turn Off When the Breakers Are Off Hi, today we are building a UPS or backup battery for the router / modem so that it does not turn of...
- How to Make a Fiido D4S Battery (kind of) Removable Do you guys have a Fiido D4S but not a place to charge it?You know, your house is too small to park ...
- How to (Re)build an Ebike Charger and Add a Fan to Keep It Cool Hi guys. In the last article we saw how to make a Fiido D4S Battery removable, but now to charge it ...
- Automatically Turn Off the Power Strip of the Computer (monitor, Speakers, Etc.) When You Shut Down the Computer. If you have a desktop computer at home, you will know better than me how boring it is to turn off th...
- How to Disable the Throttle of an Electric Bike With an Invisible Switch Hi folks, in this tutorial we will see how to disable the throttle of an electric bike (in my case a...
- Adding a Female Aux Jack to Your Old Headphone - the Best Upgrade You Can Do! Have you ever broken a headphone jack? Probably the answer is yes! Or simply have you ever had issue...
- Easiest Way to Discharge a Ebike Battery Hi guys, welcome to this new tutorial. Today I will show you the easiest way to discharge a Ebike Ba...
- Arduino School Bell - Simple DIY Hi guys, in this article we are going to see how to make a circuit with Arduino and some other compo...
- Arduino Large and Productive Solar Tracker - Do It Yourself Hi everyone! In this article we are going to see how to build a solar tracker that knows how to do t...
- Arduino Robotic Arm Controlled by Touch Interface Hello. Today I'm here to see with you how I built a robotic arm with Arduino and a graphic touch int...
- DIY Bench Variable Power Supply - ZK-4KX Hello to all boys and girls, today we will see together how I made a very compact DIY benchtop varia...
- How to Balance a Battery Pack With USB or the Traditional Method - TP4056 Hi guys, today let's see together how to balance a battery pack through a very common micro-USB conn...
- Single 18560 Battery Charger With TP4056 Hi guys, in this article we will see how to make a very convenient single charger for 18650 cells so...
- The Best Mini OLED Display I've Ever Tried! - DF Robot 5.5 'HDMI OLED-Display With Touchscreen IntroHi guys, today let's unpack together the best mini display I've ever seen that I was extremely ...
- Let's Add an Active Balancer to the Electric Bike Battery Intro:Hi guys, today we add an active balancer to the battery of our ebike so as not to risk some ce...
-
-
-
kmMiniSchield MIDI I/O - IN/OUT/THROUGH MIDI extension for kmMidiMini
120 0 0 -
DIY Laser Power Meter with Arduino
171 0 2 -
-
-
Box & Bolt, 3D Printed Cardboard Crafting Tools
158 0 2 -