Solar tracker 1 axis

Hi, newbie from Finland is needing some help with my project. Luckily it´s winter time here in Finland so I have couple of months to work with my tracker :slight_smile:

Here is code which I manage to do and I have tested this on table that it should work.
So I am controlling two relays with Arduino Nano and I have two LDR resistors to get feedback where sun is.

When I hide one LDR relay will go ON and so on.. Delays and tolerances between readings have to be adjusted on next spring.

But couple of questions, because I have also added to code two buttons so I can control rotation by hand, how code should be modified If I will add one more switch to AUTO/MANUAL operation?

And I also need to add couple of switches to limit rotation.
One opinion is to make code work like this: when tracker has worked whole day and will reach "night side" switch, Arduino will measure also Analog input 0 or 1 and when it´s dark it will automatically turn tracker to other side to "morning side" switch. Then it will start tracking sun based on tolerances between left and right measurements.

Is this right forum for this topic or should I ask from programming help?

/*
  Solar Tracker

  Controls two relays which will rotate solar panel stand to sun.

  The circuit:
  - Relay controls taken from Digital 12 and 13
  - Two pushbuttons attached to Digital pin 2 and 3 from +5V
  - 10K resistor attached to Digital pin 2 and 3 from ground
  - Two LDR resistors connected to Analog inputs A0 and A1

*/

// constants won't change. They're used here to set pin numbers:
const int buttonPinL = 2;     // number of Left switch
const int buttonPinR = 3;     // number of Right switch
const int relayPinL =  13;      // the number of the relay Left
const int relayPinR = 12;       //the number of the relay Right
// LDR and button pin connections
// name = analogpin;
const int ldrL = A0; //LDR left
const int ldrR = A1; //LDR right


// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
  // initialize the Relay pin as an output:
  pinMode(relayPinR , OUTPUT);
  pinMode(relayPinL , OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPinL, INPUT);
  pinMode(buttonPinR, INPUT);
}

void loop() {
  // read the state of the pushbutton L value:
  buttonState = digitalRead(buttonPinL);

  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState == HIGH) {
    // turn Relay on:
    digitalWrite(relayPinL, HIGH);
  } else {
    // turn Relay off:
    digitalWrite(relayPinL, LOW);

}
    
// read the state of the pushbutton R value:
  buttonState = digitalRead(buttonPinR);

  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState == HIGH) {
    // turn Relay on:
    digitalWrite(relayPinR, HIGH);
  } else {
    // turn Relay off:
    digitalWrite(relayPinR, LOW);
    
  }

  int left = analogRead(ldrL); // left
  int right = analogRead(ldrR); // right


  const int tol = 100; //tolerance between LDR readings

  int dhoriz = left - right;// check the diffirence between left and rigt


  if (-tol > dhoriz || dhoriz > tol) {
    // difference in horizontal is great enough to act on
    if (left > right) {
      // resistance on left is greater than on right
      digitalWrite(relayPinL, LOW);
      digitalWrite(relayPinR, HIGH);
    }
    else {
      // resistance on right is greater than on left
      digitalWrite(relayPinR, LOW);
      digitalWrite(relayPinL, HIGH);
    }
  }
  else {
    //difference in horizontal is below tolerance
    digitalWrite(relayPinL, LOW);
    digitalWrite(relayPinR, LOW);
  }

  // Wait a second before checking again
  delay(1000);

  }

Have You searched for solartrackers and Arduino? There are several ones being made already.

I assume that solar trackers using LDRs were fairly easy to make with discrete logic. Given the power of an Arduino though, I'd be inclined to abandon that method and use a clock or gps and calculate the position of the sun.

It may be suboptimal on a day with partial cloud cover perhaps, but equally would avoid the tendency for continuous seeking in such conditions.

I favour the use of a pair of LDRs and an Arduino. Arduinos are not expensive and using one is a lot simpler than building an electronic control circuit with discrete components. It also is a lot more flexible.

@Pahkis, it is not clear from your Original Post exactly what you want help with. (By the way this is a perfectly good place for your questions).

What does your program actually do and what do you want it to do that is different?

...R

You are on a good track. It's not random where the sun raises. Use that knowledge for the best angle to start watching. A sertain amount of "wide angle view" in case of clouds might be good. Sensing the sun is the key. Using an RTC might be useful. After a certain hour, resign and position for sunraise…..
No idea to randomly search the sky 360 degrees around, 0 to 90 degrees above the horizon.
I once judged the work of a sattellite searching project. It got the thumb down and the contractor kicked out.

Thanks to everybody for tips.
One opinion is to use real time clock for tracking, but at beginning I would like to test these LDR´s first.

I made code originally so that I can control relays by those Left/Right switches and those worked.
Later I added LDR measurements to control relays and that seems now working, but switches not working anymore..

I would like to change code so that I will add one switch as "manual mode" so that when it´s HIGH then relays can be controlled with switches, if it´s LOW then LDR´s will handle controlling.

I have to seek more examples from google how should I add also those morning/night switches to system

Pahkis:
I made code originally so that I can control relays by those Left/Right switches and those worked.
Later I added LDR measurements to control relays and that seems now working, but switches not working anymore..

I would like to change code so that I will add one switch as "manual mode" so that when it´s HIGH then relays can be controlled with switches, if it´s LOW then LDR´s will handle controlling.

You are not providing the sort of detailed information from which we can give you advice. Remember that we know nothing about your project except what you tell us.

One way to implement a manual / automatic system is to put the manual code in one function and the automatic code in another function. Then call the appropriate function depending on the state of the selector switch. Something like

void loop() {
   selectorState = digitalRead(selectorSwitchPin);
   if (selectorState == HIGH) {
      manualMode();
    }
   else {
     automaticMode();
   }
}

with the code for the different modes in the two functions.

Have a look at Planning and Implementing a Program

...R

Thanks for your help to everybody! Now code is working, but still some thinks to do, I need to add those two limit switches to code (on automatic mode) I have added those to code already as Inputs and to comments, but not yet to final code

/*
  Solar Tracker

  Controls two relays which will rotate solar panel stand to sun.

  The circuit:
  - Relay controls taken from Digital 12 and 13
  - Two pushbuttons attached to Digital pin 2 and 3 from +5V
  - One switch connected to Digital pin4 from +5V 
  - 10K resistor attached to Digital pins 2,3 and 4 from ground
  - Two LDR resistors connected to Analog inputs A0 and A1
  - Two limit switches for limiting rotation, named as M as morning, N as night

*/

// Digital pin connections and names:
const int buttonPinL = 2;     // number of Left switch
const int buttonPinR = 3;     // number of Right switch
const int buttonMA = 4;       // Manual/Auto switch D4
const int limitM = 5;     // Limit switch Morning
const int limitN = 6;     // Limit switch Night
const int relayPinL =  13;      // the number of the relay Left
const int relayPinR = 12;       //the number of the relay Right
// LDR pin connections and names
const int ldrL = A0; //LDR left
const int ldrR = A1; //LDR right


// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
  // initialize the Relay pin as an output:
  pinMode(relayPinR , OUTPUT);
  pinMode(relayPinL , OUTPUT);
  // initialize the pushbutton/switch pin´s as an input:
  pinMode(buttonPinL, INPUT);
  pinMode(buttonPinR, INPUT);
  pinMode(buttonMA, INPUT);
  pinMode(limitM, INPUT);
  pinMode(limitN, INPUT);
}

void loop() 
{
  if(digitalRead(buttonMA) == HIGH) //Manual Mode();
  {    
     // read the state of the pushbutton L value:
  buttonState = digitalRead(buttonPinL);
 
  if (buttonState == HIGH) {    // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
    // turn Relay on:
    digitalWrite(relayPinL, HIGH);
  } else {
    // turn Relay off:
    digitalWrite(relayPinL, LOW);
}
    
// read the state of the pushbutton R value:
  buttonState = digitalRead(buttonPinR);

  // Check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState == HIGH) {
    // turn Relay on:
    digitalWrite(relayPinR, HIGH);
  } else {
    // turn Relay off:
    digitalWrite(relayPinR, LOW);
    }
  }
  
  else
  
  {
    // Automatic mode
  
 int left = analogRead(ldrL); // Left
 int right = analogRead(ldrR); // Right


  const int tol = 100; // Tolerance between LDR readings

  int dhoriz = left - right;// Check the diffirence between left and rigt


  if (-tol > dhoriz || dhoriz > tol) {
    // difference in horizontal is great enough to act on
    if (left > right) {
      // resistance on left is greater than on right
      digitalWrite(relayPinL, LOW);
      digitalWrite(relayPinR, HIGH);
    }
    else {
      // resistance on right is greater than on left
      digitalWrite(relayPinR, LOW);
      digitalWrite(relayPinL, HIGH);
    }
  }
  else {
    //difference in horizontal is below tolerance
    digitalWrite(relayPinL, LOW);
    digitalWrite(relayPinR, LOW);
  }

  // Wait a second before checking again
  delay(1000);
}
  }

Take a step back, sort your thoughts and draw a flow chart or something like that.

If it's clear to you what you code should do, you can start implementing and it's going to be much easier, even if you have to start over