ADXL213 accelerometer sensitivity issues and noise

I got a ADXL213 ±1.2g accelerometer (on a sparkfun breakout board) to use it for some tilt angle measurements with arduino. In its datasheet (http://www.analog.com/static/imported-files/data_sheets/ADXL213.pdf) I read it has a typical sensitivity of 30%/g. I understood that as a percentage of the supply voltage so i thought it would be around 1.5V/g (with Vs=5v).

But a quick measure with a tester showed 2.42V at 0 degrees and 1.78V at 90 degrees. So, sensitivity is around 0.74V/g.

Taking a look to a comparison table between different accelerometers by Analog Devices (http://www.analog.com/en/sensors/inertial-sensors/products/index.html#Low_g_iMEMS_Accelerometers), you can see that ADXL203 (1.7g), has a sensitivity of 1V/g... this seems to me really strange!

In addition, when i connect one of the sensor's axis out to one of arduino adc and i read it, i see that the less significant digit of the raw count read is affected by noise (for example at zero, degrees, with no movement or vibrations, it outputs values between 503 and 505). Thus, the measured angle value fluctuates of more than half degree (too much for my application).

I read this thread (http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1251094083) and i'm going to use the averaging method, but i also read about other methods to reduce noise:

  • Using bigger capacitors on the sensor's outputs (as showed in the sensor's datasheet). Since i need static measurements, i could use a 4.7uF capacitor (in parallel with the 0.1uF capacitors present on the sparkfun's breakout board);

  • using an external, better adc converter (like the 18 bit one showed in this thread: http://forums.adafruit.com/viewtopic.php?f=31&t=12269 );

  • using a 3.3 Vref voltage for arduino ADC, since the sensor outputs 3.12V max at +90 degrees (but i don't know whether and how i can get a reliable enough 3.3V voltage reference);

Which one of the 4 methods (average reading, capacitors, external ADC, 3.3V reference) you think would be really useful for my application? Are there other ways i could consider?

Sorry for the long post and for my broken english, and thanks in advance!

Couple of things, first, read the datasheet! It says if you're having problems with noise:

For most applications, a single 0.1 [ch956]F capacitor, CDC, adequately decouples the accelerometer from noise on the power supply. However, in some cases, particularly where noise is present at the 140 kHz internal clock frequency (or any harmonic thereof), noise on the supply may cause interference on the ADXL213's output. If additional decoupling is needed, a 100 ch937 resistor or ferrite beads may be inserted in the supply line of the ADXL213. Additionally, a larger bulk bypass capacitor (in the range of 1 [ch956]F to 22 [ch956]F) may be added in parallel to CDC.

Also, looking at the datasheet, this accelerometer outputs a PWM digital signal, you can read this PWM output as an analog signal like you're trying, but I don't know how precise it will be compared to directly reading the digital signal.

Here's the deal, if you're application isn't speed dependent, you can build a low pass filter and use that to filter out any noise you have, otherwise you can average the signal over time in software and accomplish the same thing.

Increasing your ADC bit resolution might help, but not if you're fluctuating several bits with your current ADC, your upgraded ADC will simply show more resolution of an already noisy signal.

Couple of things, first, read the datasheet!

I did read the datasheet, the part you highlighted is the reason why i thought to use a 4.7uF capacitor.

I'm not familiar with PWM signals, I guess i would have to use pulseIn(), the concept doesn't seem complicated, but then i'd have to be aware of accuracy issues in measuring duty-cycle and deal with them. I'll try when i'm sure about the analog output method, so I could even try to compare the two approaches.

Your observation about ADC does make sense, but I read that arduino ADC might not be suitable for sensors with output impedance of more than 10Kohm, and ADXL213 seems to have a 32K one. So maybe this is the cause of noise, and the solution would be using an ADC with a higher input impedance (as far as i understand).

Reading values from the sensor with my tester shows a noise in the order of 1 millivolt, lower than the noise read by arduino (around 3 counts, so around 15mV), and again i don't know whether the noise comes from the sensor itself or from my (crappy) tester. As soon as i can I'll give a look with better tester and an oscilloscope.

And I still can't understand what does 30%/g sensitivity means if not 1.5V/g (with Vs=5V), the ADXL213 datasheet is the only one showing this parameter's value in such a way. And it seems to me really strange that a 1.2 accelerometer has a lower sensitivity than a 1.7 one. I have doubts I might have received another accelerometer than the ADXL213.

I would agree that better supply decoupling is a good idea, but you are quite right about reducing noise, increase the filter capacitors on the outputs - basically decide what bandwidth you want and go from there. However note that a very low bandwidth may lead to unacceptable settling times after a change in orientation.

using the 3.3V as an analog reference will help pull more bits in, but for the ultimate use a (low-noise) op-amp to bring the signal to a wider range - you'll need an op-amp that runs from a low voltage (I think there are some spec'd for 2V-->6V) so you don't saturate the output stage. You probably want to establish a signal ground at 1/2 the supply voltage for the op-amp - you probably want high-accuracy resister divider or a trimmer pot to calibrate... I recommend Horovitz and Hill for more ideas/insight.

An extra trick that might help is to select the filter capacitor so that you still get fluctuations in the LSB only, and then sum several consecutive A->D readings to pull more signal from the noise - summing 8 consecutive readings might get a bit or two more accuracy with luck - here you use the analog noise to allow the A->D to sense smaller differences than 1 LSB (by averaging).

Disclaimer - of course the noise may be fundamental and represent the limits of the sensor's accuracy... Good luck

for the ultimate use a (low-noise) op-amp to bring the signal to a wider range

I thought about this, and I will try with the op-amp, considering also that the sensor will be connected to arduino through a long cable, so i will definitely need a buffer to lower sensor's output impedance and not drown in the noise...

I found this document ( http://focus.ti.com/lit/an/sloa098/sloa098.pdf ) giving some ideas about buffers for ADC: i think i will use the 4.1 method (page 14), but without C1, and following MarkT advices (thanks!)

Now i'm searching for the right op-amp. If someone has suggestions, he's welcome! :)

As I read more, I begin understanding more things... and getting confused on them! I can't just take an ac-coupled buffer and eliminate the input capacitor. I need to use op amp as DC amplifier.

I understood I have two issues. First, I want to use a single supply, the 5V coming from arduino, so i need to create a virtual ground, that should be at Vcc/2. But I also want to bias the amplifier on the 0g sensor value (around 2.4V). And these two aspects seems to me linked in some way I still can't figure out clearly.

Than, I also read about rail-to-rail op amps, and i think i need one of them if i want to be able to actually go close to 5V on the ADC in for high sensor's output values.

I'm confused, I'm searching and reading but any help would be appreciated. I don't have Horovitz and Hill, I usually use Sedra-Smith as reference but i don't have it in my house now. :S