Solar tracking using arduino uno

Thread Starter

omfgdude753

Joined May 10, 2020
2
so im trying to design a dual axis solar tracker using an Arduino Uno-R3. Basically it just takes the input from the LDR and outputs the PWM signal to the two 9g servo motor for each axis. The question that im wondering is that why is the PWM output inconsistent on the servo? Im powering the Arduino with a USB port from my laptop.

Serial port output :
serial port.PNG

Here is the code :
Mod edit: deleted multiple screen shots of code. Code as text follows in next post - JohnInTX
https://forum.allaboutcircuits.com/threads/solar-tracking-using-arduino-uno.169586/post-1510266
 
Last edited by a moderator:

Thread Starter

omfgdude753

Joined May 10, 2020
2
C++:
#include <Servo.h>
#include <avr/sleep.h> // contains methods that controls sleep modes
//analog input range from 0 to 1023 to correspond to voltage between 0V to 5V.
Servo horizontal; // horizontal servo
Servo vertical;   // vertical servo

int servoHori = 90;   // horizontal servo initial position
int servoHoriLimitHigh = 180; // limit rotation angle for horizontal servo
int servoHoriLimitLow = 0;
int servoVerti = 0;   // vertical servo initial position
int servoVertiLimitHigh = 90; // limit rotation angle for vertical servo
int servoVertiLimitLow = 0;

//  LDR  = analogpin;
int ldrlt = 0; //LDR left top     
int ldrrt = 1; //LDR right top
int ldrld = 2; //LDR left down
int ldrrd = 3; //LDR right down
int triggerPin = 2; // digital pin 2 for interrupt

void wakeUpNow() //interrupt service routine
{
delay(100);
}

void setup() //
{
  Serial.begin(9600); //set the Arduino to transmit at 9600 bits per second (default baud rate).
  horizontal.attach(9); //horizontal servo to pin 9
  vertical.attach(10); // vertical servo to pin 10
  horizontal.write(90);
  vertical.write(0);
  delay(3000);
}

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

  // To scale the numbers between 0.0 and 5.0, divide 5.0 by 1023.0 and multiply that by sensorValue
  float voltage = lt * (5.0 / 1023.0);
  float voltage1= rt * (5.0 / 1023.0);
  float voltage2= ld * (5.0 / 1023.0);
  float voltage3= rd * (5.0 / 1023.0);

  // pulseIn(pin, value) pin, type of pulse high or low
  int pin9 = 9;
  int pin10 = 10;
  unsigned long ServoHpwm;
  unsigned long ServoVpwm;
  ServoHpwm = pulseIn(pin9, HIGH);
  ServoVpwm = pulseIn(pin10, HIGH);
 
  int deltime = 10;
  int tol = 50;
 
  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 Diffvert = avt - avd; // check the difference of up and down
  int Diffhoriz = avl - avr;// check the difference of left and right
  int ldrtot = avt + avd + avl + avr; //total value of ldr
 

  Serial.print(voltage);
  Serial.print(" ");
  Serial.print(voltage1);
  Serial.print(" ");
  Serial.print(voltage2);
  Serial.print(" ");
  Serial.print(voltage3);
  Serial.print("   ");
  Serial.print(deltime);
  Serial.print("   ");
  Serial.print(tol);
  Serial.print("   ");
  Serial.print(" ServoHpwm ");
  Serial.print(ServoHpwm);
  Serial.print(" ServoVpwm ");
  Serial.print(ServoVpwm); 
  Serial.println("   ");
 
  if (-1*tol > Diffvert || Diffvert > tol) // check if the difference is in the tolerance else change vertical angle
  {
  if (avt > avd)
  {
    servoVerti = ++servoVerti;  // if avt>avd vertical servo angle increase
     if (servoVerti > servoVertiLimitHigh)  // make sure vertical servo wont overshoot high limit
     {
      servoVerti = servoVertiLimitHigh;
     }
  }
  else if (avt < avd)
  {
    servoVerti= --servoVerti;  // if avt<avd vertical servo angle decrease
    if (servoVerti < servoVertiLimitLow)  //  make sure vertical servo wont overshoot low limit
  {
    servoVerti = servoVertiLimitLow;
  }
  }
  vertical.write(servoVerti); //Writes binary data to the serial port
  }
 
  if (-1*tol > Diffhoriz || Diffhoriz > tol) // check if the difference is in the tolerance else change horizontal angle
  {
  if (avl > avr)
  {
    servoHori = --servoHori; // if avl>avr, horizontal servo angle decrease
    if (servoHori < servoHoriLimitLow)
    {
    servoHori = servoHoriLimitLow; // make sure horizontal servo wont overshoot low limit (0)
    }
  }
  else if (avl < avr)
  {
    servoHori = ++servoHori; // if avl<avr horizontal servo angle increase
     if (servoHori > servoHoriLimitHigh) // make sure horizontal servo wont overshooot high limit (180)
     {
     servoHori = servoHoriLimitHigh;
     }
  }
  else if (avl = avr)
  {
    // nothing
  }
  horizontal.write(servoHori);
  }
 
  if ( ldrtot < 800)
  {
    servoHori=90;
    servoVerti=0;
    if(ldrtot < 800)
    {
     sleep_enable(); // enables the sleep bit in the mcucr register
     set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
     attachInterrupt (0,wakeUpNow,RISING);
     sleep_mode(); // here the device is actually put to sleep
     sleep_disable();
     detachInterrupt(0);
    }
  }
   delay(deltime);

}
 

ScottWang

Joined Aug 23, 2012
7,498
Please be sure that the LDR and PWM circuits are all good, otherwise please show their circuits.

If there is no circuit then please describe how their wiring, of course show the circuits is better.
 

ErnieM

Joined Apr 24, 2011
8,415
What do you do on mostly cloudy days? What happens when someone wearing shiny clothing walks by?

Why try and measure where the sun is (which is a difficult task) instead of predicting exactly where the sun will be by checking the date and time?

You can make up a look up table for the prediction.
 

KeithWalker

Joined Jul 10, 2017
3,603
You say that the PWM output is inconsistent. In what way? Please describe what should be happening and what is actually happening.
Regards,
Keith.
 
Top