View Full Version : Noise and IsoPod ADC inputs
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.
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.
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)
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
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.
vBulletin v3.0.7, Copyright ©2000-2012, Jelsoft Enterprises Ltd.