Using an IR sensor to track position of a servo

Hi,

My project requires me to build a robot that can navigate an obstacle course without remote control.

I have used this http://forum.arduino.cc/index.php/topic,8666.0.html as a guide and so far I have hooked up the hardware and I can debug/read the IR sensor values when connected to the analog pin. The main difference between that and mine is that I am using servos not PWM and motors. I also read somewhere that using digital pins would be better than analog but am unsure how to code that.

I am wanting to be able to count how many times the sensor reads a change from black to white (or something similar to read movement) so that I can caluculate how far the robot has gone and then say after x amount of turns, turn robot left, then go straight then after x amount of turns, turn robot right etc.

I'd appreciate any help coding this or direction to where I can get more info to code this properly. and apologies for my lack of knowlede-I have been using Arduino for about 10 days.

Cheers

My setup so far: https://www.dropbox.com/s/58rm8lddpshjuxy/IMG_1392.JPG

rgsp: I am using servos not PWM and motors

Are these continuous rotation servos aka a motor and gearbox with integrated speed control? If so, you can treat them very similarly to a PWM-controlled motor, just control them with a servo object instead of an analogWrite. Have you got to the point where you can control the direction and speed of each motor?

Yes they are continuous rotation. I use myservo.writeMicroseconds(value) to control them. I can control the speed forwards and backwards of the servos.

I planned on having them at full speed apart from when they are turning (one side stops to turn) because the run over the obstacle course will be timed.

would coding them similar to a pwm motor allow me to use the wheel encoder to track and give instructions depending on how many rotations the wheels have done?

Wheel encoders will work the same however you drive the wheels, so you can use them whilst using the Servo library to control the speed and direction of the wheels. All encoders do is to allow you to count rotations and partial rotations no matter what makes the wheel turn.

yes i understand that. How to count the rotations is what I do not know how to code.

What would be the most efficient way?

rgsp: How to count the rotations is what I do not know how to code.

It seems that your question is nothing to do with the motor and how it's driven, and is just about how to read an encoder.

However, you've already shown us a link to a thread giving full details of the hardware and software to do that, so I'm at a loss to understand what else you are hoping for.

yes- I am unsure on how to read an encoder.

I have tried the code from the linked thread. The number of clicks and turns went up really fast, even when the servo was not moving. I do not know what to change in order to get it going--I thought the problem could be using servo instead of motors. This is why I asked the question on here.

Also the wheel is spinning at about 60 - 80 rpm. is that too fast for the sensor to read?

Cheers for the help so far

You need to find out why the number of clicks increases when the wheel is not moving. Does it still still increase if the IR sensor is covered so that no light can get to it ?

60 - 80 rpm should be no problem.

yes-the number of clicks and turns increases when the servos are not moving and the sensor is covered up.

this is the code from the linked post which I have change to read the sonsor off the analog input. I am still not sure what the PWM does.

#define IOP 0
#define PWM 3

int val_new;
int val_old;
int clicks = 0;
int turns = 0;

void setup() {
      Serial.begin(115200);
      pinMode(IOP, INPUT);

      val_new = analogRead(IOP);
      val_old = val_new;
}

void loop() {
      analogWrite(PWM, 80);

      val_new = analogRead(IOP);
      
      if(val_new != val_old) {
            if(clicks == 40) {
                  clicks = 1;
                  turns++;

                  Serial.print("TURNS: ");
                  Serial.println(turns);   
            }
            else clicks++;
            
            Serial.print("CLICKS: ");
            Serial.println(clicks);

            val_old = val_new;
      }
}

rgsp: this is the code from the linked post which I have change to read the sonsor off the analog input

That code is looking for any change in the return value from analogRead(), which will naturally be fluctuating slightly just due to sampling noise, so it's hardly surprising that you are picking up spurious changes. Shouldn't you be looking for the signal going above/below a threshold, preferably with debounce and/or hysteresis? Depending on the levels, you might even be able to use a digital read.

[/quote]
“looking for the signal going above/below a threshold, preferably with debounce and/or hysteresis? Depending on the levels, you might even be able to use a digital read.”
[/quote]

This sounds exactly what I want to do I think!

I want to count how many times it changes from black to white and then use this to say for example; “after 100 changes from black to white, stop servo for 3 seconds and then start again” – Are you able to help me with some basic code to do this?

I am not sure what you mean by debounce or hysteresis.

At the moment, using analog inputs, the black reads about 4 and white is about 30 on the serial monitor.

This is the sort of thing you need to do

read the sensor
if sensor value less than 4
  set prevValue to LOW
else
  set prevValue to HIGH
end of if

start of loop
  read the sensor
  if (sensorValue greater than 4 and prevValue equals LOW) or (sensorValue less than 4 and prevValue equals HIGH)
    add one to clicks
    set prevValue to !prevValue
  end of if
  
  use value of clicks to do stuff
  
 end of loop

NOTE 1 (hysteresis) - the pseudo code above expects there to be a clean change between the readings at a value of 4 so that HIGH/LOW can be determined, but that will not happen in practice so you may need to consider LOW as being below (say) 3 and HIGH above (say) 5 to allow some latitude in the readings.

NOTE 2 (debounce) - the input may change rapidly several times as the sensor reads the edge of the black/white thus causing a false number of changing readings. This 'bouncing' effect is more usual with mechanical switches whose contacts physically bounce when opened or closed. There are techniques to overcome this. Look at the Debounce example in the IDE.