Introduction: 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!
This article is also available at this link
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
Step 1: 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
Step 3: 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); }
Step 4: 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.