Dual-axis solar tracker based of LDR, RTC, and GPS modules with smart monitoring system

Hi Guys!

I am currently doing a project on solar trackers and am very new to Arduino. I've been struggling with how I would generate a code for the RTC and GPS module in which they would calculate and track the solar positioning. I've seen a few studies relating to this but none of which I've seen show a code that could be my reference. The concept is a flower-like solar tracker (one reference of mine is from TechBoysToys)

Here are a few related undertakings:

The details:
I am using 6 total mini solar panels and 3 total motors: 2 servo motors which move rotates horizontally and vertically; 1 DC gear motor for the open-close movement. Currently, the project is dependent on the light intensity (using a 5mm photocell) which is communicated using Arduino UNO R3. I wanted to make it time-based/solar positioning algorithm based. I am planning to use an RTC (DS3231), and a GPS module (GY-NEO6MV2) for automatically collecting the data (Latitude, longitude, year, month, day, hour, minute, and second) and eventually use these data in calculating the sun's positioning.

Additionally, the data would be redirected to an android app (using an HC-05 Bluetooth module) which will show the voltage output of the solar + other data.

Here is the current code:

#include <Servo.h>

Servo horizontal; // horizontal servo
int servoh = 180;
int servohLimitHigh = 175;
int servohLimitLow = 5;
// 65 degrees MAX

Servo vertical; // vertical servo
int servov = 45;
int servovLimitHigh = 100;
int servovLimitLow = 1;

// LDR pin connections
// name = analogpin;
int ldrlt = A1; //LDR top left - BOTTOM LEFT <--- BDG
int ldrrt = A2; //LDR top right - BOTTOM RIGHT
int ldrld = A3; //LDR down left - TOP LEFT
int ldrrd = A4; //ldr down right - TOP RIGHT
int ldrmt = A5;

const int button1 = 7;
const int button2 = 8;
const int motorA = 9;
const int motorB = 10;
int buttonStateA = 0;
int buttonStateB = 0;

int pos = 0;
int pos2 = 0;
int oldvalue;
int oldvalue2;

void setup() {

  horizontal.attach(9);
  vertical.attach(10);
  horizontal.write(180);
  vertical.write(0); //45?
  pinMode(motorA, OUTPUT);
  pinMode(motorB, OUTPUT);
  pinMode(button1, INPUT);
  pinMode(button1, INPUT);
  delay(2500);
}
void loop() {
  int ldrStatus = analogRead(ldrmt);
  if (ldrStatus > 30) {
    buttonStateA = digitalRead(button1);
    if (buttonStateA == LOW) {

      digitalWrite(motorA, HIGH); //COUNTER clockwise
      digitalWrite(motorB, LOW);
    } else {
      digitalWrite(motorA, LOW);
      digitalWrite(motorB, LOW);
    }

    int lt = analogRead(ldrlt); // top left
    int rt = analogRead(ldrrt); // top right
    int ld = analogRead(ldrld); // down left
    int rd = analogRead(ldrrd); // down right
    int dtime = 10;
    int tol = 90; // dtime=diffirence time, tol=toleransi
    int avt = (lt + rt) / 2; // average value top
    int avd = (ld + rd) / 2; // average value down
    int avl = (lt + ld) / 2; // average value left
    int avr = (rt + rd) / 2; // average value right
    int dvert = avt - avd; // check the diffirence of up and down
    int dhoriz = avl - avr; // check the diffirence og left and rigt

    //if(lt>90){
    //if(Switch_a==LOW){
    // digitalWrite(9==HIGH);
    // digitalWrite(10==LOW);
    // delay(1000);
    //}}

    if (-1 * tol > dvert || dvert > tol) {
      if (avt > avd) {
        servov = ++servov;
        if (servov > servovLimitHigh) {
          servov = servovLimitHigh;
        }
      } else if (avt < avd) {
        servov = --servov;
        if (servov < servovLimitLow) {
          servov = servovLimitLow;
        }
      }
      vertical.write(servov);
    }
    if (-1 * tol > dhoriz || dhoriz > tol) // check if the diffirence is in the tolerance else change horizontal angle
    {
      if (avl > avr) {
        servoh = --servoh;
        if (servoh < servohLimitLow) {
          servoh = servohLimitLow;
        }
      } else if (avl < avr) {
        servoh = ++servoh;
        if (servoh > servohLimitHigh) {
          servoh = servohLimitHigh;
        }
      } else if (avl = avr) {
        delay(10);
      }
      horizontal.write(servoh);
    }

    delay(dtime);

  } else {
    oldvalue = horizontal.read();
    oldvalue2 = vertical.read();

    for (pos = oldvalue; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
      // in steps of 1 degree
      horizontal.write(pos);
      delay(15);
    }
    for (pos2 = oldvalue2; pos2 <= 0; pos2 += 1) { // goes from 0 degrees to 180 degrees
      // in steps of 1 degree

      vertical.write(pos2); // tell servo to go to position in variable 'pos'
      delay(15);
    }
    buttonStateB = digitalRead(button2);
    if (buttonStateB == LOW) {

      digitalWrite(motorA, LOW); //clockwise
      digitalWrite(motorB, HIGH);
    } else {
      digitalWrite(motorA, LOW);
      digitalWrite(motorB, LOW);
    }
  }
}

Do you guys have a reference code I can use in this project?

Can you guys help and guide me in creating the code? or somehow has tips I would gladly appreciate it. :grinning:

Thanks in Advance

I'm puzzled - if you've got GPS, what is the RTC for?
(Or vice versa, presuming you're not planning on moving the device, once installed)

1 Like

There is not much point in installing a GPS module, because you need to know the latitude and longitude only once, during installation. A smart phone can give you those values.

To calculate the two angles required to point the collector at the sun, at any time of day and at any location, the Arduino SolarPosition library is very handy.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.