Sharp IR sensor inaccurate readings

I have obtained a new sharp IR sensor to measure from range 10 to 80 cm for my project,
upon connected the sensor as designated in the datasheet and used various codes to measure distances ,
I can tell from the readings has a maximum for 30 cm but not 80 cm as declared in the data sheet, as after 30 cm it gives no more than 30 CM.
here is an example of the used code


  #define ir A5 

void setup() {
  Serial.begin(9600);

}
void loop() {
  float  val = analogRead(ir)*0.0048828125;
  int distanceX = 29.988*pow(val,-1.173);
  //Serial.println(val);
  Serial.println(distanceX);
  delay(1000);

}

and here are example of the readings at different distances above 30 CM

25
26
12
25
27
27
24
29
27
27
25
27
28
26
26
27
13
26
27
32
25
27
27
24
25
27
13
23
26
27
37
26
26
13
23
27
26
24
27
27
13
21
28
32
25
26
28
11
26
27
28
24
26
28
27
22
27
26
25
26
27
13
26
27
29
25
26
27
13
26
27
27
25
26
27

also I've used this library with
no apparent success

Please post a link to the sensor product page and state which Arduino you are using.

The maximum range depends on the reflectivity of the object, which should be a smooth flat surface. What are you using as a target?

Looking at the graph (below), taken from the GP2Y0A21YK0F data sheet (if that is what you have) , I would be very skeptical of the accuracy of a formula like that in your code.

the object is a flat white box, and I'm using Arduino nano , and this is the exact sensor I have.
if you have better formula or code you could post it here.

You could try the Pololu library.

However, in order to have accurate voltage readings, the ADC on the Classic Nano must be calibrated to the actual ADC reference voltage, which is usually Vcc and can be anywhere from 3.3V to over 5V. Which of the 6 or so "Arduino Nano" versions do you actually have?

This constant is almost certainly not correct:

  float  val = analogRead(ir)*0.0048828125;

The formula is same as used in library and seems giving the same result as in the GP2Y0A21YK table.
For every conversion try printing also the analogread result and the val ( and measuring with a multimeter you should se output dropping below 1V for distancies greater than 30cm )
Are you powering the sensor with a good 5V supply?

@davidefa
I'm using the 5volt supplies from the Arduino nano, and used the same connection as you can see here.
How to Use the Sharp IR Sensor (GP2Y0A41SK0F) - Arduino Tutorial : 5 Steps - Instructables

@jremington
I'm using Arduino Nano Classic with bootloader, So what is the correct formula?

Ok, but measure with a multimeter the voltage on the 5volt supplied by arduino.
I say that because if you power the arduino via usb the voltage on the 5V pin you have the usb voltage less a diode drop, and it should be in the 'range of 4.5V' if the usb voltage is 5V ( or even lower is your usb voltage is less than 5V ).
The minimum voltage for the sharp diode is 4.5V, so it could be you are actually powering it at a voltage below the minimum guaranteed functioning voltage
So a safer solution could be powering the arduino via Vin ( at least 7V, to take in account for the drop of the regulator ), and you should have a steady 5V to power the sensor.
Or even better using a separete 5V supply only for the sensor ( you need to connect both negatives/gnd together ).

1 Like

The correct constant is the one that makes the Arduino reading agree with the actual, measured voltage. See this tutorial: Gammon Forum : Electronics : Microprocessors : ADC conversion on the Arduino (analogRead)

@jremington
the tutorial is quite complicated for me , So is it possible to show me the correct constant?

@davidefa
Sure I'm using a usb to power the Nano , where it powers the sensor from the 5v pin on the Nano.
I've used a voltmeter to measure the difference between the 5v pin and the ground pin
and it gave me 4.36 volt below the required 4.5 volt .
So what are my options now knowing that the my aduino board have other soldered components ?

No. You need to measure the ADC reference voltage with a multimeter. For an Arduino with 10 bit precision (like the Uno), the correction is

(raw ADC reading)*(ADC reference voltage)/1024.

here are the measurements at 30 cm with the real reading from the Arduino analog read

280
20
294
11
290
19
319
20
302
20
278
19
329
20
295
11
285
20
317
16
293
11
289
19
317
20
291
18
264
19
319
21
288
18
325
20
289
17
28

and here are the measurements at 40 CM

335
15
333
16
344
10
333
16
363
16
334
17
482
16
348
11
335
15
339
16
337
15
509
16
343
10
332
16
353
17
334
16
361
16
332
17

and here are the measurements at 20 CM

473
18
470
18
473
18
297
19
327
18
319
19
315
17
301
19
321
17
302
17
300
18
299
19
489
19
323
18
318
11
325
19
300
18
476
18
323
11
298
19
304
17
299
18
343
19
317
20

here is the code

  #define ir A5 

void setup() {
  Serial.begin(9600);

}
void loop() {
  float  val = analogRead(ir)*0.0048828125;
  int distanceX = 29.988*pow(val,-1.173);
  Serial.println(analogRead(ir));
  Serial.println(distanceX);
  delay(1000);

}

here the code I used from the pololo library

#include <SharpDistSensor.h>

// Analog pin to which the sensor is connected
const byte sensorPin = A5;

// Window size of the median filter (odd number, 1 = no filtering)
const byte medianFilterWindowSize = 5;

// Create an object instance of the SharpDistSensor class
SharpDistSensor sensor(sensorPin, medianFilterWindowSize);

void setup() {
  Serial.begin(9600);

  // Set sensor model
  sensor.setModel(SharpDistSensor::GP2Y0A21F_5V_DS);
}

void loop() {
  // Get distance from sensor
  unsigned int distance = sensor.getDist();

  // Print distance to Serial
  Serial.println(distance);

  // Wait some time
  delay(1000);
}


and here are the results at 20 CM

178
173
173
178
173
173
173
173
173
160
173
173
180
176
180
180
182
176
172
172
179
172
179
179
181
181
181
180
182
180
180
180
181
175
175
175
175
174
174
170
170
174
177
181
181
180
177
175
175
175
143
143
140
140
143
164
172
181
181
181
181
178
173
173
173
175
175
175
175
175
179
179
179
175
182
175
175
175
181
170
171
171
171

which are completely faulty .

Looks like you have bad soldering/wiring (possible open analog input), or a bad sensor. You won't get anywhere with such large measurement variations. Post a close up, focused picture of your setup.

@jremington
I have made a new set of testing using the following code to print the analog readings from the sensors
here is the code


  #define ir A5 

void setup() {
  Serial.begin(9600);

}
void loop() {
  float  val = analogRead(ir)*0.0048828125;
  int distanceX = 29.988*pow(val,-1.173);
  Serial.println(analogRead(ir));
  //Serial.println(distanceX);
  delay(1000);

}

and here are the readings at about 70 cm

254
263
252
248
254
258
249
267
381
240
250
249
253
247
273
382
240
248
249
251
248
263
265
271
247
236
248
246
249
251
255
246
261
263
269
277
379
400
247
248
248
249
248
252
252
259
258
267
269
247
279
287
383
248
408
240
248
251
249
248
251
249
249
249
249
251
251
248
252
253
254
247
255
257
264
264
261
262
251
273
267
267
247
275
278
255
287
383
377
253
386
392
232
232
240
240
251
232
256
240
252
248
248
248
248
248
256
252
240
232
404
247
377
384
386
384
394
400
260
396
384
384
253
379
379
258
299
283
279
254
275
279
271
271
269
267
247
264
262
259
252
250
249
263
253
254
256
247
379

and here at 20 cm

335
338
333
379
334
351
341
353
379
332
334
337
343
353
369
320
332
338
338
340
333
363
477
324
333
330
335
333
348
347
353
359
367
477
333
324
334
337
334
334
340
336
336
342

and here are the photo of my setup


as you can see the IR sensor is a part of a project to measure weight and height and the wires from the sensors are connected to the the ground , 5volt , and A5 wires from The Nano Board .
as I Measured the voltage running the sensor from the Nano board seems to be less than the required 4.5 volt necessary to power the sensor .
I used a battery pack of 3 AAA batteries to supply more than 4.5 volt as you can see here.

and here

and here are the raw readings at 20 cm

376
429
217
0
88
0
0
0
0
92
0
24
380
582
381
530
894
960
970
996
943
672
877
557
685
389
318
310
0
103
0
0
0
41
116
145
105
56
85
301
188
783
937

as you can see when connecting the sensor to the battery pack resulted in completely faulty measurements
I also I found the in the documentation that a 10 micro farad capacitor is needed between the ground and the power source to stabilize the power supply to the sensor,
I found this one in the utility store nearby, is the the correct one and how to wire it

If the measures you posted was taken with the box in fixed position I'd say there is something 'unstable', wondering if these variations are in the sensor output or 'in the acquisition' ?
So using the multimeter do you have stable readings that correspond to the table below ( that should represent the device response )?
The battery pack you are using is good in the fact it is stable and has no 'switching noise' ( as could have a switching regulator ), but I'd try also with a proper 5V supply.
The capacitor you have is good ( till 250V, more than acceptable ; - ), connect between gnd/vcc of the sensor ( near the sensor ), it is polarized, so the 'white striped -' to gnd ( add also, if you have, a 100nF capacitor in parallel to the polarized one )

Volt Distance
2,6 10
2,1 12
1,85 14
1,65 15
1,5 18
1,39 20
1,15 25
0,98 30
0,85 35
0,75 40
0,67 45
0,61 50
0,59 55
0,55 60
0,5 65
0,48 70
0,45 75
0,42 80

Sounds like the battery pack is the problem. Electrically, they can be very noisy, and that is a problem for any sensor. I suggest to change to a stable, well regulated power source.

Breadboards are also unreliable.

Please post a close up, focused photo of the Arduino and the sensor wiring.

@drmina2023
I've used that sensor. It works very well with a regulated 5V supply. I soldered a small 10uF tantalum capacitor to the backside of the connector. Had no trouble getting the 10cm-80cm range but it MUST be linerized.
One thing not explained in the data sheet is that the output occurs in discrete voltage steps, it is not continuous. I have to look but it may have only been 256 steps

I used a large target when I linearized because since it's IR it's hard to know where it's pointing

@jim-p
So how to make the readings linear ?