Arduino Solar Tracker

Open hardware/software test bench for solar tracker with virtual instrumentation.

Components and supplies

Resistor 330 ohm

Mini Solar Panel

SG90 Micro-servo motor

Rotary potentiometer (generic)

Pushbutton Switch, Pushbutton

Tools and machines

Apps and platforms

Embedded Software os solar tracker test bench

1//Servo motor library 2#include Servo.h> 3//Initialize variables 4int mode = 0; 5int axe = 0; 6int buttonState1 = 0; 7int buttonState2 = 0; 8int prevButtonState1 = 0; 9int prevButtonState2 = 0; 10 11int ldrtopr= 0; // top-right LDR 12int ldrtopl = 1; // top-left LDR 13int ldrbotr = 2; // bottom-right LDR 14int ldrbotl = 3; // bottom-left LDR 15int topl = 0; 16int topr = 0; 17int botl = 0; 18int botr = 0; 19 20//Declare two servos 21Servo servo_updown; 22Servo servo_rightleft; 23 24int threshold_value=10; //measurement sensitivity 25 26void setup() 27 28 Serial.begin(9600); //serial connection setup //opens serial port, sets data rate to 9600 bps 29 Serial.println("CLEARDATA"); //clear all data that’s been place in already 30 Serial.println("LABEL,t,voltage,current,power,Mode"); //define the column headings (PLX-DAQ command) 31 32 pinMode(12, INPUT); //Mode switch Button 33 pinMode(11, INPUT); //Axis switch 34 pinMode(A4, INPUT); //Potentiometer for right-left movement and for up-down movement 35 36 servo_updown.attach(5); //Servo motor up-down movement 37 servo_rightleft.attach(6); //Servo motor right-left movement 38> 39 40void loop() 41 42// pv_power(); 43char Mode; 44 float volt = analogRead(A5)*5.0/1023; 45 float voltage = 2*volt; // Volt=(R1/R1+R2)*Voltage / R1=R2=10Ohms => voltage=2*volt) 46 float current = voltage/20; // I=voltage/(R1+R2) 47 float power = voltage*current; 48 Serial.print("DATA,TIME,"); // PLX-DAQ command 49 Serial.print(voltage); //send the voltage to serial port 50 Serial.print(","); 51 Serial.print(current); //send the current to serial port 52 Serial.print(","); 53 Serial.print(power); //send the power to serial port 54 Serial.print(","); 55 56// Serial.println(Mode); 57 buttonState1 = digitalRead(12); 58 if (buttonState1 != prevButtonState1)  59 if (buttonState1 == HIGH)  60 //Change mode and ligh up the correct indicator 61 if (mode == 1)  62 mode = 0; 63 > else  64 mode = 1; 65 > 66 > 67 > 68 prevButtonState1 = buttonState1; 69 delay(50); // Wait for 50 millisecond(s) 70 71 if (mode == 0)  72 Mode='M'; 73 Serial.println(Mode); //send Mode "Manual" to serial port 74 manualsolartracker(); 75 > else  // mode automatic 76 Mode = 'A'; 77 Serial.println(Mode); 78 automaticsolartracker(); //send Mode "Automatic" to serial port 79 > 80> 81 82void automaticsolartracker() 83 84 //capturing analog values of each LDR 85 topr= analogRead(ldrtopr); //capturing analog value of top right LDR 86 topl= analogRead(ldrtopl); //capturing analog value of top left LDR 87 botr= analogRead(ldrbotr); //capturing analog value of bot right LDR 88 botl= analogRead(ldrbotl); //capturing analog value of bot left LDR 89 90 // calculating average 91 int avgtop = (topr + topl) / 2; //average of top LDRs 92 int avgbot = (botr + botl) / 2; //average of bottom LDRs 93 int avgleft = (topl + botl) / 2; //average of left LDRs 94 int avgright = (topr + botr) / 2; //average of right LDRs 95 96 //Get the different 97 int diffelev = avgtop - avgbot; //Get the different average betwen LDRs top and LDRs bot 98 int diffazi = avgright - avgleft; //Get the different average betwen LDRs right and LDRs left 99 100 //left-right movement of solar tracker 101 102 if (abs(diffazi) >= threshold_value) //Change position only if light difference is bigger then the threshold_value 103 if (diffazi > 0)  104 if (servo_rightleft.read()  180)  105 servo_rightleft.write((servo_updown.read() + 2)); 106 > 107 > 108 if (diffazi  0)  109 if (servo_rightleft.read() > 0)  110 servo_rightleft.write((servo_updown.read() - 2)); 111 > 112 > 113 > 114 115 //up-down movement of solar tracker 116 117 if (abs(diffelev) >= threshold_value) //Change position only if light difference is bigger then thethreshold_value 118 if (diffelev > 0)  119 if (servo_updown.read()  180)  120 servo_updown.write((servo_rightleft.read() - 2)); 121 > 122 > 123 if (diffelev  0)  124 if (servo_updown.read() > 0)  125 servo_updown.write((servo_rightleft.read() + 2)); 126 > 127 > 128 > 129 > 130 131void manualsolartracker() 132 buttonState2 = digitalRead(13); 133 if (buttonState2 != prevButtonState2)  134 if (buttonState2 == HIGH)  135 //Change mode and ligh up the correct indicator 136 if (axe == 1)  137 axe = 0; 138 > else  139 axe = 1; 140 > 141 > 142 > 143 prevButtonState2 = buttonState2; 144 delay(50); // Wait for 50 millisecond(s) 145 if (axe == 0)  //control right-left movement 146 servo_rightleft.write(map(analogRead(A4), 0, 1023, 0, 180)); 147 > else  // //control up-down movement 148 servo_updown.write(map(analogRead(A4), 0, 1023, 0, 180)); 149 > 150> 151 152 153 154 155

Embedded Software os solar tracker test bench

1//Servo motor library 2#include Servo.h> 3//Initialize variables 4int 5 mode = 0; 6int axe = 0; 7int buttonState1 = 0; 8int buttonState2 9 = 0; 10int prevButtonState1 = 0; 11int prevButtonState2 = 0; 12 13int ldrtopr= 14 0; // top-right LDR 15int ldrtopl = 1; 16 // top-left LDR 17int ldrbotr = 2; // 18 bottom-right LDR 19int ldrbotl = 3; // bottom-left 20 LDR 21int topl = 0; 22int topr = 0; 23int botl = 0; 24int 25 botr = 0; 26 27//Declare two servos 28Servo servo_updown; 29Servo servo_rightleft; 30 31int 32 threshold_value=10; //measurement sensitivity 33 34void setup() 35 36 37 Serial.begin(9600); //serial connection setup //opens 38 serial port, sets data rate to 9600 bps 39 Serial.println("CLEARDATA"); //clear 40 all data that’s been place in already 41 Serial.println("LABEL,t,voltage,current,power,Mode"); 42 //define the column headings (PLX-DAQ command) 43 44 pinMode(12, INPUT); //Mode 45 switch Button 46 pinMode(11, INPUT); //Axis switch 47 pinMode(A4, 48 INPUT); //Potentiometer for right-left movement and for up-down movement 49 50 51 servo_updown.attach(5); //Servo motor up-down movement 52 servo_rightleft.attach(6); 53 //Servo motor right-left movement 54> 55 56void loop() 57 58// pv_power(); 59char 60 Mode; 61 float volt = analogRead(A5)*5.0/1023; 62 float voltage = 2*volt; 63 // Volt=(R1/R1+R2)*Voltage / R1=R2=10Ohms => voltage=2*volt) 64 65 float current = voltage/20; // I=voltage/(R1+R2) 66 float power 67 = voltage*current; 68 Serial.print("DATA,TIME,"); // PLX-DAQ command 69 Serial.print(voltage); 70 //send the voltage to serial port 71 Serial.print(","); 72 Serial.print(current); 73 //send the current to serial port 74 Serial.print(","); 75 Serial.print(power); 76 //send the power to serial port 77 Serial.print(","); 78 79// Serial.println(Mode); 80 81 buttonState1 = digitalRead(12); 82 if (buttonState1 != prevButtonState1) 83  84 if (buttonState1 == HIGH)  85 //Change mode and ligh up the correct 86 indicator 87 if (mode == 1)  88 mode = 0; 89 > else  90 91 mode = 1; 92 > 93 > 94 > 95 prevButtonState1 = buttonState1; 96 97 delay(50); // Wait for 50 millisecond(s) 98 99 if (mode == 0)  100 Mode='M'; 101 102 Serial.println(Mode); //send Mode "Manual" to serial port 103 manualsolartracker(); 104 105 > else  // mode automatic 106 Mode = 'A'; 107 Serial.println(Mode); 108 109 automaticsolartracker(); //send Mode "Automatic" to serial port 110 > 111> 112 113void 114 automaticsolartracker() 115 116 //capturing analog values of each LDR 117 118 topr= analogRead(ldrtopr); //capturing analog value of top right LDR 119 120 topl= analogRead(ldrtopl); //capturing analog value of top left LDR 121 122 botr= analogRead(ldrbotr); //capturing analog value of bot right LDR 123 124 botl= analogRead(ldrbotl); //capturing analog value of bot left LDR 125 126 127 // calculating average 128 int avgtop = (topr + topl) / 2; //average 129 of top LDRs 130 int avgbot = (botr + botl) / 2; //average of bottom LDRs 131 132 int avgleft = (topl + botl) / 2; //average of left LDRs 133 int avgright 134 = (topr + botr) / 2; //average of right LDRs 135 136 //Get the different 137 138 int diffelev = avgtop - avgbot; //Get the different average betwen 139 LDRs top and LDRs bot 140 int diffazi = avgright - avgleft; //Get the different 141 average betwen LDRs right and LDRs left 142 143 //left-right movement of 144 solar tracker 145 146 if (abs(diffazi) >= threshold_value) //Change 147 position only if light difference is bigger then the threshold_value 148 if 149 (diffazi > 0)  150 if (servo_rightleft.read()  180)  151 servo_rightleft.write((servo_updown.read() 152 + 2)); 153 > 154 > 155 if (diffazi  0)  156 if (servo_rightleft.read() 157 > 0)  158 servo_rightleft.write((servo_updown.read() - 2)); 159 > 160 161 > 162 > 163 164 //up-down movement of solar tracker 165 166 167 if (abs(diffelev) >= threshold_value) //Change position only if light 168 difference is bigger then thethreshold_value 169 if (diffelev > 0)  170 if 171 (servo_updown.read()  180)  172 servo_updown.write((servo_rightleft.read() 173 - 2)); 174 > 175 > 176 if (diffelev  0)  177 if (servo_updown.read() 178 > 0)  179 servo_updown.write((servo_rightleft.read() + 2)); 180 > 181 182 > 183 > 184 > 185 186void manualsolartracker() 187 buttonState2 188 = digitalRead(13); 189 if (buttonState2 != prevButtonState2)  190 if (buttonState2 191 == HIGH)  192 //Change mode and ligh up the correct indicator 193 if 194 (axe == 1)  195 axe = 0; 196 > else  197 axe = 1; 198 > 199 200 > 201 > 202 prevButtonState2 = buttonState2; 203 delay(50); // Wait for 50 204 millisecond(s) 205 if (axe == 0)  //control right-left movement 206 servo_rightleft.write(map(analogRead(A4), 207 0, 1023, 0, 180)); 208 > else  // //control up-down movement 209 servo_updown.write(map(analogRead(A4), 210 0, 1023, 0, 180)); 211 > 212> 213 214 215 216 217

Electronic circuit of the solar tracker with manual and automatic modes

Electronic circuit of the solar tracker with manual and automatic modes