Electronic Projects, forums and more.

Go Back   Electronic Circuits Projects Diagrams Free > Electronics Forums > Electronic Projects Design/Ideas/Reviews


Electronic Projects Design/Ideas/Reviews Are you building an electronic project or want to? Maybe you need some assistance? Come and submit your electronic questions here and let our experienced members find a solution.

Reply
 
LinkBack Thread Tools Display Modes
Old 26th July 2007, 08:10 AM   (permalink)
Default filters?

I am just at the beginning of a new hobby project and I am hoping someone can help. I have a 3 axis accelerometer which is connected to an Atmega16. I am using the Atmega16's 10 bit ADC's to read the voltages from the accelerometer. I am getting the values from the AVR through a comm port then displaying these values on my PC.

What I am finding is that the return values are fluctuating a small amount even when the accelerometer is stationary. And when I move the accelerometer I am getting a lot of variation in the values. I have been reading a lot about what other people have done with accelerometers and there is some talk about both software and hardware filters. They talk about filtering to certain bandwidths but I don't understand what that means when I am just measuring a dc voltage. My understanding of electronics is very basic.

I was hoping someone can explain in idiots terms a bit about filters and how I would use them in my applications. I was also wondering how would I smooth the data using software?
Chris_P is offline  
Old 26th July 2007, 09:44 PM   (permalink)
Default

Ok what they are saying is you must take several reading on the same channel( switching channel on the ADC is going to introduce noise ) so when i use the ADC on the AVR i tend to read sample a few times before changing chanels (ideally you should throw away the first reading) but I have found at least 8 readings makes the averaging easy but here is some code i wrote 3yrs ago so i will try and explain it (for image craft complier) it does not use the ADC interupt at all but i use the interrupt flag to determine the next sample is ready call ADCinitalise at MCU startup to prep the ADC


void ADCData(void)
{
unsigned char i;
unsigned char j;
for (i=0;i<6;i++)
{
ADMUX=i; // this is your ADC CHANEL being sampled
unANALOGUEBUFF=unANALOGUEIN[i]; // previous sample loaded makes part of the new sample ie(filter)

for (j=0;j<64;j++) //set j for 64 for samples of one channel
{
ADCSRA|=(0x01<<ADSC); //start samples
while(!(ADCSRA&(0x01<<ADIF))){}; // wait for conversion to complete
ADCSRA|=(0x01<<ADIF); // AVR write one to clear flag
unANALOGUEBUFF=unANALOGUEBUFF+ADC; //add old with new makes part of filter
unANALOGUEBUFF=unANALOGUEBUFF/2; // divide by 2 to bring reading to proper value
};
unANALOGUEIN[i]=unANALOGUEBUFF; // store in array for next time also use this array to send average value to your pc
};
}

void ADCInitialise(void)
{
uchCHANNEL=0;
ADCSRA = 0x00; //disable adc
ADMUX = 0x00; //select adc input 0
ACSR = 0x80; // adjust values to your needs read datasheet as my system does not use the interrupt vectors
ADCSRA = 0x83; // adjust to suit
asm("nop"); // gives adc time to settle from setup
asm("nop");
asm("nop");
}

ok in short it takes an average reading of 64 samples+the previous value to give the new result and store it in an array for later use the array contains the 6 channel of the adc Note i didnt use channels 7 and 8 in your case chane the for loop( i ) to sample 3 channels "for (i=0;i<3;i++)"
Less samples change loop for (j) for (j=0;j<32;i++)" will take 32 + the old valus and filter average it
seveprim is offline  
Old 26th July 2007, 11:24 PM   (permalink)
Default

Thanks for that advice seveprim. My existing ADC function takes one dummy reading and then averages 8 readings. I change the ADC channel before using this function. Shown here:-
Code:
int ADC_read(void)
{
        char i;
        int ADCr = 0;
        int ADC_temp = 0;

        sbi(ADCSRA, ADEN); // enable the ADC

        // do a dummy reading first
        ADCSRA |= (1<<ADSC);

        // wait for conversion done flag
        while(ADCSRA & (1 << ADSC));

        // do conversion 8 times for accuracy
        for(i=0;i<8;i++)
        {
                ADCSRA |= (1<<ADSC);

                // wait for conversion done flag
                while(ADCSRA & (1 << ADSC));

                // get result
                ADC_temp = ADCL;
                ADC_temp += (ADCH << 8);

                // accumulate results for averaging later
                ADCr += ADC_temp;
        }

        ADCr = ADCr >> 3; // average 8 samples

        cbi(ADCSRA, ADEN); // disable the ADC

    return ADCr;
}
Is the reading going to become more stable if I take more than 8 readings and average them? Do I need to enable and disable the ADC in this function as I have done, or can I leave it enabled?

What I took from your example and tried was on the PC program I take the last reading and the new reading and average them before displaying them. This seems to have smoothed the result quite a bit. I also discard any readings that are too different to get rid of the spikes that occur every now and then. I thought I would do it on the PC as it is much faster and I want the AVR to be able to poll it's sensors as fast as possible and just send raw data to the PC where it does all the calculations. Is this the right approach? Or should I let the AVR do the calculations?

I am wondering if my circuit would be improved with some sort of RC filter between the AVR and the accelerometer? And if so, how do I determine the best values for R and C?

Any advice will be a great help.
Chris_P is offline  
Old 26th July 2007, 11:27 PM   (permalink)
Default

Go on msn add seveprim@hotmail.com easier to talk then here
seveprim is offline  
Old 26th July 2007, 11:48 PM   (permalink)
Default

Um why arent you waiting for the coversion to complete ?

ie this line is wrong

while(ADCSRA & (1 << ADSC)); this is wrong !!!! you are not waiting for anything here this is the start conversion flag !!!

you should be checking the ADIF flag and clearing flag like the code i wrote !!!

while(!(ADCSRA&(0x01<<ADIF))){}; // wait for conversion to complete
ADCSRA|=(0x01<<ADIF); // AVR write one to clear flag
seveprim is offline  
Old 27th July 2007, 01:43 AM   (permalink)
Default

Quote:
Originally Posted by seveprim
Go on msn add seveprim@hotmail.com easier to talk then here


Um why arent you waiting for the coversion to complete ?

ie this line is wrong

while(ADCSRA & (1 << ADSC)); this is wrong !!!! you are not waiting for anything here this is the start conversion flag !!!

you should be checking the ADIF flag and clearing flag like the code i wrote !!!

while(!(ADCSRA&(0x01<<ADIF))){}; // wait for conversion to complete
ADCSRA|=(0x01<<ADIF); // AVR write one to clear flag
I do struggle understanding the details of a lot of code. I am not sure how I came about the code I posted, but I have used it for ADC for quite a while now and it seems to work OK. I just found this in the Atmega16 manual:-
Quote:
A single conversion is started by writing a logical one to the ADC Start Conversion bit, ADSC. This bit stays high as long as the conversion is in progress and will be cleared by hardware when the conversion is completed.
So my code was using Single Conversion mode and not Free Running mode. So I don't think it is outright wrong.

But then reading further it does talk about the ADC Interrupt Flag and constant sampling. So I will change it to use the ADIF. Thanks.

Last edited by Chris_P; 27th July 2007 at 06:41 AM.
Chris_P is offline  
Old 27th July 2007, 02:03 PM   (permalink)
Default

Quote:
Originally Posted by Chris_P
I do struggle understanding the details of a lot of code. I am not sure how I came about the code I posted, but I have used it for ADC for quite a while now and it seems to work OK. I just found this in the Atmega16 manual:-
So my code was using Single Conversion mode and not Free Running mode. So I don't think it is outright wrong.

But then reading further it does talk about the ADC Interrupt Flag and constant sampling. So I will change it to use the ADIF. Thanks.
No after reading the manual (atmega128) you code is correct you actually found a neater way of doing the same thing (waiting for conversion to complete) with my code it is basically same deal except I had to then clear the ADIF flag (wasted time ) so your code is correct and better !!! ( i am going to steal your mod lol )
seveprim is offline  
Old 27th July 2007, 02:12 PM   (permalink)
Default

Quote:
Originally Posted by Chris_P
I am wondering if my circuit would be improved with some sort of RC filter between the AVR and the accelerometer? And if so, how do I determine the best values for R and C?

Any advice will be a great help.
Sorry I missed this question earlier well the last time I used the ADXL202E from anolog devices it had two outputs(per axis) one was a PWM value derived from the analog voltage on a capacitor if memory serves me the larger the cap value the longer the sample time was on the chips internal timing (ie gave fewer internal samples to the averaging circuit but less noise) as for adding passives to the output of the chip I would say not to do that ... what chip are you using ?
seveprim is offline  
Old 27th July 2007, 02:39 PM   (permalink)
Default

Have you ever try to see the waveform of the input pin of the adc with a oscillatorscope when the accelerometer is stationary? the impedance of accelerometer is high so the designing of the pre-amplifier must be very carefully.

Another suggestion is try to power the circuit with batttery. if the noise disappeared, you'll have to re-design the circuit and the PCB.

Mike
ezpcb is offline  
Old 27th July 2007, 02:54 PM   (permalink)
Default

Quote:
Originally Posted by ezpcb
Have you ever try to see the waveform of the input pin of the adc with a oscillatorscope when the accelerometer is stationary? the impedance of accelerometer is high so the designing of the pre-amplifier must be very carefully.

Another suggestion is try to power the circuit with batttery. if the noise disappeared, you'll have to re-design the circuit and the PCB.

Mike

No one is using a pre amp nor do we want to introduce one as accelometers already do that for you.
seveprim is offline  
Old 27th July 2007, 10:27 PM   (permalink)
Default

Quote:
Originally Posted by seveprim
Sorry I missed this question earlier well the last time I used the ADXL202E from anolog devices it had two outputs(per axis) one was a PWM value derived from the analog voltage on a capacitor if memory serves me the larger the cap value the longer the sample time was on the chips internal timing (ie gave fewer internal samples to the averaging circuit but less noise) as for adding passives to the output of the chip I would say not to do that ... what chip are you using ?
I am using a Freescale MMA7260Q, and now that I go back and look at the schematic I see it already has RC filters on each axis. And I am powering it with batteries at the moment too, so I guess I have covered most of the noise problems. It is probably just the inaccuracy of the ADC causing the fluctuations. They are minor but I am using the readings to move a 3D object on my PC and it does shake continually even when it is stationary.

As far as Mike's suggestion of redesigning the pcb and circuit. The AVR is in an STK500 development board, the MMA7260Q is on a breakout board pcb but it is all connected through a breadboard. I guess this is all contributing to the noise problems.

Appreciate the advice though, I am learning all the time.
Chris_P is offline  
Old 28th July 2007, 12:40 PM   (permalink)
Default

You could work more on the software/firmware and look for more changes that relate to actual movement ie dont move the 3d object unless you see a reading with a difference of x because when you move an acceloromter you get an inital higher value until you hand accelation stops ( ie hand reaches top speed) can you post your ADC reading ie data sent to PC

from the freescale datasheet
2. Physical coupling distance of the accelerometer to
the microcontroller should be minimal.

I am wondering how far apart your lines are

3. Flag underneath package is connected to ground.

Make sure you got nice ground and did you use a star topology on the AVR ananlog ground pin ( look at data sheet ) to the freescale they should be isolated from the digital ground via a zero ohm link smt-0805

........................................... 0 ohm link smt -0805
AVR analog gnd________________/\/\/\_________________ gnd
Freescale gnd_______________/

Last edited by seveprim; 28th July 2007 at 12:56 PM.
seveprim is offline  
Old 29th July 2007, 10:31 PM   (permalink)
Default

Quote:
Originally Posted by seveprim
You could work more on the software/firmware and look for more changes that relate to actual movement ie dont move the 3d object unless you see a reading with a difference of x because when you move an acceloromter you get an inital higher value until you hand accelation stops ( ie hand reaches top speed) can you post your ADC reading ie data sent to PC
These are just the raw 10 bit adc values but from a stationary accelerometer I get readings like this:-
X - 450 454 450 447 450 452 451 453 450 447 452 454
Y - 541 540 538 544 534 542 541 538 541 539 541 541
Z - 781 781 785 779 780 780 779 781 781 783 779 784
Quote:
Originally Posted by seveprim
from the freescale datasheet
2. Physical coupling distance of the accelerometer to
the microcontroller should be minimal.

I am wondering how far apart your lines are
hmmm .. I missed reading that, my lines are way to far apart.
Quote:
Originally Posted by seveprim
3. Flag underneath package is connected to ground.

Make sure you got nice ground and did you use a star topology on the AVR ananlog ground pin ( look at data sheet ) to the freescale they should be isolated from the digital ground via a zero ohm link smt-0805

........................................... 0 ohm link smt -0805
AVR analog gnd________________/\/\/\_________________ gnd
Freescale gnd_______________/
I have not used a star topology as you suggested. I can't seem to find a reference to this in the data sheet. Which one mentions this, the AVR or the accelerometer?

I was trying to get nice smooth tilt and direction angles just using a 3 axis accelerometer and a 2 axis magnetometer, but I have since realised that the accelerometer can't really distinguish between tilt and directional movement so I think I need to incorporate a 2 axis gyroscope into my design. So I am not going to worry too much about improving this till I have the gyro. Then the fun will begin merging the data from the accel and gyro to give me accurate tilt angles independent of directional movement.
Chris_P is offline  
Old 30th July 2007, 06:16 AM   (permalink)
Default

Quote:
Originally Posted by Chris_P
I have not used a star topology as you suggested. I can't seem to find a reference to this in the data sheet. Which one mentions this, the AVR or the accelerometer?
No it is not mentioned in the Data sheets but I like to incorporate it in my designs a 2 cent resistor forces all the analog lines(using route software) to one pad and the other side digital GND stops alot of noise, you can even up the resistance a bit say to 10 ohms can help sometimes but it more the forcing the traces to one point on analog gnd path.
seveprim is offline  
Reply

Bookmarks

Thread Tools
Display Modes



Similar Threads
Title Starter Forum Replies Latest
Filters Choice? mo7mad General Electronics Chat 4 6th April 2006 02:50 PM
filters mstechca General Electronics Chat 3 27th May 2005 04:35 AM
Filters, plz help! elec123 General Electronics Chat 2 18th April 2005 07:18 PM
controlling band-pass filters aidanbre Micro Controllers 4 15th April 2003 08:32 AM
band pass filters aidanbre Electronic Projects Design/Ideas/Reviews 1 29th November 2002 07:43 AM



All times are GMT. The time now is 08:04 PM.


Electronic Circuits  |  Learning Electronics
Powered by vBulletin® Version 3.7.0
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.

eXTReMe Tracker