Solar tracker not working in sunlight

Hello All,
My solar dual axis tracker works well under artificial light and follows torch light perfectly, BUT as soon as I put it outside in the sun( no clouds) ,it goes to it's start position and ignores the sun. I put opaque plastic caps (ex pir sensors) on the 4 LDR's, to soften the sun light, but it made no difference.
Can someone please suggest what is wrong with the below code? Many thanks..Use code tags to format code for the forum

pin :face_with_raised_eyebrow:assignment questionable ???

The numbers represent analog's eg A0,A1,A2,A3 for 0,1,2,3

please re-edit your first post to put your code into a so called code-section

It is very unlikely that your code is causing the malfunction, because it works with flashlight as inteneded.

For analysing if your LDRs are saturated or not by the much brighter sunlight you should add code that prints the values of the analogRead-functions to the serial monitor.

Even a pretty "strong" flashlight might have 500 Lumen of light intensity
Bright sunlight is 10000 Lumen. 20 times more.

Which means all four LDRs are reporting "uaaah is this bright ! Bring me the sunscreen and my sun-glasses!"

Or in ADC-numbers
All four LDRs report ADC-value 1023 (if your microcontroller is an arduino-Uno)
even in case your sensors look under an angle of 45 degrees to the sun.

StefanL38. -->Sorry, but I have no idea where the code section is. I put my code between a start and end code tag, apart from that I have no idea, sorry.

You simply click on this link below and then you can read a tutorial that shows it step by step

Use a local RTC to turn the solar tracker simply.

2 Likes

Hi, @amspen
Can you please post some images of your tracker, in particular the LDR sensor assembly.

Can you please post a copy of your circuit, a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, power supplies, component names and pin labels.

Before you repost your code, press [ CTRL ] [ T ] , this will auto format your code and make it easier to follow.

Can I suggest some Serial.print statements in your code to display the sensor data on the IDE monitor.
Also change Serial.begin(9600) to Serial.begin(115200), then make sure you change the baud rate in the IDE monitor to 115200.

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

Format your code using Tools/Auto Format in the future.
The sun is several orders of magnitude stronger than whatever you used, you will need to adjust sensitivity.

Hello Tom
I got the code from :https://www.instructables.com/Arduino-Solar-Tracker/
I set the Serial.begin to 115200 , as you suggest
I don't know how to put :Serial.print statements in the code.

Hi, @amspen

Can you please post your code?
To add code please click this link;

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:




#include <Servo.h> // include Servo library 

Servo horizontal; // horizontal servo
int servoh = 90; // stand horizontal servo

Servo vertical; // vertical servo
int servov = 90; // stand vertical servo

int tol = 50; // Increase tolerance
int dtime = 10; // Reduce delay for faster response

// LDR pin connections
// name = analogpin;
int ldrlt = 0; //LDR top left
int ldrrt = 1; //LDR top right
int ldrld = 2; //LDR down left
int ldrrd = 3; //ldr down right

void setup()
{
  Serial.begin(115200);
  // servo connections
  // name.attacht(pin);
  horizontal.attach(9);
  vertical.attach(10);
}

void loop()
{
  int lt = analogRead(ldrlt); //  left top
  int rt = analogRead(ldrrt); //  right top
  int ld = analogRead(ldrld); //  left down
  int rd = analogRead(ldrrd); //  right down

  int dtime = analogRead(4) / 20; // read potentiometer
  int tol = analogRead(5) / 4;

  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 difference of top and down
  int dhoriz = avl - avr;// check the difference of left and right

  if (-1 * tol > dvert || dvert > tol) // check if the diffirence is in the tolerance else change vertical angle
  { // || means "OR"
    if (avt > avd)
    {
      servov = ++servov;
      if (servov > 180)
      {
        servov = 180;
      }
    }
    else if (avt < avd)
    {
      servov = --servov;
      if (servov < 0)
      {
        servov = 0;
      }
    }
    vertical.write(servov);
  }

  if (-1 * tol > dhoriz || dhoriz > tol) // check if the difference is in the tolerance else
    //change horizontal angle
  {
    if (avl > avr)
    {
      servoh = --servoh;
      if (servoh < 0)
      {
        servoh = 0;
      }
    }
    else if (avl < avr)
    {
      servoh = ++servoh;
      if (servoh > 180)
      {
        servoh = 180;
      }
    }
    else if (avl == avr)
    {
      // nothing
    }
    horizontal.write(servoh);
  }
  delay(dtime);
}

Hi, @amspen
I have edited your code to include a monitor display function.
When you try it, make sure the IDE monitor speed is set to 115200.
It will give you the raw data from each of the LDRs.

#include <Servo.h>  // include Servo library

Servo horizontal;  // horizontal servo
int servoh = 90;   // stand horizontal servo

Servo vertical;   // vertical servo
int servov = 90;  // stand vertical servo

int tol = 50;    // Increase tolerance
int dtime = 10;  // Reduce delay for faster response

// LDR pin connections
// name = analogpin;
int ldrlt = 0;  //LDR top left
int ldrrt = 1;  //LDR top right
int ldrld = 2;  //LDR down left
int ldrrd = 3;  //ldr down right

int lt;
int rt;
int ld;
int rd;

void setup() {
  Serial.begin(115200);
  // servo connections
  // name.attacht(pin);
  horizontal.attach(9);
  vertical.attach(10);
}

void loop() {
  lt = analogRead(ldrlt);  //  left top
  rt = analogRead(ldrrt);  //  right top
  ld = analogRead(ldrld);  //  left down
  rd = analogRead(ldrrd);  //  right down
  serialout();
  int dtime = analogRead(4) / 20;  // read potentiometer
  int tol = analogRead(5) / 4;

  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 difference of top and down
  int dhoriz = avl - avr;  // check the difference of left and right

  if (-1 * tol > dvert || dvert > tol)  // check if the diffirence is in the tolerance else change vertical angle
  {                                     // || means "OR"
    if (avt > avd) {
      servov = ++servov;
      if (servov > 180) {
        servov = 180;
      }
    } else if (avt < avd) {
      servov = --servov;
      if (servov < 0) {
        servov = 0;
      }
    }
    vertical.write(servov);
  }

  if (-1 * tol > dhoriz || dhoriz > tol)  // check if the difference is in the tolerance else
  //change horizontal angle
  {
    if (avl > avr) {
      servoh = --servoh;
      if (servoh < 0) {
        servoh = 0;
      }
    } else if (avl < avr) {
      servoh = ++servoh;
      if (servoh > 180) {
        servoh = 180;
      }
    } else if (avl == avr) {
      // nothing
    }
    horizontal.write(servoh);
  }
  delay(dtime);
}
//==================================
void serialout() {
  Serial.print("lefttop = ");
  Serial.print(lt);
  Serial.print("\t righttop = ");
  Serial.print(rt);
  Serial.print("\t leftdown = ");
  Serial.print(ld);
  Serial.print("\t rightdown = ");
  Serial.println(rd);
}

You should see the values change as you cover each LDR.
You do have the X shaped visor on the LDR assembly?

Tom... :smiley: :+1: :coffee: :australia:

Hi,
I have edited it a bit more to allow the ADC to keep up with the multiplexed inputs.

#include <Servo.h>  // include Servo library

Servo horizontal;  // horizontal servo
int servoh = 90;   // stand horizontal servo

Servo vertical;   // vertical servo
int servov = 90;  // stand vertical servo

int tol = 50;    // Increase tolerance
int dtime = 10;  // Reduce delay for faster response

// LDR pin connections
// name = analogpin;
int ldrlt = 0;  //LDR top left
int ldrrt = 1;  //LDR top right
int ldrld = 2;  //LDR down left
int ldrrd = 3;  //ldr down right

int lt;
int rt;
int ld;
int rd;

void setup() {
  Serial.begin(115200);
  // servo connections
  // name.attacht(pin);
  horizontal.attach(9);
  vertical.attach(10);
}

void loop() {
  lt = analogRead(ldrlt);  //  left top
  lt = analogRead(ldrlt);  //  left top
  rt = analogRead(ldrrt);  //  right top
  rt = analogRead(ldrrt);  //  right top
  ld = analogRead(ldrld);  //  left down
  ld = analogRead(ldrld);  //  left down
  rd = analogRead(ldrrd);  //  right down
  rd = analogRead(ldrrd);  //  right down
  serialout();
  int dtime = analogRead(4) / 20;  // read potentiometer
  int tol = analogRead(5) / 4;

  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 difference of top and down
  int dhoriz = avl - avr;  // check the difference of left and right

  if (-1 * tol > dvert || dvert > tol)  // check if the diffirence is in the tolerance else change vertical angle
  {                                     // || means "OR"
    if (avt > avd) {
      servov = ++servov;
      if (servov > 180) {
        servov = 180;
      }
    } else if (avt < avd) {
      servov = --servov;
      if (servov < 0) {
        servov = 0;
      }
    }
    vertical.write(servov);
  }

  if (-1 * tol > dhoriz || dhoriz > tol)  // check if the difference is in the tolerance else
  //change horizontal angle
  {
    if (avl > avr) {
      servoh = --servoh;
      if (servoh < 0) {
        servoh = 0;
      }
    } else if (avl < avr) {
      servoh = ++servoh;
      if (servoh > 180) {
        servoh = 180;
      }
    } else if (avl == avr) {
      // nothing
    }
    horizontal.write(servoh);
  }
  delay(dtime);
}
//==================================
void serialout() {
  Serial.print("lefttop = ");
  Serial.print(lt);
  Serial.print("\t righttop = ");
  Serial.print(rt);
  Serial.print("\t leftdown = ");
  Serial.print(ld);
  Serial.print("\t rightdown = ");
  Serial.println(rd);
}

Tom.. :smiley: :+1: :coffee: :australia:

1 Like

Hi Tom. All values show 1023 in the sun and the X shaped visor in the picture, is near identical to the one I made, which I painted matt black.

Sounds like a problem in the wiring or choice of components (the LDRs and associated resistors).

The wiring diagram in the original Instructables is nearly uninterpretable, and the 10K value for the resistors in the voltage dividers is probably much too large. Or, the ground connection is missing.

Something like this would probably work, with resistors of 1K or less:

1 Like

What if you cover them up, or even just one LDR, can you see a difference?
You are running the code in post #15?

Tom.. :smiley: :+1: :coffee: :australia:

I uploaded your last code:
Inside all show values around 600/800 , using a led torch all values go to 1023.
Outside all values also show 1023. Blocking light on each, decreases the value and instantly changes the orientation.

Hi,
Take @jremington advise in post #17, that should help.

The LDRs are saturated even in the shade of the sun.

Tom.. :smiley: :+1: :coffee: :australia:

The diagram you are showing is the same as what I made.
The only difference is the resistor value, mine are 10K.
I will replace mine later with 330 Ohm, as you suggest .
As a matter of interest, What are the pot meters connected to A4 (tolerance ) & A5 (speed) for?