Introduction: Solar Tracker Using Arduino and Raspberry Pi 3

This Instructable will teach you how to create a solar tracker using Arduino and Raspberry Pi 3 Model B. We will also learn how to create a graphic user interface using Processing.

As we all know, energy is an indispensable part of our lives. From transportation to agriculture, cooking to water heating, air conditioners to refrigerators, using laptops to watching television, using phones to watch silly videos to typing this very Instructable, everything needs energy!

Solar energy is the cleanest form of renewable energy which can be used to satisfy the growing need for energy while supporting sustainable development.
However, the use of solar energy can face certain problems. One such problem is that the position of the sun throughout the day varies.

We can solve this problem by creating a solar tracker. A solar tracker is a device which tracks the position of the sun and alters the position of the solar panel to maximize the power output of the system.

Components required-

1) Jumper wires

2) Sheet metal (alternative: cardboard)

3) 2 Servo motors

4) 4 Light dependent resistors

5) Arduino + Arduino cable

6) Raspberry Pi 3 Model B + keyboard, mouse, power supply and monitor for using RPi

7) Solar panel

8) Four 10K ohm resistors

Components required for manufacturing PCB (optional step)-

1) FeCl2 solution

2) Acetone

3) Etching marker

4) one component side PCB

5) Soldering rod

6) Solder

Softwares required-

1) Arduino

2) Raspbian Jessie

3) Eagle or Fritzing

4) Processing

Step 1: Draw and Understand Schematic Diagram

The schematic can be made using either Fritzing or Eagle software. Here, the basic schematic was made using Fritzing.

4 Light dependent resistors are used on four corners of the solar panel to sense light. The values from these LDRs is read by the Arduino.
To move the solar panel, we use servo motors. The bottom servo motor is the horizontal servo motor whereas the top servo motor is the vertical servo motor.
The average of the two top and the two bottom LDRs is calculated. If the average of the two top LDRs is more, then the vertical servo motor rotates towards that side. If the average of the two bottom LDRs is more, then the vertical servo motor rotates towards the bottom side.
The average of the two right and the two left LDRs is calculated. If the average of the two right LDRs is more, then the horizontal servo motor rotates towards that side. If the average of the two left LDRs is more, then the horizontal servo motor moves towards that side.
This is the logic behind the code used to create the solar tracker.

Step 2: Design and Manufacture PCB (optional Step)

The wiring of the solar tracker is a lot and can cause hindrance to the motion of the tracker.

One of the workable solutions for this problem is to design and manufacture a customized printed circuit board.

Steps to design and manufacture a PCB-

1) Design schematic using Eagle software

2) Print the schematic on glossy paper

3) Iron the glossy paper on the one component side PCB

4) Apply etching marker to all the tracks as a safety measure

5) Dip PCB inside FeCl2 (ferrous chloride) solution for about 30 minutes to complete the etching process

6) Use water to get rid of excess ferrous chloride on the PCB

7) Use acetone to clean the tracks

8) Place the components at appropriate places and solder them

An alternative to this step is to use a cardboard piece to support the LDRs and the solar panel. It will be explained in the next step.

Step 3: The Setup

1) To start the setup, create a base for the setup. Here, heavy sheet metal is used as a base to support the entire structure. Alternatively, a cardboard piece could be used for the same.

2) Cut two metal strips out of light sheet metal. Drill one hole on each strip to attach the servo motors as shown. Alternatively, two perforated metal strips could be used.

3) In case you have decided not to create a PCB, then take a piece of cardboard to support the LDRs. Look at the image to understand the position of the LDRs and solar panel.

4) Attach one servo motor to one metal strip that has a hole in the middle. Stick that servo motor to the base and bend the metal strip as shown.

5) Attach the other servo motor to the other metal strip that has one hole on one of its ends. Bend the metal strip as shown. Stick this servo motor to the previously placed metal strip such that the servo motor can move without hindrance.

6) Stick the PCB or cardboard (with LDRs and solar panel) on top of the second metal strip.

7) Make the necessary connections by checking the schematic.

Step 4: Steps to Use Raspberry Pi 3 Model B (optional)

Arduino can be used via a laptop. Alternatively, it can be used via Raspberry Pi. Arduino can be directly connected to RPi using one of its USB ports.
Processing can also be used either on laptop or on RPi.
However, it is mandatory to use the same device for both Processing and Arduino at one time.

First, setup RPi using any of the tutorials available online.
Then, download Arduino on it using

sudo apt-get install Arduino

from command line.

Download Processing on Rpi using

curl | sudo sh

from command line.

Step 5: Arduino Code

#include<Servo.h> //header file for using servo motors

//define Servos

Servo servohori; //horizontal servo motor

int servoh = 0;

int servohLimitHigh = 160;

int servohLimitLow = 20;

Servo servoverti; //vertical servo motor

int servov = 0;

int servovLimitHigh = 160;

int servovLimitLow = 20;

//define LDRs

int ldr1 = 0; //top left

int ldr2 = 1; //top right

int ldr3 = 2; //bottom right

int ldr4 = 3; //bottom left

void setup ()


Serial.begin(9600); //start serial monitor







void loop()


servoh =;

servov =;

//capture analog values of each LDR

int reading1 = analogRead(ldr1);

int reading2 = analogRead(ldr2)-;

int reading3 = analogRead(ldr3);

int reading4 = analogRead(ldr4);

//necessary to send values to serial monitor so that Arduino can communicate with Processing













// calculate average

int avg12 = (reading1 + reading2) / 2;

int avg34 = (reading3 + reading4) / 2;

int avg32 = (reading3 + reading2) / 2;

int avg41 = (reading1 + reading4) / 2;

//compare average of two and move servo motors accordingly

if ( avg12>avg34)


servoverti.write(servov +1);

if (servov > servovLimitHigh)


servov = servovLimitHigh;




else if (avg12 < avg34)


servoverti.write(servov -1);

if (servov < servovLimitLow)


servov = servovLimitLow;








if (avg32 < avg41)


servohori.write(servoh +1);

if (servoh > servohLimitHigh)


servoh = servohLimitHigh;




else if (avg32 > avg41)


servohori.write(servoh -1);

if (servoh < servohLimitLow)


servoh = servohLimitLow;










Step 6: Processing Code

A graphic user interface was created using Processing.
The rectangles represent the value of the LDRs and the circles with arcs represent the angle of the servo motors.

The code-

import processing.serial.*; //to communicate with the serial monitor of Arduino

Serial myPort;

int[] inStr = {0,0,0,0,0,0};

void setup()


size(1200,650,P3D); //to define size of the GUI window

background(0); //to make the background black

myPort=new Serial(this, "COM4", 9600); //In place of COM4, use the Arduino port in your laptop or Raspberry Pi. Make sure the baud rate is the same as the one given in Arduino code.



void draw()


background(0); //The background is declared as black again. This is necessary so that the motion described in the draw function appears without any distortions.

//for servo motor 1

fill(100,100,200); //to give color to the object

ellipse(1000, 200, 100,100);



text("Servo 1", 970, 300);

arc(1000,200,100,100 ,radians(180),radians(180+inStr[4])); //to draw a dynamic arc to represent the angle of the servo motor

//for servo motor 2


ellipse(1000, 450, 100, 100);



text("Servo 2", 970, 550);

arc(1000,450,100,100, radians(180),radians(180+inStr[5]));

//for LDR1

fill(200, 200, 0);

rect(100, 570, 100, -inStr[0]); //draw a dynamic rectangle to represent the value of the LDR



text("LDR1", 100, 600);

//for LDR2

fill(200, 100, 100);

rect(300,570, 100, -inStr[1]);



text("LDR2", 300, 600);

//for LDR3

fill(100, 200, 100);

rect(500, 570, 100, -inStr[2]);



text("LDR3", 500, 600);

//for LDR4


rect(700, 570, 100, -inStr[3]);



text("LDR4", 700, 600);


void serialEvent(Serial myPort)


String inString = myPort.readStringUntil('\n'); //read values from serial monitor



inString = trim(inString);

inStr = int(split(inString, ',')); //split the values from the serial monitor where a comma is encountered. Store each value in the array inStr



Step 7: Demonstration :)

Robotics Contest 2017

Participated in the
Robotics Contest 2017

Microcontroller Contest 2017

Participated in the
Microcontroller Contest 2017