Help with GP2Y0A710K0F IR sensor reading and conversion code

Soooo I am on the same boat as earlier people. I have this IR sensor I am trying to hookup to an Arduino One currently, but will eventually be on the adafruit Pro trinket. I am using the USB for power and have tried this code both in 5v and 3.3v and am having issues. I currently have it printing the voltage output because I was noticing the inconsistencies. Also for the power function, that was pretty much trial and error until I got a number that fit for the distance I was at.

2 questions based on the 5v setup

  1. The sensor is giving inconsistent numbers when doing various lengths. Like one time i measure 100 cm, it will give me about 520. If it go to a different length then come back, or reupload, then next time it will be 490 or such. Is there a connection fault or is it the usb issue?

  2. Am I even close on the conversion formulas used? I looked at different examples through the previous posts and years and found this one to, I think, supposedly be the most accurate at the end result, but it currently isn't working for me.

Any help is greatly appreciated, or if you have the code, even more so!!! :wink:

If you also have a better suggestion about how to do it and can give me some examples, that would be helpful too

#define sensorPin 0
#define VOLTS_PER_UNIT    .00488F        // (.0049 for 10 bit A-D)  :1/v *225@5 -.887  ,  148.5@3.3: -.391087
float volts;
float inches;
float proxSens = 0;
float cm;

void setup() {
 
Serial.begin(9600); 
   pinMode(sensorPin, INPUT);

}

void loop() {
 proxSens = analogRead(sensorPin);
 volts = (float)proxSens * VOLTS_PER_UNIT; // ("proxSens" is from analog read)
 cm = 225 * pow(volts,-.887);     // same in cm

 Serial.println(proxSens);
 //Serial.print(cm);
 Serial.print(' ');

 delay(200);

}

First help us! Link to data sheet for the sensor? What are you really using the IR sensor for? Schematic of your project showing power supply and all connections?

Paul

Here is the datasheet.

I am using my project for distance measurement. I am going to put the sensor at the end of a rod and use if for a reference measuring from the middle of the object, then display on an LED board. Right now just trying to get all the readings and formulas worked out.

Also like i said, currently running of the USB power, though didn't have it connected in the picture.

ir sensor datasheet.pdf (411 KB)

Now that we have the data sheet on the device you are using, I can make more sense of your original post.

Does you program code use the minimum and maximum values for each possible distance, or are you just trying to use a single value?

Paul

Currently, it just grabs any value you gets. I do have another sketch that grabs the average of 5 reads, then displays that, but that runs into the same problem as I wan't to get the readings with 2mv or less if possible, right now they are varying 10+ it seems.

Here is that code:

#define VOLTS_PER_UNIT    .00488F

const int irSense = A0;          // Connect sensor to analog pin A0
float distance = 0;
float volts = 0;
float cm = 0;
float inch = 0;

void setup() {
  Serial.begin(9600);            // Use Serial Monitor window
}

void loop() {
  Serial.println(irRead(), DEC); // Call irRead function to read sensor
                                 // Print value in Serial Monitor
  delay(250);                    // Wait another 1/4 second for the next read
                                 // (Note: Because of delays built into the
                                 //   irRead function the display of values will
                                 //   be slower than in the SharpGP2Y0A21_Simple
                                 //   sketch
}

// Take multiple readings, and average them out to reduce false readings
int irRead() {
  float averaging = 0;             //  Holds value to average readings

  // Get a sampling of 5 readings from sensor
  for (int i=0; i<5; i++) {
    distance = analogRead(irSense);
    volts = distance * VOLTS_PER_UNIT;
    cm = 225 * pow(volts,-.887);
    averaging = averaging + cm;
    delay(50);      // Wait 35 ms between each read
                    // According to datasheet time between each read
                    //  is -38ms +/- 10ms. Waiting 50 ms assures each
                    //  read is from a different sample
  }
 // distance = averaging / 5;      // Average out readings
  return(distance);              // Return value
}

Again, I believe the power function value is really what is holding this back, but I don't know how to calculate it correctly. If there is an easier way, I would be willing to try that. Thanks for the help

Also, a side note:

The final build will be using a high end 9.4 volt rechargeable battery as the power source, but it will be on a condensed board in size, not the uno.

Did you calibrate the device using the paper and averaging specified in the data sheet. If so, are you using that value to build a table of distances? The range of min-max seems to be greater than you are looking for.

Paul

I tried using the white piece of paper starting at 3 feet 4 inches, but didnt get very far. I increased 3 inches each set of reads, was in the 500s then dropped to the low 400s. Went back to the beginning, fell to the 300s.

I am pretty much goal and erroring. I don't know what formulas to use or how to use them. Trying to put it together from other posts, but not working, obviously....

The picture of your setup is little help. Draw a real schematic. The picture looks like you are powering the sensor from the Arduino. The max current for the sensor is 50 ma. Look up how much current the Arduino can supply. Change the sensor supply to a separate supply, but grounds all connected.

Paul

Ok I redid the setup per your suggestion. Everything directly connects, no breadboard.

Lets follow your schematic. You are powering the sensor with a battery rated at 9.4 volts. the sensor data sheet give an operating voltage of -0.3 to + 7 volts. Do you see a problem lurking in your design?

Paul

Well I haven't powered it yet on this setup, as I was using arduino setup before, that was constrained to a max of 5 volts.

So in this case since it give a recommended voltage between 4.5 and 5.5 volts, I would want to drop it 4.5 volts to put at 4.9 volts. Since its max supply currently is 50 mA:

R = 4.5/.05 = 90 ohm

Then based on the voltage needs of the resistor

V = (.05^2) *90 = .225

So I would need a 1/4 watt, 90 ohm resistor on the ground connector at the switch connection to the sensor correct? Would I need exactly that one or can I get a "higher rated" one? If so, how much higher?

Edit: I got that 50 mA from the Average supply current. I saw later in the:

"Please use power supply which can output 350mA or more to operate this product properly since this product requires about 330mA as the sensing peak current to LED."

I also just found that if that is the case, my 9.4 volt battery won't do it as it is 230mA. I am going to use my 7.4 800mAh Lipo battery instead in the same setup.

So in that case you would do:

2.5/.35 = 7.14

(.35^2)* 7.14 = .87465

correct? Which one would I use to find the resistor I need, the .05 or .35?

Zminator15:
Well I haven't powered it yet on this setup, as I was using arduino setup before, that was constrained to a max of 5 volts.

So in this case since it give a recommended voltage between 4.5 and 5.5 volts, I would want to drop it 4.5 volts to put at 4.9 volts. Since its max supply currently is 50 mA:

R = 4.5/.05 = 90 ohm

Then based on the voltage needs of the resistor

V = (.05^2) *90 = .225

So I would need a 1/4 watt, 90 ohm resistor on the ground connector at the switch connection to the sensor correct? Would I need exactly that one or can I get a "higher rated" one? If so, how much higher?

Edit: I got that 50 mA from the Average supply current. I saw later in the:

"Please use power supply which can output 350mA or more to operate this product properly since this product requires about 330mA as the sensing peak current to LED."

I also just found that if that is the case, my 9.4 volt battery won't do it as it is 230mA. I am going to use my 7.4 800mAh Lipo battery instead in the same setup.

So in that case you would do:

2.5/.35 = 7.14

(.35^2)* 7.14 = .87465

correct? Which one would I use to find the resistor I need, the .05 or .35?

I would recommend 3 size "D" cells in series for 4.5 volts. The max current is only a short time for the pulse operation of the LED.

Paul

Really? 3 huge d batteries vs one small lipo?

And if you must know, fine. This is to act as a "rangefinder" on the top of my mandalorian helmet arm that will have the electronics and power housed inside my helmet, for costuming purposes. I would like it to be more than just show and actually read correctly, or close to it, when it is on.

Also, when it will be on, it will be constantly reading and outputting, the way I plan on having it, so wouldn't it need that 330+ mA all the time?

Are you saying in this situation you wouldn't use resistors?

If I am going to use them, which I am still planning on it, will any of the calculation above work?

Assuming the power get taken care of, what is the next part you see wrong/needs to be changed in the code?

In other words, would any battery setup that will get me in that voltage and amperage range work?

Then from there, what are my next steps? Try to calibrate?

Zminator15:
In other words, would any battery setup that will get me in that voltage and amperage range work?

Then from there, what are my next steps? Try to calibrate?

Yes. I have never used your device, not any similar.

The calibration should be by using the white paper at distance steps for the range you want. Make a list/table of distances and readings. Repeat several times to determine the variations you will encounter in real use. Are the variations reasonable and similar for each calibration run? If not, you need to find out why and correct the problem. could be temperature, dust in the air, etc.

Once the variations are determined and fixed, then you can use the best table to see if you can figure out a formula to compute those values. If not, then you will need to set up two tables in your program. One for voltage value and the other for matching distance. Look up in the tables to find your distance.

Paul

Hello friends,

After many time of using this arduino community I decided to give some back :).

SO with IR sensor GP2Y0A710K0F which measuring distance between 1m to 5.5m there two problems. First, the values very unstable, because max voltage from sensor is 2.5v, when you measuring 100cm distance. For that, I strongly recommend to use ADS1115 or something similar.

The other problem, if I good understand datasheet, the sensor measuring not linear. That's mean from 1m to 2m distance the voltage difference is 0.7V. But from 2m to 5.5m the voltage difference is 1.55V, which means from 2m to 3m voltage difference is 0.44V.

So, first you must split calculation by checking values if you measuring range from 1m to 2m or from 2m to 5.5m. it's simply because 2m will get 1.8 volts. IF (sensorValue > 368) { distance = 457 - sensorValue *100cm/143bit;}
457 is calculated value.

IF (sensorValue < 368) { distance = 607 - sensorValue * 350cm/317bit;}
607 is also calculated value because you know that 0,25volts which mean's 5.5meter is about 51. So 51 * 350 / 317 will give about 57. 550 + 57 = 607. And that's it.

I am using that method and have very stable and accurate distance measuring system.

I will give code:

Sorry, some words in lithuanian and some lines for debugging and also I am using ADS1115 and measuring values changes only in some millimeters.

#include <Wire.h>
#include <Adafruit_ADS1015.h>
float tikslusAtstumas = 0.0;
boolean index = true;
Adafruit_ADS1115 ads(0x48);

void setup() {

Serial.begin(9600);
ads.begin();
}

void loop() {
int16_t adc0; // we read from the ADC, we have a sixteen bit integer as a result

adc0 = ads.readADC_SingleEnded(0);

if (adc0 > 9599)
{
float AB = 100/3733.0;
tikslusAtstumas = 457-adc0AB;
index = true;
}
else {
float AC = 350/8267.0;
tikslusAtstumas = 607-adc0
AC;
index = false;
}
// read the input on analog pin 0:
float sensorValue = analogRead(A0);
float skai = (450 / 511.0);
float skai2 = sensorValue * skai;
float atstumas = 550 - skai2;
// print out the value you read:
//Serial.println(sensorValue);
Serial.print(atstumas);
Serial.print(" ");
Serial.println(tikslusAtstumas);
//Serial.println(index);
delay(10); // delay in between reads for stability
}