Let's Make Robots!

Getting 3 axis accelerometer to work?


I am attempting to use a three axis accelerometer to detect when my robot runs into something.  My problem is that it only sort of works...with the code I wrote for it.  The accelerometer works fine, but my algorithm and/or placement of the accelerometer doesn't do it.  I saw Oddbot do this with one of his little robots, and it seemed to work fine.  Oddbot is way (well way, way, way) beyond my skill level with this stuff, but if he can get it to work, I should too theoretically.

My robot is fairly heavy for a hobby robot (about 5#) which would affect how the accelerometer works because it has more momentum so changes in direction might not register as well.  I put the accelerometer in the very center of the robot, attached the sensor with electric tape and watch the X and Y axis(es).  If I see a > .4 g change and then another > .4 change very soon after, I assume I ran into something.  Based on whether it was a negative g or positive G in the Y axis defines whether I back up and then turn left or right.  Pretty simple, straightforward, 15 lines of code to implement - should work? 

Without the motors running, all changes to the robot are picked up with the accelerometer.  I can slap the robot, see the numbers change and a good jolt will give a > .4 g change and it will attempt to back up and turn etc.  The problem is that when I am running this on our wood floors, across tile and grout lines etc, that is enough to register sporadically as a > .4 g change, so it will back up, turn etc even though it hasn't run into anything.  Even looking for a .4 g change, it sometimes doesn't register when I run into something and it will grind and grind until I kick it (giving it a > .4 g jolt) which makes it back up and turn one way or the other.  What is frustrating too, is with fresh batteries, just starting the robot in a straight line is enough to register a > .4 g change so it will go 6" back up turn, go 6" back up turn, rinse and repeat.  I have tried all kinds of different numbers, put in many hours of stumbling behind it in my dining room and .4 g gives the best, albeit not acceptable performance.  A lower number and all it does is back up and turn, a bigger number and it doesn't register anything.

One thing I had thought of was to put the accelerometer on a piece of plywood or plastic that had 4 small rubber bands pulling gently from all corners.  This would increase the movement and therefore the g numbers when I hit something which might be enough for me to filter out background readings from going straight across uneven floors, etc.  Maybe if I placed the sensor closer to the front of the robot where it is going to hit things I could get more reliable readings?

I would like to believe that defeat is not in my lexicon.  But I am feeling like the San Francisco 49ers this past Monday.  I have probably spent too hours so far on this (embarassingly high amount of time), and although I have learned a lot, I am nowhere near having something that can reliably detect collisions.  Any one else do this successfully?  Anyone have any suggestions?




Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

I bought my ADXL345 for only a couple of $ on Ebay. I had to play for like 5 min to find the right threshold to trigger the interrupt. Could be that it is much harder on a big heavy bot though.

You have a challenge for sure. Accelerometers by nature detect motion or G's so on a mobile platform and without some filtering they are very noisy. That's why you see Gyro /Accel combos and comp filters used in balancing bots. I would definitely check out Bajdi's bot for an example. It already had the tap detection feature so I'm just guessing, really guessing, that would need a pretty high G hit to determine you hit something. Would be an interesting project for sure. Keep us posted on your progress! Stephen

could one not take forward motion into account when calculating a hit/tap?

.01m/s with a hit/tap would mean 0m/s in .1 of a second?
I had to look up how to calculate acceleration, because, it has been a couple days since I used the formulas. :)

a = (Vf - Vi)/t
a = (0 - .01)/.1
a = -.1/1 = -.1 m/s/s

.1 = 9.8x / 100
10 = 9.8x 
1.02 = x, so, if the bot were traveling at .01 m/s (1 cm/s) there would be a .02 change in acceleration, I think. :)

Looking at your picture it has been more years for me than you! 

That might be a way to approach it.  The theory is good and not an approach I had thought of.  I may just use the current sensors I have on my motor driver to detect the collision.  I was playing with it last night, and it seems pretty repeatable.

Thanks for making me feel better about not making this work.  I am pretty new to this and since I saw others had done it, that it was a good way forward.  One thing I didn't mention in my post is that I have current sensors on my canakit motor driver for each motor.  bdk6 mentioned using an encoder which made me think about how the current sensors would be great for exactly this issue.  I was so focused on making the accelerometer work, I wasn't thinking big picture about the tools I already have.  I probably don't even need the accelerometer or will try a combo with both.

detection. Maybe you need to have some code that ignores the accelerometer for a bit? Also, you said the grout lines can trigger a detection. Is that detection only on the X and/or Y axis'?

ignoring the accelerometer after startup.  Maybe get the time when it starts forward and ignore for 500 ms until it settles down.  With the grout lines, I get both x and y numbers since it never hits it square on and the tiles aren't exactly the same height.  Also, I have 3 1/2" oak strip flooring and if the wheels hit a high spot I can get the same jump in the g forces in both x and y axes on either the tile or the wood flooring.  My project uses an  existing battery powered vaccuum as its base, and I am kind of stuck with the hard plastic 3/8" rollers on it for front wheels.  It may be impossible to write software around that issue...


Which accelerometer do you have? I made a crash bot some time ago using an ADXL345 accelerometer. The ADXL345 has "tap detection", that triggers an interrupt. My robot is quite small and light so it was very easy to find the right value.



is where I bought it.  I used their library which does analog conversion to g forces.  It doesn't have a tap detection feature but is cheaper too.  I was assuming that this was a software or algorithm issue on my part.  Since the tap detection on your sensor goes to an interrupt, maybe I need to speed up the cycle of readings and look at the data difference generated between hitting something and riding over uneven floors so I can create my own "tap" detection.   I may yet end up buying it though.  Thanks for the suggestion!