HOME - - - - - - - - Table of contents, my Arduino "How To" articles
Other material for programmers Delicious Bookmark this on Delicious   Recommend to StumbleUpon

Reading analog values with an Arduino

An example using an ultrasonic distance sensor

This page describes using an Arduino to interface with the analog output from a reasonably inexpensive sonar rangefinder. The range finder has a splendid array of features; we only scratch the surface here.

The sensor in question is a MaxBotic LV-MaxSonar EZ20. I bought mine in February 2008 from www.pololu.com for $26 plus a reasonable p&p charge.

First I will show you a really, really basic Arduino program to access the sensor. Then I will expand upon that. There are things in this which may be of interest to you even if you don't have the sensor I am writing about... anything that returns an analog voltage from 0 to 5v (or less) can use the programs.


Initially, all we need is an Arduino and the ultrasonic distance sensor, aka "EZ0". The EZ0 has numerous pads, but we only need to connect wires from the "GND", "5v" and "AN" pads. (They are labeled in the copper traces, if you look closely at the underside of the module.) The maximum likely current demand of the EZ0 is 3mA, so it can be powered from the Arduino. The AN line goes to the analog input of your choice. I'm using AN0, but you only need to change one line at the head of the program to "re-write" it to expect the sensor on a different channel.

Most of what you need to know is explained in the sourcecode that follows. You can skip directly to that, if you wish.

As with all Arduino programs, there are two main functions, "setup" and "loop".

Just before "setup" in the sourcecode, you will see two #defines. These tell the compiler....

I chose "an0" as a way to refer to the first (and in this case only) analog input pin. LEDpin is my reference for the pin on which I have an LED which I will want to turn on and off. Not only are these human-friendly (well, at least geek-friendly) terms for things easier to deal with than "0" and "13", but if someone else is using the program, and for some reason, say, wants to connect the LED to pin 12, then they only need to change the....

#define LEDpin 13

.... line (to #define LEDpin 12), and instantly, all through the program, anywhere that a reference was made to the pin the LED was attached to occurs, that reference has been "revised" to accommodate the programmer's wish to move the LED to pin 12.

Most of the examples I've seen for Arduino code would put the zero and the 13 into variables. This "works", but is less elegant.

Also before the declaration of "setup", I've declared a variable "iAnVal".

Nothing in the declaration of "setup" is essential to the core function of this program, which is to read an analog value, from, as it happens, the MaxBotic ultrasonic range finding unit. However, if the program is to be useful, and if we are to retain our sanity, it needs to tell us what we've read, and it needs to help us see what's happening, 'cause few programs do exactly what they "should" until a few passes through the "write/ test/ edit/ re-write, re-test" cycle. Sigh. So, in "setup", we prepare the system to send "things" out via the built-in serial interface. (That's the Serial.begin line) And we prepare the pin defined by LEDpin to be used for output.

Do take a moment to read the two comments under "N.B." in the sourcecode, in the "setup" declaration.

Once the Arduino is programmed, and told to begin executing that program, first, always, it does whatever is in the "setup" function, which we just discussed. It then goes on to do what's in the "loop" function. In this case, that consists of....

The first pause is there for two reasons. 1) There is no point in reading the analog value as often as the Arduino could. 2) Without this pause, the LED would not be off for a perceptible period of time. The second pass over this pause occurs shortly after the LED is turned off on the first pass through the loop.

"Tell the user what the reading was". In this simple version of the "read sensor" program, the user can't see what the sensor is reporting unless the Arduino is attached to a larger computer, or another output device has been provided. Don't worry.... the next version of the program (farther down the page, after the one below) will "work" without either.

The standard Arduino development environment "talks to" the Arduino over a serial link. That link is usually provided via a USB interface, but the Arduino, and to some extent the big PC driving it, "think" they're "talking" via a serial link. That link is used, for instance, for sending the program to the Arduino.

But! The link can be used for other things. The program below sends back ("up") the serial link the value read from the analog sensor. The "Serial.println(iAnVal)" statement is the one that causes this. The "trick" is knowing how to see (in the usual, human, sense, the information that the Arduino has sent to the big PC. Here's how...

When the Arduino Development Environment program is running in the big computer, it shows as a window with a menu across the top consisting of "File.. Edit.. Sketch.. (etc)". Below that is a row of icons... a triangle to verify the code, a square to stop it, etc. At the right hand end of that line of icons is a rectangle with a little circle above it. Hover your mouse pointer over it, and you will see "Serial Monitor".

After you have written your program and saved it, and "upload to I/O board"ed it, and seen the "Binary sketch size..." message in the panel at the bottom of the Arduino Development Environment program's window, click on the Serial Monitor icon. Once the Arduino has finished the "setup" function (it was taking a while in a Boarduino I was using... not sure why...), then you will see numbers appearing where you once had the "Binary sketch size..." message. These numbers are the readings the Arduino is making of the analog input. They come from the Serial.println line. Put something in front of the ultrasonic ranger, and the numbers will change.

Pretty cool! Here's the simple program that does what I've described. After you've got that into an Arduino and working, come back and look at the material after this, the first program.

/*MaxBotix1simple
ver 29 Mar 08

A demonstration of using an analog sensor with an Arduino.
While general points arise, the example shows an ultrasonic
rangefinder, MaxBotix LV-MaxSonar EZ0, in action.

This program is explained in the "How To" at....

http://sheepdogguides.com/arduino/aht1a.htm
================*/


/*First: Create a human-friendly name for the pin on which you have the sensor.
 Change just the following line if you want to connect your sensor on a
 different analog input.*/
#define anIn 0 //(no ; here... never is on a "#define" line.)

#define LEDpin 13 /*(no ; here) Not "needed"... but helpful if you have
   an LED and resistor on pin 13. It will be made to "wink" so that you
   can see that your the program IS executing the "loop" function.*/

int iAnVal;  /* declare a variable to store the value coming from the sensor
      It has not been given an initial value as an assignment is made to the
      variable before any attempt to read from it.*/

void setup() {
/*The two lines here are not "needed" to read the sensor, but they
  support things which can help you see what is going on as you debug
  your program*/
Serial.begin(9600);//See note at the Serial.write line.
pinMode(LEDpin, OUTPUT);  // prepare the pin "LEDpin" for output

/*========================================
N.B.:

1) The sensor does some things at each power cycle. For the rest of
the time after coming to life, until the next cycle, it will work best if
there is only air for at least 14 inches in front of it during the second
or two as power is applied.

2) For some reason I haven't tracked down... maybe it has always done it?...
but my Arduino is, when I run this program, taking about 8 seconds (from the
time I get the message "Binary sketch size....") to start executing the "loop"
function. This isn't enough time to be a problem, but you need to know that
the pause is happening before you worry that the program isn't running. The
"wink" of the LED tells you when "loop" has started running.
=========================================*/

} //end of setup

void loop() {
iAnVal = analogRead(anIn);   // read a value from the sensor

delay(150);     /* Stop the program for a moment. Partly to
   make the "wink" work, but also as there is no reason to
   read the sensor as frequently as the Arduino could read it.*/

Serial.println(iAnVal);
/*You do not need anything "extra" beyond the normal Arduino
  Development Tool (my name for the most basic, can't live
  without it, arduino.exe that you must already have to see
  things that have been sent to the serial port by using
  Serial.println

  In the icons under the menu (menu: "File.. Edit.. Sketch....),
  at the right hand end, is one that is identified "Serial Monitor"
  if you hover your mouse pointer over it. Click on this after
  starting the upload of the program to your Arduino, and things
  that are sent with Serial.println will appear in the panel at
  the bottom of the Arduino Development Tool window.

  For Serial.println to work, you should do a Serial.begin during
  the "setup" function.

 ------------------------------------------*/

/*The three following aren't "needed"... they wink the LED so that you
can see that the "loop" function is executing.*/
digitalWrite(LEDpin,HIGH);
delay(150);
digitalWrite(LEDpin,LOW);

}

So. That's the simple program. It reads the sensor, and sends the value read to the serial stream, which you can read while the Arduino is attached to your PC, as explained above, and in the comments within the program.

Now for and enhanced version of the program. It is very similar, but, once you add four LEDs to the circuit, the program gives the result from the sensor on a crude 5 value bar graph. (No LED on, 1 on, 2 on, etc.)

The LEDs and their resistors go on pins 9,10,11, and 12, unless you want to change the #defines at the top of the program. Each LED goes from its pin, to its resistor, and that goes to ground. (The "zero volts" connection, or "rail".) Resistor size? Depends a little on the LED, but about 300-800 ohms will probably be okay.

You can jump ahead and read through the code if you wish,

All that's been added to the program bits and pieces setting up the pins for the LEDs as outputs, and defining some constants which will determine when the LEDs turn on. The latter are "Thresh0", "Thresh1", etc. "Thresh" as in "threshold".

Once these things were taken care of, I only had to add the four lines to loop which look like....

if (iAnVal<Thresh0)
         {digitalWrite(LEDan0,HIGH);}
        else {digitalWrite(LEDan0,LOW);};

That says: "If the analog value read from the sensor a moment ago is less than the number in "Thresh0", then turn the first LED on, and if it isn't turn the LED off. Pretty simple, really, apart from getting all the semi-colons exactly right!

And now you know about all of the new stuff in the extended version of the first program. Load it to your Arduino, and watch the LED bar graph grow and shrink as you move your hand close to and away from the sensor. Beware: The sensor has pretty good "peripheral" vision, and the bar graph will tell you the closest thing seen by the sensor. If you want to change the distance that causes, say, the second LED to come on or go off, just change the values assigned to the different threshold constants.

Enjoy! Amaze your friends!

/*MaxBotix2simple
ver 29 Mar 08

A slightly extended version of the following.
The extension requires four LEDs (with resistors), and
provides a bar graph to display an indication of the value
that the analog sensor is returning.

A demonstration of using an analog sensor with an Arduino.
While general points arise, the example shows an ultrasonic
rangefinder, MaxBotix LV-MaxSonar EZ0, in action.

This program is explained in the "How To" at....

http://sheepdogguides.com/arduino/aht1a.htm
================*/


/*First: Create a human-friendly name for the pin on which you have the sensor.
 Change just the following line if you want to connect your sensor on a
 different analog input.*/
#define anIn 0 //(no ; here... never is on a "#define" line.)

#define LEDpin 13 /*(no ; here) Not "needed"... but helpful if you have
   an LED and resistor on pin 13. It will be made to "wink" so that you
   can see that your the program IS executing the "loop" function.*/

int iAnVal;  /* declare a variable to store the value coming from the sensor
      It has not been given an initial value as an assignment is made to the
      variable before any attempt to read from it.*/


/*New material, part of additions to turn MaxBotix1simple
         into MaxBotix2simple....*/
#define LEDan0 9 //no ; after any #define
#define LEDan1 10
#define LEDan2 11
#define LEDan3 12

#define Thresh0 21 //(no ; here)
#define Thresh1 36 //(no ; here)
#define Thresh2 51 //(no ; here)
#define Thresh3 66 //(no ; here)

/*End, this block of new material, part of additions to turn
         MaxBotix1simple into MaxBotix2simple....*/

void setup() {
/*The two lines here are not "needed" to read the sensor, but they
  support things which can help you see what is going on as you debug
  your program*/
Serial.begin(9600);//See note at the Serial.write line.
pinMode(LEDpin, OUTPUT);  // prepare the pin "LEDpin" for output

/*========================================
N.B.:

1) The sensor does some things at each power cycle. For the rest of
the time after coming to life, until the next cycle, it will work best if
there is only air for at least 14 inches in front of it during the second
or two as power is applied.

2) For some reason I haven't tracked down... maybe it has always done it?...
but my Arduino is, when I run this program, taking about 8 seconds (from the
time I get the message "Binary sketch size....") to start executing the "loop"
function. This isn't enough time to be a problem, but you need to know that
the pause is happening before you worry that the program isn't running. The
"wink" of the LED tells you when "loop" has started running.
=========================================*/

/*New material, part of additions to turn MaxBotix1simple
         into MaxBotix2simple....*/
pinMode(LEDan0,OUTPUT);
pinMode(LEDan1,OUTPUT);
pinMode(LEDan2,OUTPUT);
pinMode(LEDan3,OUTPUT);

} //end of setup

void loop() {
iAnVal = analogRead(anIn);   // read a value from the sensor

/*New material, part of additions to turn MaxBotix1simple
         into MaxBotix2simple....*/
if (iAnVal<Thresh0) {digitalWrite(LEDan0,HIGH);} else {digitalWrite(LEDan0,LOW);};
if (iAnVal<Thresh1) {digitalWrite(LEDan1,HIGH);} else {digitalWrite(LEDan1,LOW);};
if (iAnVal<Thresh2) {digitalWrite(LEDan2,HIGH);} else {digitalWrite(LEDan2,LOW);};
if (iAnVal<Thresh3) {digitalWrite(LEDan3,HIGH);} else {digitalWrite(LEDan3,LOW);};

/*End, this block of new material, part of additions to turn
         MaxBotix1simple into MaxBotix2simple....*/

delay(150);     /* Stop the program for a moment. Partly to
   make the "wink" work, but also as there is no reason to
   read the sensor as frequently as the Arduino could read it.*/

Serial.println(iAnVal);
/*You do not need anything "extra" beyond the normal Arduino
  Development Tool (my name for the most basic, can't live
  without it, arduino.exe that you must already have to see
  things that have been sent to the serial port by using
  Serial.println

  In the icons under the menu (menu: "File.. Edit.. Sketch....),
  at the right hand end, is one that is identified "Serial Monitor"
  if you hover your mouse pointer over it. Click on this after
  starting the upload of the program to your Arduino, and things
  that are sent with Serial.println will appear in the panel at
  the bottom of the Arduino Development Tool window.

  For Serial.println to work, you should do a Serial.begin during
  the "setup" function.

 ------------------------------------------*/

/*The three following aren't "needed"... they wink the LED so that you
can see that the "loop" function is executing.*/
digitalWrite(LEDpin,HIGH);
delay(150);
digitalWrite(LEDpin,LOW);

}

As the rabbit used to say, "That's All Folks". I hope it has been clear and helpful. Do please feel free to get in touch (see below.) Word "how you went wrong" would be useful, even if you figured out what the problem was. Maybe I can extend this "How To" note, and save the next person from the nuisance you had.





   Search this site or the web        powered by FreeFind
 
  Site search Web search
Site Map    What's New    Search

The search engine is not intelligent. It merely seeks the words you specify. It will not do anything sensible with "What does the 'could not compile' error mean?" It will just return references to pages with "what", "does", "could", "not".... etc.
In addition to the tutorials for which this page serves as Table of Contents, I have other sites with material you might find useful.....

Sequenced set of tutorials on Arduino programming and electronics interfacing.
Tutorials about the free database supplied with Open Office version 2. (If you experienced Adabas with Star Office, ooBase is nothing like it!)
Some pages for programmers.
Using the parallel port of a Windows computer.


If you visit 1&1's site from here, it helps me. They host my website, and I wouldn't put this link up for them if I wasn't happy with their service.




Ad from page's editor: Yes.. I do enjoy compiling these things for you... hope they are helpful. However.. this doesn't pay my bills!!! If you find this stuff useful, (and you run an MS-DOS or Windows PC) please visit my freeware and shareware page, download something, and circulate it for me? Links on your page to this page would also be appreciated!

Click here to visit editor's Sheepdog Software (tm) freeware, shareware pages.


And if you liked that, or want different things, here are some more pages from the editor of these tutorials....

Click here to visit the homepage of my biggest site.

Click here to visit the homepage of Sheepdogsoftware.co.uk. Apologies if the "?FrmAht" I added to that link causes your browser problems. Please let me know, if so?

Click here to visit editor's pages about using computers in Sensing and Control, e.g. weather logging.



To email this page's editor, Tom Boyd.... Editor's email address. Suggestions welcomed!


Valid HTML 4.01 Transitional Page tested for compliance with INDUSTRY (not MS-only) standards, using the free, publicly accessible validator at validator.w3.org


Why does this page cause a script to run? Because of the Google panels, and the code for the search button. Why do I mention the script? Be sure you know all you need to about spyware.

....... P a g e . . . E n d s .....