SHARP GP2Y0A02YK0F IR Proximity Sensor Question

I am using three sharp ir sensors to control three stepper motors harvested from a robotic arm. My code is a modified version of the MotorKnob code from the Arduino Stepper Library. The problem is the analog sensors produce a signal that has a small but constant variation in voltage. The variation causes the motors to constantly rotate back and forth even when nothing is interacting with the sensor. The stepper motors will control an interactive sculpture and it would be best if this variation of signal could be reduced or eliminated. Is there anything I can do on the software or hardware side to reduced this variation? It would be best for my very small grad student budget if I could solve this through software, but I'm open to hardware suggestions as well. I am fairly new to Arduino (project #2) but excited to be here. Thanks in advance for your advice. :slight_smile:

The code I started with is here: http://arduino.cc/en/Tutorial/MotorKnob

Picture of my rig under construction: Photobucket | Make your memories fun!

My modified version looks like:

/*
 * MotorKnobMultipleSteppers
 *
 * A stepper motor follows the turns of a potentiometer
 * (or other sensor) on analog input 0, 1, and 2.
 *
 * Origional code this was modified from can be found at 
   http://www.arduino.cc/en/Reference/Stepper
 * This example code is in the public domain.
 */

include <Stepper.h>

// change this to the number of steps on your motor
define STEPS 100

// create an instance of the stepper class, specifying
// the number of steps of the motor and the pins it's
// attached to
Stepper stepper1(STEPS, 1, 3, 2, 4 );
Stepper stepper2(STEPS, 5, 7, 6, 8 );
Stepper stepper3(STEPS, 9, 11, 13, 12 );

// the previous reading from the analog input
int previous = 0;

void setup()
{
  // set the speed of the motor to "X" RPMs
  stepper1.setSpeed(120);
  stepper2.setSpeed(120);
  stepper3.setSpeed(120);
  
}

void loop()
{
  // get the sensor value
  int val = analogRead(0);

  // move a number of steps equal to the change in the
  // sensor reading
  stepper1.step(val*25 - previous*25);
  stepper2.step(val*25 - previous*25);
  stepper3.step(val*25 - previous*25);

  // remember the previous value of the sensor
  previous = val;
}

Please modify your post, select the code and press the # button to get code tags, looks better.

That said, you can do multiplpe samples or use a running average

// multisample version
// as the sensor is not very steady in its reading 
// doing 32 samples smooths the reading.
unsigned int rawAvg()
{
  unsigned long raw = 0;
  for (byte i=0; i<32; i++) 
  {
    raw += analogRead(A0);
    //delay(1);
  }
  return raw/32;
}

// running average version
// use of 1024 == 10 bit shift 
//    + configurable ~1/1000
//    + no floats
unsigned int rawRA()
{
  static unsigned long value = 0;
  unsigned int a = 950;
  value = (a * value + (1024-a) * analogRead(A0)) /1024;
  return (unsigned int) value;
}

I think im gonna risk sounding really foolish but i cannot figure out how to take your code and insert it into my existing code properly.

I think im gonna risk sounding really foolish but i cannot figure out how to take your code and insert it into my existing code properly.

The one who asks a question is a fool for a moment, the one who don't asks a question is a fool forever :wink: Chinese proverb, Lao Tse?

Thry this ( not tested)

/*
 * MotorKnobMultipleSteppers
 *
 * A stepper motor follows the turns of a potentiometer
 * (or other sensor) on analog input 0, 1, and 2.
 *
 * Origional code this was modified from can be found at 
   http://www.arduino.cc/en/Reference/Stepper
 * This example code is in the public domain.
 */

include <Stepper.h>

// change this to the number of steps on your motor
define STEPS 100

// create an instance of the stepper class, specifying
// the number of steps of the motor and the pins it's
// attached to
Stepper stepper1(STEPS, 1, 3, 2, 4 );
Stepper stepper2(STEPS, 5, 7, 6, 8 );
Stepper stepper3(STEPS, 9, 11, 13, 12 );

// the previous reading from the analog input
int previous = 0;

void setup()
{
  // set the speed of the motor to "X" RPMs
  stepper1.setSpeed(120);
  stepper2.setSpeed(120);
  stepper3.setSpeed(120);
  
}

void loop()
{
  // get the sensor value
  int val = rawAvg(0);

  // move a number of steps equal to the change in the
  // sensor reading
  stepper1.step(val*25 - previous*25);
  stepper2.step(val*25 - previous*25);
  stepper3.step(val*25 - previous*25);

  // remember the previous value of the sensor
  previous = val;
}

// multisample version
// as the sensor is not very steady in its reading 
// doing 32 samples smooths the reading.
unsigned int rawAvg(int pin)
{
  unsigned long raw = 0;
  for (byte i=0; i<32; i++) 
  {
    raw += analogRead(pin);
    //delay(1);
  }
  return raw/32;
}

// running average version
// use of 1024 == 10 bit shift 
//    + configurable ~1/1000
//    + no floats
unsigned int rawRA(int pin)
{
  static unsigned long value = 0;
  unsigned int a = 950;
  value = (a * value + (1024-a) * analogRead(pin)) /1024;
  return (unsigned int) value;
}

robtillaart:
The one who asks a question is a fool for a moment, the one who don't asks a question is a fool forever :wink: Chinese proverb, Lao Tse?

Very wise words.. that worked like a charm by the way. I just wanted to give a sincere thanks. You have been a huge help. Hopefully I can pass on the favor in time. I do have some more questions but I'm going to move this project post over to the programing topic. I think any other questions I have would suit it best.

If you think you might be willing to let me pick your brain any more feel free to take a look.

http://arduino.cc/forum/index.php/topic,70772.new.html#new

Thanks again

Note that instead of

** int val = rawAvg(0);**

you could use the running averige function

** int val = rawRA(0);**

Try and note the differences in behaviour, especially when tweaking the parameter a e.g. 0, 100, 300, 500,700, 1024

unsigned int a = 950;