Tuesday, April 5, 2011

Interfacing MaxSonar EZ1 with mbed

Libby carefully inspects my wiring...

MaxBotics makes the LV-EZ series of sonar rangers. The devices are aptly named and provide very flexible interfaces: TTL serial, analog, and pulse width to represent distance. The rangers can be chained together so that they read and output results sequentially. Pretty neato.

Several weeks ago, while facing problems getting my new GPS to work, I decided to try something easier: working with a recently purchased MaxSonar EZ1 ranger (datasheet, PDF).

MCU of choice for the interfacing project was the ARM Cortex M3-based mbed.  The mbed is the brains on board my AVC competition robot Data Bus.


One first has to solder header pins onto the ranger module. Not a big deal. The pins are clearly labeled GND, +5, TX, RX, AN, PW, BW. The module can take any voltage from 2.5-5.5V so standard 3.3V and 5.0V will work. My mbed runs on 3.3V.  The EZ1 datasheet provides scaling information for 3.3V and 5.0V supplies.

For the mbed, connect VOUT (3.3V, pin 40) to +5, GND (pin 1) to GND, p20 (pin 20) to AN. That's all there is to it on the hardware side.

Connecting an mbed to the EZ1 sonar


Initially I tried reading serial data out of the EZ1 but for some reason I was not getting the output indicated in the datasheet. So I thought I'd try reading the analog values.

Use the mbed library's AnalogIn API, read the analog value as a float. Then convert the analog reading to voltage, and finally convert to inches using the scaling factor provided in the datasheet (6.4mV/inch for 3.3V supply)

Source code on mbed.org

AnalogIn ain(p20);
Serial pc(USBTX, USBRX); // tx, rx

int main() {
    float adc, volts, inches;
    int feet, in;
    while (1){
        adc = ain.read();           // read analog as a float
        volts = adc * 3.3;          // convert to volts
        inches = volts / 0.0064;    // 3.3V supply: ~6.4mV per inch
        feet = (int) inches / 12;   // inches to feet (trunc)
        in = (int) inches % 12;     // remainder: in(ches)
        pc.printf("%8.2f adc %8.2fV %8.2f in %d'%d\"\n", 
                  adc, volts, inches, feet, in);

        wait(0.05);                 // ~20Hz update rate ; note we aren't
                                    // truly synchronized ...   

Moving the sonar around the room, pointing at various objects:

0.11 adc     0.35V    54.77 in 4'6"
    0.11 adc     0.35V    54.77 in 4'6"
    0.03 adc     0.10V    15.36 in 1'3"
    0.05 adc     0.17V    26.32 in 2'2"
    0.02 adc     0.07V    10.58 in 0'10"
    0.07 adc     0.23V    36.39 in 3'0"
    0.02 adc     0.07V    10.58 in 0'10"
    0.03 adc     0.11V    17.63 in 1'5"
    0.02 adc     0.06V     9.19 in 0'9"
    0.02 adc     0.06V     9.07 in 0'9"
    0.01 adc     0.05V     7.43 in 0'7"

Testing and LCD

To test the unit outside, I hooked up a serial-enabled LCD to the mbed, and transmitted the foot and inch data to the LCD. The LCD uses a common HD44780 controller.(For wiring, see the wiring diagram above)

Send 0xFE to indicate a command followed by 0x01 to clear the screen. To position the cursor, send 0xFE followed by 0x80|n where n is the cell number (0x00 is the top left, 0x40 is row 2, left, 0x10 is row 3, left and 0x50 is row 4 left.

I added the following to the code above to print out feet and inches.

        lcd.putc(0x80 | 0x00);
        lcd.printf("%2d'%2d\"             ", feet, in);

I powered the mbed by connecting a 9V batter on VIN (pin 2) and GND (pin 1) (see wiring diagram above)

The test session was intended to determine the feasibility of using the sonar on my AVC robot for detecting barrels, people, cars, and other UGVs.


The maximum detection distance appears to be approximately 22 feet (6.7m). The device can detect a variety of objects, narrow to wide: my Jeep Grand Wagoneer is huge and hard to miss, my mailbox is much smaller but the sonar found it too.

The ranger will sit only a few inches off the ground and I found that the beam pattern causes echoes from the ground in front of the ranger. That's because the propagation pattern expands both vertically and horizontally.

A week or two ago, I ordered a parabolic reflector for the Parallax Ping sonar that may help to reduce the vertical dispersion while increasing the range of the EZ1.


  1. Sorry for posting a question on here but I need some help. I am also using the XL-5 ESC for a robot (not AVC) but I cant figure out how to control it with my arduino. The steering works fine and if I have it plugged into the receiver and then plug it into my arduino it works. Otherwise if I just have it plugged into my arduino and send a command the light just shines red. Do you have any code you could share for the xl-5. Thank you and sorry for asking a question in the comments.

  2. The XL-5 responds to servo pulses just like your servo but there are some tricks to consider, particularly on Arduino and particularly with the XL-5. Use the "contact me" link on the page, upper right, send me a message with your email and we can talk offline, k?