Go Down

Topic: Sharp IR Sensor, bad code? *fixed* (Read 3 times) previous topic - next topic

Triple_Dude

Mar 28, 2009, 11:21 am Last Edit: Mar 29, 2009, 08:53 am by Triple_Dude Reason: 1
Hello all, before I paste my code, I'd just like to explain a little bit about the problem:
I'm using a Sharp GP2Y0A21YK IR Proximity sensor, and it doesn't not seem to be responding properly. By that, I mean it constantly outputs around "40" (give or take about 8) out of a maximum possible of 1024 from the analog input readings (as in, the value does not change when I move the IR sensor closer or farther away from objects). I have no idea what is going on, but I will paste my code to see if there's any errors I'm making (The code is a mash up between one found on the Playground, and another I scoured through the net)

Code: [Select]

//define pins. I used pins 4 and 5
#define irLedPin 4          // IR Led on this pin
#define irSensorPin 1       // IR sensor on this pin

int avgFactor = 10;
int irRead(int readPin, int triggerPin); //function prototype

void setup()
{
 //pinMode(irSensorPin, INPUT);
 pinMode(irLedPin, OUTPUT);
 pinMode(13,OUTPUT);
 Serial.begin(9600);
 // prints title with ending line break
 Serial.println("Program Starting");
 // wait for the long string to be sent
 delay(100);
}

void loop()
{  
 Serial.println(read_gp2d12_range(irSensorPin)); //display the results
 //Serial.print(analogRead(5));
 delay(200); //wait for the string to be sent
}

/*
read_gp2d12_range
Function that reads a value from GP2D12 infrared distance sensor and returns a value in centimeters.

This sensor should be used with a refresh rate of 36ms or greater.

Javier Valencia 2008

float read_gp2d12_range(byte pin)

It can return -1 if something gone wrong.

*/

float read_gp2d12_range(byte pin) {
 int i;
 int distRead = 0;
 int runningTotal = 0;
 int distAvg = 0;
 for (i=0; i < avgFactor; i++)
 {
   distRead = analogRead(pin);
   runningTotal += distRead;
   delay(1);
 }
 distAvg = (runningTotal / avgFactor);
 return distAvg;
}


Thanks in advance for any tips/help/advice provided :P.

etracer

The problem is most likey how you have the sensor wired up, but there are a few problems in your code as well.

Have you simply tested the sensor on it's own? All you need is to power the sensor with 5V and check the output pin voltage with a multi-meter. Moving something in the sensors filed of view should produce a related voltage change. Note that according to the datasheet, the voltage range over about 40cm is very small and may show much change. The 10bit precision on the ADC input will likely make detection beyond this range unreliable (there's simply not enough precision).

From a code perspective:

You have a prototype for irRead() which is not defined.

You're setting the irLedPin (digital pin 4) to an output but never using it. Perhaps you're intending to use this digital pin to power the sensor? If that's how it's wired then the problem is that you never set the pin high and your sensor is not getting power. Note that the sensor indicates a typical current consumption of 30ma with a max of 40ma.  40ma is the limit for digital outputs from an Arduino so you'd be pushing it pretty close. For testing I'd power the sensor directly from the 5V supply instead of the digital pin.

In your read_gp2d12_range() function you seem to be reading the analog output faster than the device can sample. You only have a 1ms delay in your averaging loop. According to the datasheet the device takes 38.3ms (+- 9.6ms) per reading. With only a 1ms delay in your average loop, you're not giving the sensor enough time to acquire samples. Thus you're getting the same (single) sample for all 10 of your reads.

Lastly, there's no real reason to have the result of your read_gp2d12_range() function be a float. Your samples from the analogRead have integer precision and any fractional readings are lost. Since you're averaging them over time to minimize the effects of sensor noise,  you're fooling yourself if you think fractional values are meaningful. You're not getting float values anyway because your intermediate result variable distAvg is declared as an int.

While there are problems with the code, with the possible exception of the lack of the digitalWrite(irLedPin,HIGH) I don't see anything that will make it not work. Fixing the problems will make it work better.


Triple_Dude

Thanks so much for pointing out the "HIGH" issue... I can't believe I missed that.

Regarding the current, the sensor itself is rated to use a maximum of 40ma, so I believe 1 digital pin should be sufficient. If it isn't, I will try it with the 5v out pin :).

Okay, I just tried it out with your suggestions, and the sensor seems to work now! Many thanks!

halley

It's nice you flagged your thread as answered, but don't erase a useful title!  Lots of people find threads with web searches, and if your title mentions the problem and the word "solved," then they'll definitely check into the solution you discuss.  A week from now, though, and nobody will know why there's a thread that seemingly started out solved.

Triple_Dude

#4
Mar 29, 2009, 08:52 am Last Edit: Mar 29, 2009, 08:54 am by Triple_Dude Reason: 1
Hmm, you're right, it's a shame that I can't fit my original title and the flag "*fixed*".

EDIT: Okay, I had to modify the title a little bit while still keeping the original meaning for the most part in order to fit "*fixed*".

Pauly

I am now working on the same issue.
Can you post your final code?


Md Nurul Hassan

Hello, I am Nurul . I need GP2Y0A21YK ir module ... I live in india... Kindly inform me where i can get this???....

Go Up