Building a Sun Tracker

by NotADesigner in Workshop > Energy

1137 Views, 24 Favorites, 0 Comments

Building a Sun Tracker

PXL_20240408_174323574.jpg

In this project, I will document the process of designing, coding, and assembling a sun tracker. My sun tracker, which will track the sun's position using a GPS moduel, is built using a 3D printer and utilizes widely available parts.

Supplies

Supplies.jpg

The main components of the sun tracker are:

  1. Arduino Nano RP2040 Connect
  2. SG90 Servo
  3. 28BYJ-48 Stepper + Driver
  4. Solar cell
  5. GPS + Compass
  6. 4x M3 screws


Apart from these components, you will need to have the following tools:

  1. 3D-printer or 3D-printing service
  2. Soldering kit
  3. Hot glue gun
  4. Alan Key (M3)
  5. Computer or PC

Designing in Fusion360

I designed all of my parts in Fusion360. I will however not go into depth of the modelling process in Fusion360. All of the models you´ll need are given below.

Assembling the Sun Tracker

After 3D-printing the parts, you now need to assemble it. Before starting, be sure to prepare the following tools:

  1. Hot glue gun
  2. Alan Key (M3)


Let´s get started with the assembly!

1. Step: In the first step you will need to take the solar cell, the 3D-printed piece "Holder" and the hot glue gun. Attach the solar cell to the "Holder" using the hot glue.

It´s important to place the positive (red) and negative (black) wire in between the slots of the "Holder" while attaching them.


2. Step: Connect the servo to the part "Connector", by pushing the servo into one of the "Connector's" holes. This step can require some force!


3. Step: Now put some hot glue between the servo and the "Connector" and press them together.


4. Step: Press the stepper motor and GPS into the corresponding indents of the "Plate". The stepper should now hold the whole weight of the solar cell, servo, "Holder", and "Connector" by itself. If this is not the case, you can further strengthen it with hot glue.


5. Step: Using the 4x M3 screws you can now connect the "Box" to the "Plate".


Now you´ll need to start wiring everything up

Wiring

Wiring.png

For this step, you will need the soldering kit and the wiring diagram given above.


1. You can wire the components to the Arduino as long as you follow the wiring diagram, however, it is helpful to start by wiring the GPS module first, as it is by far the most complex component to wire up. For a clean and smooth solder contact, it is helpful to tin the tips of the cable and put a little bit of solder on the contact you want to solder. After soldering the GPS module to the Arduino it should look like this.


2. After soldering the GPS module, you should now start soldering the stepper driver to the Arduino. I soldered my cables directly to the stepper driver, however you can also use jumper cables and push them into the pins.

Like the first step, you follow the wiring diagram and solder the cables correspondingly, with two exceptions. The + (positive) wire of the stepper driver will connect to the 3.3V pin on the other side, just as connecting the - (negative) wire to GND on the opposite side. The steps we have just taken are important to avoid too many cables being soldered to one pin on one side.

The result should look like that.


3. The servo is the last component you will need to solder. Like the steps above, you will just follow the wiring diagram. The finished wiring should look like this.


You are now finished with the hardware of the sun tracker! Let´s continue with uploading the code!

Uploading the Code

#include <SolarCalculator.h>
#include <Arduino.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_GPS.h>
#include <Adafruit_HMC5883_U.h>
#include <Stepper.h>
#include <Servo.h>


//GPS Config
#define GPSSerial Serial1

char noread;
bool GPSlock;

Adafruit_GPS GPS(&GPSSerial);

//Compass Config
int devangle, turndeg, pastturndeg, pastheaddeg, totaldeg, numsat;
double sunAZ, sunELE, AZangle;
const int utc = 2;
float headrad, headdeg, lon, lat;

Adafruit_HMC5883_Unified Compass = Adafruit_HMC5883_Unified(12345);

//Stepper Config
const int stepsrev = 32;
const int gearred = 64;
int difhead, difAZ;
double pastsunAZ;

Stepper Stepper(stepsrev, 6, 8, 7, 9 ); //1-3-2-4 Pins

//Servo Config
Servo servo;
const int servoPin = 5;

//Sunrise + Sunset
int sunriseint, sunsetint;
float sunrisefloat, sunsetfloat;
double sunrise, sunset, transit, timenow, sunriseclock, sunsetclock;

void setup() {
  Serial.begin(9600);
 
  //GPS + Compass Setup
  GPSSerial.begin(9600);
  GPS.begin(9600);
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
  GPSlock = false;
 
  sensor_t sensor;
  Compass.getSensor(&sensor);
  Compass.begin();

  //Stepper Setup
  devangle = 0.069;
  totaldeg = 0;
  pastturndeg = 0;
  pastheaddeg = 0;
  pastsunAZ = 0;
 
  //Servo Setup
  servo.attach(servoPin);
  servo.write(90);
}

void loop() {
  //Compass Loop
  sensors_event_t event;
  Compass.getEvent(&event);
 
  headrad = atan2(event.magnetic.y, event.magnetic.x);
  headrad += devangle;
 
  if(headrad < 0) {
    headrad += 2*PI;
  }
  if(headrad > 2*PI) {
    headrad -= 2*PI;
  }
 
  headdeg = headrad * 180/M_PI;

  //GPS Loop
  clearGPS();
 
  while(!GPS.newNMEAreceived()){
    noread = GPS.read();
  }

  GPS.parse(GPS.lastNMEA());
 
  numsat = GPS.satellites;
 
  if(GPS.fix) {
    lat = GPS.latitude/100;
    lon = GPS.longitude/100;
 
    GPSlock = true;
  }
 
  if(GPSlock == true) {
    //Solar Calculator
    calcHorizontalCoordinates(GPS.year, GPS.month, GPS.day, GPS.hour, GPS.minute, GPS.seconds, lat, lon, sunAZ, sunELE);
   
    //Sunrise + Sunset
    calcCivilDawnDusk(GPS.year, GPS.month, GPS.day, lat, lon, transit, sunrise, sunset);
   
    sunriseint = sunrise;
    sunrisefloat = (sunrise - sunriseint)*0.6;
    sunriseclock = sunriseint + sunrisefloat + utc;

    sunsetint = sunset;
    sunsetfloat = (sunset - sunsetint)*0.6;
    sunsetclock = sunsetint + sunsetfloat + utc;
   
    timenow = (GPS.hour + utc) + (GPS.minute/60);
   
    //Servo Loop
    servo.write(180 - sunELE);

    //Stepper Loop
    AZangle = sunAZ-headdeg;

    difhead = (headdeg-pastheaddeg);
    difAZ = (sunAZ-pastsunAZ);

    AZangle = (difAZ-difhead); //headdeg

    if(AZangle >= 180) {
      AZangle = AZangle - 360;
    }
    if(AZangle <= -180) {
      AZangle = AZangle + 360;
    }
   
    AZangle = AZangle*5,688;

    Stepper.setSpeed(300);
    Stepper.step(round(AZangle));

    pastheaddeg = headdeg;
    pastsunAZ = sunAZ;
  }

  Serial.println("Heading in degrees: ");
  Serial.print(headdeg);
  Serial.println("GPS-lock: ");
  Serial.print(GPSlock);
  Serial.println("Elevation of the sun: ");
  Serial.print(sunELE);
  Serial.println("Azimuth of the sun");
  Serial.print(sunAZ);
}

void clearGPS() {
  while(!GPS.newNMEAreceived()) {
    noread = GPS.read();
  }

  while(!GPS.newNMEAreceived()) {
    noread = GPS.read();
  }

  GPS.parse(GPS.lastNMEA());
}

//Code made by @NotADesigner


To upload the code to the Arduino you first need to install the Arduino IDE. After downloading and opening the Sun_Tracker.ino file, provided below, you can now connect the Arduino to your PC or computer. Alternatively, you can create a new Arduino Project and paste the code from above.

Now you can select the board in the Arduino programming environment and click the arrow to upload the code.


If you have successfully uploaded the code, this notification should pop up!

Downloads

Your Sun Tracker

Unbenanntes Video (3).gif

You can now use your sun tracker to track the sun. In my case, I hooked up a led to my solar cell, but you can do whatever you want with it! Try something new, and most importantly have fun!