Thursday, July 25, 2013

A simple dead reckoning algorithm on Arduino

Acceleration of an object moved from left to right, X4

I was trying to get the position of my accelerometer (relatively to its initial one) but googlein' around doesn't seem to be enough  this time. The concept is quite simple: since the acceleration is the first derivative of velocity, and position's second one, we could calculate the position of an object only by integrating (two times) the data from its acceleration. Ok, let's start from a good set of acceleration data. The graph above shows 2000 elements read out from the serial out of Arduino, with a rolling mean of 10 values. I'm trying to figure out why there are so many spikes to make it need 10 samples to get rid of them. Perhaps my "professional" solder process made some false-contact and the stirring of the circuits make them touch.

This is an example of this data loss (around the 925th sample) probably due to the phenomenon described above, or perhaps for the low quality of the contacts on the arduino side. Indeed I didn't use wires like these, but just a copper wire without its plastic cladding.
Anyway, let's do the dirty job. Since:

So, considering as a raw approximation a simple sum as the integrating function, we have that
  1. velocity(i) = velocity(i-1) + acceleration (i)
  2. position(i) = position (i-1) + velocity (i) 
Whereas v(0)= p(0)= 0; For a first analysis I tried to implement the algorithm in Excel (offline, of course) and the partial results are show below. The blue line is the acceleration while the orange one is the velocity.

Image 3

These are not from the same data as those in the first image, but the filtering is the same: a rolling mean of 10 values. The setup (Arduino + ADXL) is moved along the X-Axis for six times. Moreover, in this case I've already added a couple of further improvements. First, all the value below a threshold are thrown away to avoid the effect of the small vibrations. Second, since there could be an "offset" fixed value of static acceleration, this is calculated over a mean of 2048 samples and subtracted to all of the successive values. 
Anyway we introduce an error at every step, which is integrated over time and so it keeps growing with the number of samples. If you click on the image 3 you can see how the velocity doesn't return to zero even between two movements!   The error in the estimation of the velocity brings to an even bigger error in the calculus of position: 

Image 4
Even if the object was moving alternatively between two points, it seems moving away from them (the system is not stable). Ok, so far so good. It could not be so simple!  :)
Let's try to reduce this error. If you have any advice, question, or if you just want to insult me, do it in the comments below. See you soon.

Wednesday, July 17, 2013

ADXL345 + Arduino!

As many Arduino enthusiast, I bought a ADXL345 accelerometer from RS components and I set it up to communicate with my board in order to use it in a wider electronic project. I did want to share my experience. If you want to try the accelerometer yourself, you have two choises: buy the sparkfun BOB, which comes ready to be used, or buy the accelerometer and a couple of passive components from your preferred distributor and make your own Break Out Board.
I opted for the second one! ;)
Of course you'll need some hardware stuff, and the results will not be as good as the assembled one, but the satisfaction will be over 9000. For the breakout board you will need some bypass capacitors to solder as close as possible to the VCC pin of the SMD, which is a LGA. After some hours of super focused, high level, ultra professional layout design with EAGLE, and after a couple of iron stains on my jeans, the result is the following:

ADXL345 on a DIY breakout board.

As you can see the result is quite obscene if compared to the red-fashioned ultra-small sparkfun edition, but this is a DIY and I love it!  In the image above the wire needed to provide power supply and I2C communication are already connected to my Arduino UNO. The second step of course was to google for some lines of code to read the accelerometer data. Internet is full of code for Arduino and this IC. Basically the code aims to: 
  1. Initialize the I2C communication setting the Arduino as Master & the IC as Slave.
  2. Wake up the device from its low power mode (sleep mode)
  3. Read out the X-Y-Z acceleration value. 

I left out the function code for "readFrom" and "writeTo" to keep the post as compact as possible. If you need it, just leave a comment and I will send you the entire project. The image below is a snapshot from the IC's datashhet and it shows the meanings of the bits in the Power Control Register, whose addres is 0x2D. As you can see from the code above, we first reset the register writing to 0 every bit, and than we set to 1 the bit "Auto Sleep Mode" and "Measure". The latter is the one who let the device start measuring. Of course we could set the bit with a single instruction, but since this is kind a tutorial, I thought it was better to leave the three different tokens.
Next step: Calculate position from acceleration. If I reach 10 comments, I promise I'll do it in one day! ;)

ADXL345 POWER_CTL Register configuration byte