CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

AD Digital Filter
Goto page 1, 2, 3, 4, 5  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
viki2000



Joined: 08 May 2013
Posts: 233

View user's profile Send private message

AD Digital Filter
PostPosted: Wed Mar 19, 2014 7:34 am     Reply with quote

Hi,

I use the AD internal converter to read the AC voltage in one point of the sinus, each time at 3ms after ZC (Zero Cross) detection. I use a simple voltage divider with 2 resistors to obtain the proper voltage at input of the PIC.
Due to many possible errors as: tolerance in resistors, moment of ZC detection, small instability in the power of PIC, the AD accuracy…I do not get always the same number as result of AD conversion.
I read the sinus several times to reduce the error, each time in the same point. I do it 8 times, but can be also 10 times.
The numbers that I get look like: 55, 47, 48, 47, 47, 46, 47, 46.
Then, up to now I used the average to get the result.
Sometimes I get very close numbers, and the best precision seems n-1, n, n+1, as 46, 47, 48, but other times I get a too far away reading, as 55 above. Then the average is affected.
I realized that would be probably better to do it different.
For example to eliminate the number which are too far (high or low) from the rest which are concentrated around one value with +/-1 digit.
Then instead of average, maybe is better just to choose which number appear more often than other numbers and to choose that one as end result.

Any idea how can be such filter implemented in C or pseudo code, having in mind that the code should be as small as possible?
The PIC used is PIC10F322.


Last edited by viki2000 on Wed Mar 19, 2014 7:54 am; edited 1 time in total
clarence



Joined: 18 Mar 2014
Posts: 4

View user's profile Send private message

PostPosted: Wed Mar 19, 2014 7:43 am     Reply with quote

AV=AVold + K*(Avold - reading);
AVold =AV;

K between 0 and 1 ( not inclusive of limits ie not exactly zero or one)

small K is more filtering, large K is less.

K = 1 is no filtering at all.

the output is AV and filtered result.
viki2000



Joined: 08 May 2013
Posts: 233

View user's profile Send private message

PostPosted: Wed Mar 19, 2014 7:52 am     Reply with quote

Thank you for the quick reply.
I forgot something.
I would like to stay away of float numbers due to low computation possibilities of the PIC10F322.
If I understand right, your K is between 0 and 1, which means a decimal real number which is not good for this case.
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Wed Mar 19, 2014 8:02 am     Reply with quote

http://www.ccsinfo.com/forum/viewtopic.php?t=50320


Try that out...
Maybe a bit slow for you.

G.
_________________
CCS PCM 5.078 & CCS PCH 5.093
stinky



Joined: 05 Mar 2012
Posts: 99
Location: Central Illinois

View user's profile Send private message

PostPosted: Wed Mar 19, 2014 8:12 am     Reply with quote

Gabriel wrote:
http://www.ccsinfo.com/forum/viewtopic.php?t=50320

+1.
ASMBOY's routine works well and has helped me circumvent noise from a switching supply. Compiled it for a 10LF322 Version 4.141. 60%
clarence



Joined: 18 Mar 2014
Posts: 4

View user's profile Send private message

PostPosted: Wed Mar 19, 2014 8:20 am     Reply with quote

K = 0.5 then just shift right one place.

or use fixed point like 8.8

also consider a median filter.

The last three values are buffered and the output is always the middle value in the three long buffer. This rejects noisy spike type interference.
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Wed Mar 19, 2014 8:32 am     Reply with quote

also re: clarence excellent illustration,
when K is a power of 2 - the shift instr. is your friend Very Happy Very Happy Very Happy

remember the key drawback to olympic averages is also it's strength-
long term averaging -for low noise - but also greater uncertainty about the instantaneous value. all depends on what you need for your app to work as you need. if you need to make decisions closer to the moment of reading any one sample - clarence method is better- but the absolute running average will always have a greater error bar /n samples per reading.
clarence



Joined: 18 Mar 2014
Posts: 4

View user's profile Send private message

PostPosted: Wed Mar 19, 2014 8:46 am     Reply with quote

I need to clarify the median filter.

The selected output is the value that is between the hi and lo value in the buffer, not anything to do with the index into the buffer.
Ttelmah



Joined: 11 Mar 2010
Posts: 19539

View user's profile Send private message

PostPosted: Wed Mar 19, 2014 8:47 am     Reply with quote

Critical thing is understanding the nature of the noise, which then allows much better smoothing to be designed.
Choices are (amongst others...):
Simple mean.
Olympic averaging.
Things like moving averaging.

Now all can potentially be done using integer arithmetic (using 32 bit values for the rolling sum if used, and binary division factors). Olympic averaging is superb, if you have single erroneous samples amongst otherwise 'good' data.
The simple mean, is good if the primary noise is something like Gaussian.
The moving average is very useful at showing long term trends (commonly used in financial analysis). Interestingly a simple version of the exponential form of this is easy to calculate, while updating on a 'per sample' basis without having to maintain a large number of samples for summing (Clarence's post is a simple form of this).

It all depends on the nature of your noise, and how fast you need it to update, together with how fast you are sampling, and the available storage etc..

Now for you the environment will affect things. Classic things causing problems are TRIAC controls on the line, which will commonly cause spike noise at a point moving in the cycle. For this the link to the Olympic sort is a good way to start.
If the noise is more random, and the trend required is always long term, than consider the moving exponential average instead.

Separately, are you sure the main fault is with the value being read?. Remember that if you are using the supply rail as your Vref, noise on _this_ will appear as errors in the result...
temtronic



Joined: 01 Jul 2010
Posts: 9243
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Mar 19, 2014 9:32 am     Reply with quote

hmm... you say ALL you have is a voltage divider to measure the AC voltage??
If so that's very, very bad hardware as the PIC's ADC is 'unipolar', meaning it only measures +ve DC voltages. During the negative swing, that -AC voltage will put undue stress on the ADC section. Worst case...blow up the PIC, best case...cause erratic readings.

Also you don't say what level the 'AC' is, but if 'mains' level (120v,240v,347v, 550v) be very, very careful about properly isolating it from the PIC and YOU !!

hth
Jay
gpsmikey



Joined: 16 Nov 2010
Posts: 588
Location: Kirkland, WA

View user's profile Send private message

PostPosted: Wed Mar 19, 2014 11:03 am     Reply with quote

One issue that has sort of been skipped over is there are two parts to this problem - the first is the noise, the second is averaging or some other means to "smooth" the result. Your first priority should be to get the signal as clean as possible to start with (the old "garbage in - garbage out" applies here). Once you have as clean as possible a signal you want to measure, then you can worry about averaging etc. to get the type of reading you need.

Also as pointed out, if you are not isolated from the mains and don't have a very good reason for not having isolation, you NEED to add isolation. Mains can fry you and your circuit (it is not good to let the "magic smoke" out of your circuit ..... or YOU )

mikey
_________________
mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3
viki2000



Joined: 08 May 2013
Posts: 233

View user's profile Send private message

PostPosted: Wed Mar 19, 2014 2:29 pm     Reply with quote

I do not need isolation, It must be without. The application requires so.
Don't worry about AC negative alternation, I use a rectifier bridge, so I get only positive voltage.
Don't worry about these aspects. I cannot improve the external hardware to make the signal cleaner. I cannot add more components.
I have to do it only software as suggested above, eventually improved.

The olympic code is nice, but might be too big, I already have 70% code in the PIC10F322.
I tried to apply the formula suggested by "clarence", but I miss something or I am too tired now.
Just look at the Excel file from link below. The result is not good, something is wrong.
https://drive.google.com/file/d/0BwXmKaSw75eKWTk2OE9QWld6Qzg/edit?usp=sharing
viki2000



Joined: 08 May 2013
Posts: 233

View user's profile Send private message

PostPosted: Thu Mar 20, 2014 9:36 am     Reply with quote

The silence about the Excel file does not sound good to me...
Today I tried the olympic code with some small adjustments for my PIC10F322.
When I compile the code as it is using compiler version 4.140, I get 35%Flash and 73%RAM memory used.
The PIC10F322 has only 8 bit the AD, so the variables used can be smaller size.
Then, I sample only 8 times the signal, not 16 times. And I eliminate the 2 lower values and 2 higher values and remain with 4 good values in the middle of the array.
Compiling such "adjusted" code takes only 23%Flash and 31%RAM memory.

As I already use some variables in the program, the code takes even less for me. I am somewhere at 85% Flash and 50%RAM and can be still optimized to be less (the entire code), but for the moment the tests gave good results with the olympic code below:
Code:

// olympic++  adc de-noising routine for 8 bit ADC values for PIC10F322
// NOTE: you must have selected the desired ADC channel before calling
// reads 8x , sorts and tosses low 2 && high 2 readings
// then averages the middle 4

unsigned int8 adchlx(void){  // read 8 - sort, keep middle 4 average

 unsigned int8 i;  unsigned int16 accum=0;
 unsigned int8 s, b[8]; int1 didswap=1;

   for ( i = 0 ; i < 8;  i++ ) {
           b[i]= read_adc(ADC_start_and_read); // ADC set for 8 bits
           delay_us(8);
     } //    end of for loop for multi sample
   while(didswap){  // bubble sort
     didswap=0;
     for (i=0; i<7; i++){ // i 0-7
      if(b[(i)]>b[(i+1)]){ // if low element greater than next  -do  swap
           s=b[i]; // hold upper
           b[i]=b[(1+i)];
           b[(1+i)]=s;
           didswap=1;
      } // ~if
     } // ~for
    } // ~while
   // now sort and keep middle 4 values
   for (i=3; i<7; i++){  accum +=b[i];  }
   return(accum>>2);
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19539

View user's profile Send private message

PostPosted: Thu Mar 20, 2014 10:17 am     Reply with quote

'Rectifier bridge', implies there will be around 0.6v of droop at all points on the incoming waveform. Measuring a small interval after the zero crossing, with a voltage divider, means you will be largely 'in' the area comprising the droop....
viki2000



Joined: 08 May 2013
Posts: 233

View user's profile Send private message

PostPosted: Thu Mar 20, 2014 11:16 am     Reply with quote

I am not sure I get it. Could you please explain with more details?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2, 3, 4, 5  Next
Page 1 of 5

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group