0
\$\begingroup\$

I'm 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 motors for each axis. The question that I'm wondering is that why is the PWM output inconsistent on the servo? I'm powering the Arduino with a USB port from my laptop. enter image description here

Here is the code :

 #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);
}
asked May 10, 2020 at 21:21
\$\endgroup\$
2
  • 1
    \$\begingroup\$ In what way are the PWM signals inconsistant? \$\endgroup\$ Commented May 10, 2020 at 21:25
  • \$\begingroup\$ @JRE For instance if you look at the serial port output, the voltages from the LDR are constant but the PWM outputs are fluctuating \$\endgroup\$ Commented May 10, 2020 at 21:36

1 Answer 1

1
\$\begingroup\$

Your problem lies in trying to read the PWM signal using pulseIn on the same channel you are doing servo.write.

You are changing the PWM width, then at some point you ask for a pulseIn. That command waits for a state transition on the specified pin.

Since the PWM signal and the start of the pulseIn wait period aren't synchronized, you read various pulse periods.

Don't bother with pulseIn. You are setting the pulse width using servo.write. Just log the value (servoHori and servoVerti) that you calculate and be done with it. Or are you concerned that the Arduino library won't actually set the pulse width (or angle) that you specified?

answered May 10, 2020 at 22:16
\$\endgroup\$
1
  • \$\begingroup\$ Thanks for replying, i understood what i did wrong. \$\endgroup\$ Commented May 14, 2020 at 11:59

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.