all about electronic and microcontrollers

Monday, August 8, 2011

Distance Sensor Sharp 2YOA21 & LCD

The distance sensor produced by Sharp is a popular and relatively low cost solution for measuring distance. The sensor can be used also for measuring the rightness or color (in very limited extent) but in this article we will talk only about measuring distances.
In the current experiment we will use the 2YOA21 model and the characteristics of this sensor are:
  1. Minimum Measuring Distance = 10cm;
  2. Maximum Measuring Distance = 80cm;
  3. Infrared Proximity Sensor;
  4. Analog output inversely proportional to distance;
  5. Sensor is Ratiometric;
  6. Operating Supply Voltage = 4.5V to 5.5V;
  7. Average Supply Current – Typical = 30mA;
  8. Response Time = 38 ± 10ms.
Obviously there are several versions of sensors which are capable to measure distances shorter or longer, depending on needs.
Examples of sensors are:
  • Sharp Distance Sensor GP2D120 (4-30cm);
  • Sharp Distance Sensor GP2Y0A21 (10-80cm);
  • Sharp Distance Sensor GP2Y0A02 (20-150cm).
The data signal of sensor 2YOA21 are sent in analog way and the connection made with the microcontroller is very simple. The analog output varies from 3.1V at 10cm to 0.3V at 80cm.

Hardware setup:
In the current article I intend to display the measured distance, between sensor and some object, on the LCD with 2x16 characters.
Physical realization is carried out on the breadboard with 2420 dots.

Trough this video I would like to share the situation in real time.

Now, I will share a little bit of theory, theory needed to put things in motion.

Below I present the timing diagram for data signal transmitted on pin 1 of the sensor 2YOA21.

Timing diagram.

The following diagrams are very useful when we want to construct the formula for measuring distance.

The distance vs. output voltage.

Above we have the diagram that specify the relationship between the distance measured and the output voltage of 2YOA21 sensor.
The output voltage vs. inverse number of the distance.

Above we have the diagram that specify the relationship between the output voltage and the inverse number of distance sensor 2YOA21.

Pin description of 2YOA21 distance sensor.


Below we have the diagram block of 2YOA21 distance sensor.

Block diagram.

In the datasheet, the manufacturer recommend us how to align properly, the distance sensor by the measured surface.
Below I will present you trough two pictures how to do that.

Proper Alignment to Surface Being Measured

Proper Alignment to Moving Surfaces.

Before we put the toy in operation we must take into consideration the following tips:
  • Must be kept the sensor lens clean. The dust, water, oil, and other contaminants can deteriorate the characteristics of this device;
  • When using a protective cover over the emitter and detector, ensure the cover efficiently transmits light throughout the wavelength range of the LED (λ = 850 nm ± 70 nm). Both sides of the protective cover should be highly polished;
  • Objects in proximity to the sensor may cause reflections that can affect the operation of the sensor;
  • Sources of high ambient light (the sun or strong artificial light) may affect measurement. For best results, the application should be designed to prevent interference from direct sunlight or artificial light;
  • Using the sensor with a mirror can induce measurement errors. Often, changing the incident angle on the mirror can correct this problem;
  • The manufacturer recommends a 10 μF (or larger) bypass capacitor between VCC and GND near the sensor.
For more details, please study the Sharp 2Y0A21YK datasheet.

Circuit Diagram:
Difficulty level of the electronic scheme, is low. The microcontroller used is PIC16F876A because he posses the analog to digital converter, conversion required for the signal processing collected from our distance sensor.
S1 is the master reset button, R1 is the resistor of pull-up button.
Cristal quartz by 8 MHz, is used.
C3 and C4 are used for additional filtering of the sensor 2YOA21.
Trough J1 we ensure the connectivity with distance sensor.
ICSP connector is used to program the microcontroller.
Trough R2 we can adjust the contrast for LCD with 2x16 characters.
R3 adjusts the current through the LED LCD (light intensity of it).

The electronic schematic.

The electronic scheme is built in Eagle Cad, free version.

The program is written in mikroC Pro for PIC 2011 (version v4.60).
Until this moment, I found 3 ways to extract the formula that converts the sensor output voltage in the distance. I will show below:
  1. Based on "typical values" from Sharp, the formula to translate sensor value into distance (the formula is only valid for a sensor value between 80 to 500) is:
  2. Analyzing the diagrams below we can deduce:

    Calibration curves of 2YOA21 sensor.

    This equation was derived from the calibration curve:

    where “IR Value” is the digital output signal from the sensor.
    The curve was created by plotting output values of the IR sensor versus distances to a stationary, flat object.

    Here is the diagram of 2YOA21 sensor values at ranges between 0cm and 150cm:

    Sharp Sensor Data.

  3. And now I will present the formula used in the current article.
    As I said above, the analog voltage is the inverse of distance, so distance can be calculated as:

    then scaled to suit with the datasheet.
    We will load ADC value in 16 bit “math” variable and we will use in this way:

    for scaling, 6050 is a constant.
All three methods are tested by me, so you can have confidence in their accuracy. I chose the latter method because it seemed more interesting, nothing more.
For those who are extremely pretentious can develop a look-up table from data points supplied from the graph, but if you choose this route should be considered the RAM memory of microcontroller, must be big enough to host the entire data table.

Below is my software version:
'  Project name: Distance Sensor Sharp 2YOA21 & LCD Display
'  Description:
'          In this experiment we will try to display on LCD 2x16 character, 
'          distance helped by IR senzor "Sharp 2Y0A21YK" wich is able to give
'          distance betwen 10cm~80cm.
'  Written by:
'          Aureliu Raducu Macovei, 2011.
'  Test configuration:
'    MCU:                        PIC16F876A;
'    Test.Board:                 WB-106 Breadboard 2420 dots;
'    SW:                         MikroC PRO for PIC 2011 (version v4.60);
'  Configuration Word:
'    Oscillator:                 HS (8Mhz)on pins 9 and 10;
'    Watchdog Timer:             OFF;
'    Power up Timer:             OFF;
'    Browun Out Detect:          ON;
'    Low Voltage Program:        Disabled;
'    Data EE Read Protect:       OFF;
'    Flash Program Write:        Write Protection OFF;
'    Background Debug:           Disabled;
'    Code Protect:               OFF

// LCD module connections;
sbit LCD_RS at RB0_bit;
sbit LCD_EN at RB1_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;

sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
// End LCD module connections;

unsigned int cm,cm10;
unsigned int math;
char *text;
char *digit = "00";

void calc_distance(void)
 // from the datasheet the analog voltage is
 // the inverse of distance, so distance can be calculated
 // d = (1 / volts) then just scaled to suit the datasheet
 // load ADC value in 16bit math variable.
 math = ADC_Read(0);
 math = ADRESH;
 math = (math * 255);
 math += ADRESL;
 // now invert it; (1 / volts) use (6050 / volts) for scaling, 6050 is a constant;
 math = (6050 / math);
 if(math >= 2) math -= 2;   // fix linear error (-2)
 if(math < 10) math = 10;   // min limit at 10cm
 if(math > 80) math = 80;   // max limit at 80cm
 // convert from 0-99 to 2 decimal digits, 0-99cm
 while(math >= 10)
  math -= 10;
 cm = math;

void main(void)
 ADCON0 = 0X01;              // RA0 as Analog Input;
 ADCON1 = 0X0E;              // Reference VDD and VSS, with left justified;

 CMCON |=7;                  // Disable comparator;

 TRISA0_bit = 1;             // Make RA0 as input;
 PORTA = 0x00;               // Initial value of PORTA;

 LCD_Init();                 // Initialize the LCD;
 LCD_Cmd(_LCD_CURSOR_OFF);   // Cursor mode off;
 LCD_Cmd(_LCD_CLEAR);        // Clear the entire LCD;

 text = "Sharp 2Y0A21";
 text = "Distance:";
 text = "cm";

  calc_distance();            // Call the "calc_distance" function;

  digit[0] = cm10 + 48;       // tens digit;
  digit[1] = cm +48;          // unit digit;
  Lcd_Out(2,10,digit);        // display on LCD from column 2, from character 10;


  1. hye sir,
    can help to teach me how should i convert the code to HEX code...i try to copy paste the code microbasic but i found error..

    plz help sir

    this is my email

  2. Hi, my code is written in mikroc pro for pic, that's why, you can't compile this code with mikroBasic. I recommend you to use mikroc pro for pic compiler.

  3. it says "Undeclared identifier 'CMCON' in expression lcd.c" . can i comment this line?

  4. how did you calculate that constant, 6050? how should i proceed for the gp2d12 sensor?

  5. salut. vreau sa folosesc un gp2d12, ca am nevoie pt distante mai mici. cum calculez constanta aia? l-am modificat un pic pe asta, dar sub 6cm nu gasesc nicaieri functie de liniarizare. si nu prea am inteles cum ai ajuns la valoarea 6050 pt asta..
    multumesc anticipat

  6. Firstly, thank you.
    Secondly, about CMCON, at compile, you got error, maybe becouse you use a microcontroller who can not recognize this function "CMCON", try to make that line as comment to see what it's happening.

    Dear Trica, on the datasheet of the GP2Y0A21 is graph of relation between its output voltage and measured distance. This graph is not a linear one, however the graph of inverse values of output voltage and distance almost is, the constant was chosen by 6050 after successive calculations made ​​in spreadsheet programs, the output voltage is already converted to 10 bit +5Vcc values of analogue-digital converter with comparison voltage.

    After a short analysis on the datasheet of the GP2D12, I realize that this sensor can measure dinstante between 10cm respectively 80cm, obviously becomes unstable outside these parameters, correct me if I'm wrong.

    1. am gasit in mai multe locuri grafic pt gp2d12, in unele locuri minim 10cm in altele minim 4cm. eroarea la CMCON era pt ca folosesc un pic16f887, am rezolvat, am gasit comanda pentru dezactivare comparator. pana la urma ma descurc cu asta de 10 cm si pt distante mai mici. multumesc pt raspun si pt cod, mi-a fost de mare ajutor. bafta in continuare!

  7. thaaaaaaaaaaaaaaaaanks to you
    can you explane the code with tow Sharp 2Y0A21YK please

  8. thank you
    can you explane the code with tow Sharp 2Y0A21YK please
    using 2 (tow) ADC channels
    appreciate that for you

  9. It is very easy to implement what you propose , in the current tutorial I explained in detail, how to use a single distance sensor. Now I feel compelled, to let you try, on your own, to connect the second distance sensor. I think that will help you, to bring some improvements to the project and also learning something new about programming, don't you think?

    If you realy don't understand the code, please let me know, I will help you. I don't have so much spare time, but i will try.

  10. ducu thank you body it was really helpful and valuable.

    but i couldn't understand your answer about Sharp GP2D12 !

    can i use your code on Sharp GP2D12? because i don't have Sharp 2YOA21.

  11. Can you please explain this line math = (math * 255);

  12. Hello Semmoor Semmoor,
    Try the code with your Sharp GP2D12 and tell me how it works.
    math = (math * 255); ----The initial value is calculated trough a lenght of 8 bits, and the current line makes another lenght of 8 bits, making the "math" value on a 16-bit legth.

  13. Dear sir

    How can i replace Sharp 2YOA21 by IR sensor and infrared receiver for measure fuel tank level


  14. Hi Brahim Hassen,
    question is a bit ambiguous, what type of sensor you mean?, wouldn't be easier to use optocouples? It must be seen what type of information give the infrared receiver.
    Can be done everything you need, but firstly you have to determine the desired parameters.

  15. HI ducu
    I would just like to say "THANK YOU" for a VERY quick response
    I want to use the circuit for measuring the level of fuel oil in the tank (Length =4m)


  16. Hi ducu, sorry i was really busy i couldn't answer, i did try the Sharp GP2D12, and it worked exactly like Sharp 2YOA21. Thanks i'm waiting for your great lessons.

  17. how about ultrasonic distance sensor i think it's more precise , i wish if there's a tutorial about that

  18. HELLOW i have a question i don't undersatand the code !pleas help me becaouse i need it ,

  19. Thank you for sharing this information.I am very interested in low cost laser distance sensor:)

  20. Can i use this code on PIC 16F877A?

  21. With a little adjustments, you can.

  22. Ducu, I try to use this code on pic16f877a. The output become messy. I mean the output of the character on the LCD display doesn't show the accurate/correct character as similar to what your LCD shown. May I know what I have to adjust?

  23. hello can i use this code on a pic18f1320, i had a gp2y0a02yk thanks

    1. Hello Sooso,
      After a quick search on its datasheet, this microcontroller is suitable for your needs.

  24. Thank for the code but i think the LCD module connection are incorrect somwhere some how because on the code it is written like sbit LCD_RS at RB0_bit
    but on your schematic pin LCD_RS is at RB4 and RB0 is connected to DB4
    looking forward to your reply Ciao

    1. Bravo you are very attentive to details.
      I will fix the error.

  25. How can i program the sensor in C to interface it with PIC 16F877 and display the distance on the LCD? maximum distance i want to reach is 150cm.

  26. hi bro...can u explain me why we use this formule code?
    math = ADRESH;
    math = (math * 255);
    math += ADRESL;
    i have easypic with mic pic18f45k22
    what meaning by this?

    math = ADRESH;
    math = (math * 255);
    math += ADRESL;
    thnx :)

  27. hi bro...can u explain me why we use this formule code?
    math = ADRESH;
    math = (math * 255);
    math += ADRESL;
    i have easypic with mic pic18f45k22
    what meaning by this?

    math = ADRESH;
    math = (math * 255);
    math += ADRESL;
    thnx :)

  28. Thank you again for all the knowledge you distribute,Good post. I was very interested in the article, it's quite inspiring I should admit. I like visiting you site since I always come across interesting articles like this one.Great Job, I greatly appreciate that.Do Keep sharing! Regards, entfernung


If you do not understand something, or if you make some aplication helped by this blog, let me know.