0
votes

I'm trying to get a servo to move in the direction of the brightest light source and stop when they equal each other, but I've been running into issues. It seems to just make random movements and sometimes, barely work.

I've tried setting ranges (if they're within this range of each other). I've tried rounding the LDR values to the nearest hundred, that helped but it still just commits too much. I tried getting rid of all delay functions just in case they were messing it up but then it started twitching all over the place. Changing the value of the resistors I'm using(currently 220 ohm, but tried others, didn't have an effect).

 #include <Servo.h>
//Setup the integers and servo
int leftLightSensor = A1;
int rightLightSensor = A0;
int leftAnalogValue = 0;
int rightAnalogValue = 0;
int leftRoundedValue = 0;
int rightRoundedValue = 0;
int servoPin = 8;
Servo myServo;

//Attach the servo to the digital pin
void setup() {
  // put your setup code here, to run once:
  myServo.attach(servoPin);
  Serial.begin(9600);  // doing this just to be able to see the values I'm working with
}

//Do all the things
void loop() {
  // put your main code here, to run repeatedly:
  leftAnalogValue = analogRead(leftLightSensor);
  rightAnalogValue = analogRead(rightLightSensor);
  leftRoundedValue = 100*((leftAnalogValue + 50) / 100);  //rounding the values to the nearest hundred(ex. 342 = 300)
  rightRoundedValue = 100*((rightAnalogValue + 50) / 100); // same thing here
  delay(100);


  Serial.println(leftRoundedValue); 
  Serial.println(rightRoundedValue);

  if(leftRoundedValue > rightRoundedValue){
    myServo.write(0);
  }
  else if(leftRoundedValue < rightRoundedValue){
    myServo.write(180);
  }
  else{
    myServo.write(92);
  }
}

The goal is to have the servo rotate in the direction of the brightest light source and stop when it's pointing at it. But instead it just makes what appear to be random movements. Sometimes it will barely work for about a second and then go back to random movements.

1

1 Answers

0
votes

I see two big issues,

  1. is this line:

    if(leftRoundedValue > rightRoundedValue){ myServo.write(0); } else if(leftRoundedValue < rightRoundedValue){ myServo.write(180); } else{ myServo.write(92); }

You're telling it to move all the way to the extreme if the light is brighter on one side than the other. It seems from your description that what you really want to do is move just a little bit and test the light again. If the light is at position 120 then this code can never find it. It will go to 180, see that the light is to the left, then go to 0 and see that the light is to the right and then go to 180. It will never be able to go to any other position.

What's worse is that if it did find the light and the two values are equal, you don't tell it to stay there, you tell it to move to 92 which again, may not be where the light is.

The other one is this line:

leftRoundedValue = 100*((leftAnalogValue + 50) / 100); 

The first part of that can overflow if the analogvalue is greater than 277. Since everything there is int, the math will be done in 16 bit signed math and 100 * 328 will overflow and int and give a negative result. Do it like this instead:

leftRoundedValue = 100ul*((leftAnalogValue + 50) / 100); 

That will force the right hand side to be handled as 32 bit unsigned. It won't overflow and then the result should fit into an int.