sharp IR glued to Hitec servo (robot eyes)

I am using an Arduino Uno board to control a non modified Hitec servo (0 to 180 degree) and a sharp IR. The sensor is glued on so that it is facing “forward” when I drive the servo to 90 degrees. My goal is to have the servo do a sweep from 0 degrees to 180 degrees while I take measurements from the Sharp IR so I can get a feel for what is in front of my robot. I have posted the following test code I am working on to make this work. I have the line that actually stores what the sharp IR is reading commented out below. With it commented out this is the fastest I can get him to turn his “neck” from 0 degrees to 180 degrees.

For now I would be happy to get a reading every 5 degrees. So I store the reading from the sensor every 5 degrees in my array and then print it out when it is done turning his neck. My problem is he is about 15 degrees off. I know this because i set the delays for much longer so he turned his head very slow. I place objects directly in front of him and on his sides. Then I compared this slow accurate output to my output with the following code–but with the one line un-commented. I can get accurate readings if I make the delay large enough that he is turning his head about ½ or [ch8531] the speed he is currently turning.

I feel like I shouldn’t have to increase the delay because at the point in code where he makes a reading, if he is pointing to where I think he should be (the last neckservo.write position), the reading should be accurate. Does anyone have any ideas.

p.s. I realized on my read through that when I said accurate I am not clear. I believe I am receiving accurate data in distance but that it is off by 15 degrees. So my accurate readings show an object close by at val[90] and val[95] my code below shows the object close by in val[115] and val[120].

Thanks in advance for any help. I really do appreciate it.

#include <SoftwareServo.h>

SoftwareServo neckservo;

int test_flag = 1;

int c;
int eyes = 0;
int val[180];

void setup()
{
Serial.begin(9600);
neckservo.attach(2);
}

void look_left(int limit)
{
for(c = 0; c < limit; c++)
{
neckservo.write(0);
delay(15);
SoftwareServo::refresh();
}
}

void loop()
{

while(test_flag)
{
look_left(100);

for(c=0; c <= 180; c = c+5)
{
neckservo.write(c);
SoftwareServo::refresh();

//val

 = analogRead(eyes);
      
      neckservo.write(c+1);
      SoftwareServo::refresh();
      delay(3);
      neckservo.write(c+2);
      SoftwareServo::refresh();
      delay(3);
      neckservo.write(c+3);
      SoftwareServo::refresh();
      delay(3);
      neckservo.write(c+4);
      SoftwareServo::refresh();
      delay(3);
      neckservo.write(c+5);
      SoftwareServo::refresh();
      delay(3);
    }
    
    for(c=0; c <= 180; c = c+5)
    {
      Serial.print("val[");
      Serial.print(c);      Serial.print("]: ");
      Serial.print(val[c]);
      Serial.print("\n");
    }
    test_flag = 0;
  }
}

The ADC takes time to get a stable reading. By the time the reading has stabilized, you’ve changed where the sensor is pointing, so the value being read has changed.

You’ll need to stop the servo long enough to get accurate readings. How? In a minute. First, some questions.

Which Arduino do you have?

Which IR sensor is it? What is it’s field-of-view?

Why are you using SoftwareServo instead of Servo? The Servo library uses a timer, and can control multiple servos. Unless you are trying to control more servos that Servo can control, or need the timer that Servo uses for some other purpose, you should be using the hardware-based Servo library.

void look_left(int limit)
{
 for(c = 0; c < limit; c++)
 {
     neckservo.write(0);
     delay(15);
     SoftwareServo::refresh();
 }
}

This code sends the servo to the same position many times, waiting a short time after each write. Why? If the function sent the servo to a different position each pass through loop, it would make sense, but that is not what it does.

Have you timed how fast your servo can move from 0 to 180? Does the delay (int the rest of your code) reflect how long it takes to move 1 degree?

Is the stuff that the sensor is sensing moving or static? If it is moving, how fast is it moving? How fast does the robot move? Is it moving while scanning?

The answers to these questions will help us decide on an approach that will minimize the problems you are having.

Having a robot move at 30 MPH among other moving things, scanning and reacting at the same time, is not going to be possible with the Arduino and an IR sensor.