PDA

View Full Version : Noise and IsoPod ADC inputs


brian
10-10-07, 05:40 PM
I am trying to interface a SparcFun IMU (accelerometer/gyro) to the ADC inputs on the IsoPod V2. With a 12-bit ADC I would expect a resolution at least close to 3.3 V / 4096 = .8 mV. When I just read the ADC from the terminal for one of the accelerometers while the board is completely motionless, I see readings that vary as much as 2.415 V to 2.494 V. So I'm getting variations of many hundreds of mV. The board has a precision 2.5 V reference that should be accurate at least down to the single mV range, but I see similar fluctuations in my ADC readings when I try to sample this reference as well. These fluctuations represent more than 7 degrees of fluctuation for the angle measurement application I'm working on. The IMU is suppsed to be able to measure fractions of a degree, and it seems that I should be able to use the IsoPod ADCs to get at least into the single degree range. The signal I'm trying to measure is scaled at about 11 mV / degree.

I have a 22uF and .22 uF cap across the power going into the IMU board. I'm powering the IMU board with the 5V regulator from the IsoPod. I do not have any bypassing from the IMU output to the ADC inputs on the IsoPod, The connections are direct using 5" wires. I'm assuming the problems I'm having are due to noise. I've tried powering the IMU board with a precision bench supply, but the problem persists. Any recommedations on how to get more precise readings? The specs for the IMU and ADC imply it's possible to read down into the single millivolt range.

Even just pointing me at some examples for the electrical connections to the IsoPod ADCs would be helpful.

nmitech
10-11-07, 10:56 AM
Here is an example program for averaging the analog readings, and some comments and suggestions to improve the noise problem.
http://www.newmicros.com/isopod/appnotes/ADC.txt

And more examples on download page,
http://www.newmicros.com/store/product_details/download.html

Also, tie the IMU GND pin to VSSA pin on IsoPod J3 pin 2 for common ground.

brian
10-11-07, 12:50 PM
Actually, I have an IIR filter implementation I used when I was trying to read angles with a potentiometer. I was using an RC servo pot across VDDA and VSSA. I implented the filter due to the same 100 mV noise problem. The filter was very effective at producing a stable value. I just wasn't quite sure if this is a really valid way to deal with the noise.

I'd feel better if I had a cleaner signal.

Thanks, I will look at the references you sent.

brian
10-11-07, 01:57 PM
Thanks. That first reference was helpful. Looks like g_jilek already went down this path. Interesting he ended up using a Weighted Average filter, which is a simple form of IIR. Guess I didn't have to write my own 8)

brian
10-11-07, 02:19 PM
For what it's worth, this is my filter. It keeps the filtered value in a variable. The intent was to have the filtered value available in memory for other state-machines to access. It would probably be more efficeint to just do everything in a single machine state on the stack, but I wanted to separate the sample from the conversion of the value, and my sample rate is pretty slow.

( This program is an experiment in filtering the position of the
( the sensor for the pendulum. The Futaba RC servo pot appeared to
( be extremely noisy, producing variations beyond 100 mv. This code
( implements a simple software filter to deal with the noise. Appears
( to work, but this point, it's unknown if the resulting response
( will be sufficient for pendulum balance.

( Some info from notebook:
(
( Approx 28 mV / deg .. 12-bit ADC .. ref 3.3V
( This results in 0.8 mV per count on the ADC.
( 34.75 (35) counts / degree.

( Not sure if I recall correctly, but noise seemed to swamp the reading at
( this resolution by at least a full degree. This filter seems to bring
( things back in line, but not sure if the response is sufficient.
( This code was developed several months ago, comments added on 1/11/07.

( Added DUMPVOLTS loop to print filtered voltage value from position
( pot. 1/11/07

DECIMAL

5000 PERIOD

FVARIABLE fFilt
FVARIABLE fVolts

0.99E0 FCONSTANT T1 ( First filter term ... 9 / 100
0.01E0 FCONSTANT T2 ( Second filter term ... 1 / 100

: ReadAdc ADC6 ANALOGIN ;

( Filter: FilterVal = current reading * T2 + previous FilterVal * T1
(
: AdcSum ReadAdc S->D D>F T2 F* fFilt F@ T1 F* F+ fFilt F! ;

( Dumps out the position pot value in volts.

LOOPINDEX CYCLE-COUNT
DECIMAL 1000 CYCLE-COUNT END
: DUMPVOLTS BEGIN CYCLE-COUNT fVolts F@ F. CR CYCLE-COUNT COUNT UNTIL ;

MACHINE POSITION_FILTER

ON-MACHINE POSITION_FILTER

APPEND-STATE INIT_FILTER
APPEND-STATE FILTER_CYCLE
APPEND-STATE UPDATE_CYCLE

GRNLED OFF
REDLED OFF
YELLED OFF

(

IN-STATE INIT_FILTER CONDITION TRUE
CAUSES

ReadAdc S->D D>F fFilt @ F!

THEN-STATE FILTER_CYCLE TO-HAPPEN

IN-STATE FILTER_CYCLE CONDITION TRUE
CAUSES

AdcSum
YELLED OFF
GRNLED ON

THEN-STATE UPDATE_CYCLE TO-HAPPEN

IN-STATE UPDATE_CYCLE CONDITION TRUE
CAUSES

fFilt F@ 3.3E0 F* 32760.0E0 F/ fVolts F!

YELLED ON
GRNLED OFF

THEN-STATE FILTER_CYCLE TO-HAPPEN

INIT_FILTER SET-STATE
INSTALL POSITION_FILTER

brian
10-11-07, 03:11 PM
Just running the filter does in fact seem to do the trick quite nicely. Here's an updated version. The comments regarding the first filter term was incorrect, should be 99/100, and the S>D D>F can just be S>F. I must have been looking at the older document at the time.

( Derived from InvPendFilt.txt. Implements a Weighted Average
( filter to deal with the IsoPods noisy ADC readings

DECIMAL

( 5000 PERIOD

FVARIABLE fFilt
FVARIABLE fVolts

0.99E0 FCONSTANT T1 ( First filter term ... 99 / 100
0.01E0 FCONSTANT T2 ( Second filter term ... 1 / 100

: ReadAdc ADC0 ANALOGIN ;

( Filter: FilterVal = current reading * T2 + previous FilterVal * T1
(
: AdcSum ReadAdc S>F T2 F* fFilt F@ T1 F* F+ fFilt F! ;

( Dumps out the position pot value in volts.

LOOPINDEX CYCLE-COUNT
DECIMAL 1000 CYCLE-COUNT END
: DUMPVOLTS BEGIN CYCLE-COUNT fVolts F@ F. CR CYCLE-COUNT COUNT UNTIL ;

MACHINE POSITION_FILTER

ON-MACHINE POSITION_FILTER

APPEND-STATE INIT_FILTER
APPEND-STATE FILTER_CYCLE
APPEND-STATE UPDATE_CYCLE

GRNLED OFF
REDLED OFF
YELLED OFF

(

IN-STATE INIT_FILTER CONDITION TRUE
CAUSES

ReadAdc S>F fFilt @ F!

THEN-STATE FILTER_CYCLE TO-HAPPEN

IN-STATE FILTER_CYCLE CONDITION TRUE
CAUSES

AdcSum
YELLED OFF
GRNLED ON

THEN-STATE UPDATE_CYCLE TO-HAPPEN

IN-STATE UPDATE_CYCLE CONDITION TRUE
CAUSES

fFilt F@ 3.3E0 F* 32760.0E0 F/ fVolts F!

YELLED ON
GRNLED OFF

THEN-STATE FILTER_CYCLE TO-HAPPEN

INIT_FILTER SET-STATE
INSTALL POSITION_FILTER


Accelerometer output from SparkFun IMU in volts while holding the board flat against the table. Not shown here, but I can now detect even very small wiggling of the board. It appears that just the filtering is sufficient.

2.4545
2.4547
2.4547
2.4549
2.4549
2.4549
2.4549
2.4549
2.4548
2.4548
2.4548
2.4548
2.4545
2.4545
2.4546
2.4546
2.4547
2.4547
2.4547
2.4547
2.4547

RMDumse
10-15-07, 11:52 AM
You may be already well past this, but as an additional point: A critical point might be the wiring between the IMU and the A/D section. Did you note there was a separate place for an analog ground? We have chokes on the board on both the analog power and ground side, so if you separate your signals between digital and analog sections sometimes you can bet better results.

If you are powering from the board's 5V, you may be importing digital noise on the digital ground.

Does the IMU have a separate analog ground you can match to the 'Pod analog ground reference?

I am trying to interface a SparcFun IMU (accelerometer/gyro) to the ADC inputs on the IsoPod V2.

Something to consider. I've never seen a quiet gyro or accelerometer yet. They are known for their noise.

It's good you tried the 2.5V reference.

With a 12-bit ADC I would expect a resolution at least close to 3.3 V / 4096 = .8 mV. When I just read the ADC from the terminal for one of the accelerometers while the board is completely motionless, I see readings that vary as much as 2.415 V to 2.494 V. So I'm getting variations of many hundreds of mV.

Just as a point of clarification the difference between 2.415 V to 2.494 V is 79 mV so you really aren't up to the "many hundreds of mV" range in actuality, unless I misunderstood something.

I'm glad the filtering worked out, and appreciate you sharing your code.