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.
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 Sonar_I2C_Sender_v005.zip
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 APM_I2CSonar.zip
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!)
Would this work with the hc-sr04?
I am working on a obstacle avoidance system for my quadcopter. I am also using a Maxbotix XL MB1200 sonar sensor. I am planning to do my coding with Arduino Uno and have a APM 2.5 flight controller. I have read your blog and was wondering if I should follow the same steps? Meaning connecting the arduino to APM with I2C ? Also I didnt understand one part.. Did you alter the code of the APM or just did it within the Arduino ?
I appriciate your help :)
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.
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.
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!
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. ...at 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 it...one 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.
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. ...by 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,
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. http://copter.ardupilot.com/wiki/sonar/
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?
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)