ADC Example: LV-MaxSonar-EZ4 Ultrasonic Range Finder
Using ADC to measure the distance between two objects with an umtrasonic range finder
The LV-MaxSonar-EZ4 from MaxBotix is an easy to use, reasonably priced ultrasonic range finder with a range of 6-255 inches (15cm to 6.45m). You can get readings from the device using Serial, Pulse-Width (PWM) or Analog outputs. In our case, we're going to use the analog output on the device to measure distances between the sensor and the nearest object.
Since the device is manufactured in the US, all distance measurements are returned in one-inch units. To determine how many inches you are from the nearest obstacle, you simply need to divide the results of the A/D conversion by two.
In this example we will be using AD1.6 (located on pin 1 of the LPC2148, also containing GPIO 0.21). Sample code and a full project file are both located below if you'd like to try this out for yourself.


Source Code
The full project for this example is available at the end of the page, but we've also added the source code of main.c here for convenient reference:
#include "cross_studio_io.h" // Required by debug_printf
#include "lpc214x.h"
// This example assumes that PCLK is 12Mhz!
// Method prototypes
void maxSonarInit();
int maxSonarRead();
// Program entry point
int main(void)
{
maxSonarInit();
// Constantly read the results of ADC1.6
int distance = 0;
while (1)
{
// Get conversion results
distance = maxSonarRead();
// Send results to the Crossworks debug window
debug_printf("%d inches\n", distance);
}
}
// Initialise LV-MaxSonar-EZ4 on ADC1.6 (P0.21)
void maxSonarInit(void)
{
// Force pin 0.21 to function as AD1.6
PCB_PINSEL1 = (PCB_PINSEL1 & ~PCB_PINSEL1_P021_MASK) | PCB_PINSEL1_P021_AD16;
// Enable power for ADC1
SCB_PCONP |= SCB_PCONP_PCAD1;
// Initialise ADC converter
AD1_CR = AD_CR_CLKS10 // 10-bit precision
| AD_CR_PDN // Exit power-down mode
| ((3 - 1) << AD_CR_CLKDIVSHIFT) // 4.0MHz Clock (12.0MHz / 3)
| AD_CR_SEL6; // Use channel 6
}
// Read the current distance (in inches) using ADC1.6
int maxSonarRead(void)
{
// Deselects all channels and stops all conversions
AD1_CR &= ~(AD_CR_START_MASK | AD_CR_SELMASK);
// Select channel 6
AD1_CR |= (AD_CR_START_NONE | AD_CR_SEL6);
// Manually start conversions (rather than waiting on an external input)
AD1_CR |= AD_CR_START_NOW;
// Wait for the conversion to complete
while (!(AD1_DR6 & AD_DR_DONE))
;
// Return the processed results, dividing by two for distance in inches
return (((AD1_DR6 & AD_DR_RESULTMASK)
>> AD_DR_RESULTSHIFT)
/ 2);
}