Creating an I2C sonar for Arducopter

I've created an I2C digital signal sonar module to avoid the noise problems I have been having with the current analog signal sonar module.


Seeing all the problems we are having with noisy sonar data got me thinking

Where does the noise come from? Is it:

  • RF noise from the ESCs affecting the sonar module directly ?
  • RF noise from the ESCs affecting the analog signal line between the sonar and APM?
  • Noise on the DC power supply affecting the Sonar module?
  • Something else?

The current popular solution of remote mounting the sonar has probably eliminated DC power as the primary source of our noise. In other words - if noisy DC power was the ource of the noise problem then no matter where you mount the sonar you would still have the noise. Regardless if DC noise were still an issue Maxbotics has a solution to DC noise in their FAQ.

Personally I've found that remote mounting the sonar module has only partially solved my noise problems. This is probably due to the Sonar power and signal cable passing within 10mm of one of the ESCs near where it plugs in to the APM on my arducopter.

(This photo shows how close my ESC is to the analog port on the IMU Shield)


So I wondered if I could get rid of the analog signal path and see how the sonar noise changed. This has led me to put together a I2C sonar module. This communicates digitally between the sonar and APM using the I2C port on the APM IMU shield. It also allows you to use the PWM output from the sonar which Maxbotics recommends as "the most accurate"



All that is needed is an Arduino, an I2C cable and some software.

Arduino mini

DIY Drones GPS Cable

The GPS cable supplies power and connects data lines between the Arduino and APM IMU Shield (you need to cut one end off the cable)

APM IC2 Function Arduino Mini

PIN1 <-----> GND <-----> GND

PIN2 <-----> 5V <-----> VCC

PIN3 <-----> SDA <-----> A4

PIN4 <-----> SCL <-----> A5


Three Wires connect the Arduino to the Sonar

Arduino Function Sonar

GND <-----> GND <-----> GND

VCC <-----> 5V <-----> V+

D5 <-----> PWM <-----> PIN2


Here is what it looks like mounted on the sonar - with double sided tape

The sonar is on a standard jdrones sonar mount


The Arduino then needs to be programmed as an I2C slave.

Here is my code

You must use an FTDI cable to program an Arduino Mini

The code continuously reads and stores the sonar distance as a PWM signal from the module.

It responds to any I2C request for data with a two byte integer representing the current sonar range in cm.

Additionally it has the ability to return noise filtered sonar data.

Note the MaxBotix experts strongly recommend a mode or median filter not averaging filter.

Currently the code can be requested to return spike filtered, median or mode filtered data.


I have modified the Arducopter code to use this I2C sonar and started testing

Here is my sonar library

If the testing all works OK I'll see if Chris or Jason want to put it in the code repository



To put it simply the results so far are great!

Indoor and outdoor tethered tests show no noise and no data problems

Here is a graph showing Sonar data in red and baro in green.

first segment is with motors running second with motors off

Its too windy to fly here today (in the Aussie vernacular: It's strong enough to blow ya dog off its chain!)

Stay tuned!




Views: 19764

Comment by Randy on February 26, 2013 at 6:52am

For automatically detecting the sonar what we should do is have a very small detection class.  This hopefully won't take very many bytes of RAM (eating program space is ok, we have enough).  Then we call this detection class can ping the i2c bus to see if there's a sonar there or not, if yes, it returns a true and we dynamically create the i2c sonar class and use it.  if it's not there, we dynamically create the regular sonar class that uses the analog pin.   This is how we've handled the GPSs anyway.

Comment by Chris on February 28, 2013 at 12:07am

I do not agree with wasting program space:

avr-size --mcu=atmega2560 --format=avr /tmp/
AVR Memory Usage
Device: atmega2560

Program: 214054 bytes (81.7% Full)
(.text + .data + .bootloader)

Data: 5544 bytes (67.7% Full)
(.data + .bss + .noinit)

There is still space, but not enough for wasting in my opinion!

btw I solved my noise issue, I had still the non I2c maxbotix conntected which causes noise on the new one on I2C. 


Comment by Nathan Asdourian on May 10, 2013 at 8:22pm

I don't suppose there is a way to make this able to respond to multiple i2c address inquiries?

I'm just getting started with looking through what you wrote but I just found out that the spektrum data bus is i2c also, I was hoping that with all the extra available cpu time, I might be able to somehow have it also respond to my radio, and snoop in on the telemetry data stream to acquire any of the info I want to send to my tx(namely the gps info)

Comment by Richard on August 16, 2013 at 12:03am

I'm planning to add a Sonar sensor to my Hex.

Please, can anyone tell me, if i2c sensors are already implemented and useable in Arducopter 3.0.1 ?!

I really searched all over the internet but could not find any information regarding this.

Or should I go with an analog version?

Comment by Randy on August 16, 2013 at 12:43am


    The I2C sonar isn't supported yet I'm afraid so you'd better go with the analog version.  I just updated the wiki page for this within the last 24h or so including adding a note that the i2c sonar's are not supported.

Comment by Richard on August 16, 2013 at 3:37am

Thanks for your quick reply, Randy.

I just downloaded the Ardupilot Arduino SDK and synced with git. (master branch)

In the rangefinder lib, I saw that the XL I2C seems somehow implemented. you :-)

Can you give me a short hint how to activate it?

(Sorry for the noob question. I'm not new to programming and electronics but Ardupilot and Arduino)

I just want to avoid buying an analog version now and then a new one with I2C in a few weeks when it might get officially implemented.

Too said, there is no sensor supporting I2C -and- analog output.

Thanks in advance,


Comment by Randy on August 16, 2013 at 6:34am


     Yes, I wrote the library but sadly neglected to incorporate it properly into arducopter.  Basically we were running low on memory at the time (mostly resolved now) and we couldn't afford to create the object but then not use it. a very high level, to use it you would need to replace the line in ArduCopter.pde where it creates the analog sonar object with the i2c sonar.  ... but then there's another problem...the i2c sonar requires you make two calls to to ask for the latest distance and another to tell it to take another reading.  So that 2nd call needs to be added into one of the arducopter's loops or the call to read from the i2c sonar should be modified to it also tells the sonar to take another reading immediately.

Comment by Richard on August 16, 2013 at 7:59am

Regarding the 2nd call: even without having detailed info about the programming structure of Arducopter, from programmer's sight of view, your second attempt sounds the best for me: to tell the sensor to make another measuring soon after reading the previous value. (if the reading-loop does not have a too long delay so that the new measuring does not get outdated till next read.

Everyone is messing around with shieling, noise reduction and a lot of other things to get the analog sensors running well.

I2C sensors are available at nearly the same price and you already implemented it into the source.

It would be really said, not using it!

As a developer myself, I fully understand, that you cannot post detailed programming instructions for every request someone has.

But I'm sure (and google also says so ;-) ) there are many users interested in using I2C Sonar sensors.

So if you had the time, it would be great, if you could write a quick how to, which parts of  the code need to be changed to use it, for those interested.

P.S. I had a look in the repository, and you are investing a lot of time and afford into the project. Just wanted to say: Thanks you!

Comment by sumartono on August 21, 2013 at 10:34pm

I got 3dr quad recently, and happy with all available features provided,also have the chance to test drop tennis ball like Randy's video, auto takeoff and landing as well.I am also need for I2C sonar to be implemented as final project, I hope Randy and others dev team will make it available at the soonest.I am agree as Richard request, there are many users interested on I2C Sonar.Thank you.

Comment by Randy on August 22, 2013 at 12:48am

We've greatly improved the reliability of the sonar ahead of the AC3.1 release (maybe 1 month away?).  Definitely I2C sonar is in the future but probably won't make AC3.1.


You need to be a member of DIY Drones to add comments!

Join DIY Drones

© 2020   Created by Chris Anderson.   Powered by

Badges  |  Report an Issue  |  Terms of Service