0

Hi All i am working on a project where I have to calculate the moving average of ADC readings. The data coming out from ADC represent an Sinusoidal wave.

This is the code I am using to get moving average of a given signal.

longNew = (8 bit data from ADC);
longNew = longNew << 8;
//Division
longNew = longNew >> 8;    //255 Samples
longTemp = avgALong >> 8;

avgALong -= longTemp;// Old data 
avgALong += longNew;// New Data

avgA = avgALong >> 8;//256 Point Average

enter image description here

Reference Image

Reference Image

Please refer this image for upper limit and lower limit relative to reference (or avgA)

Currently I am using a constant value to obtain the upper limit and lower limit of voltage for my application which I am calculating as follows

upper_limit = avgA + Delta(x); lower_limit = avgA - Delta(x);

In my case I am taking Delta(x) = 15.

I want to calculate this constant expression or Delta(x) based on signal strength. The maximum voltage level of signal is 255 or 5Volt. The minimum voltage level of signal varies frequently because of that a constant value is not useful for my application which determines the lower and upper limit.

Please help

Thank you

Jonnus
  • 2,988
  • 2
  • 24
  • 33
Kunal Sonone
  • 43
  • 3
  • 14
  • 1
    It's not clear what your question - problem is. And I don't follow `longNew = longNew << 8; longNew = longNew >> 8;` – Weather Vane Oct 26 '15 at 18:42
  • to remove the upper 8 bits from the variable. – Kunal Sonone Oct 26 '15 at 18:44
  • Why do you need to remove the upper bits from an 8-bit variable? – Weather Vane Oct 26 '15 at 18:47
  • There are various ways of filtering a rolling average, they vary with their response characteristics. Some "unstick" slowly, and converge quickly, etc. Did you try some simple searching such as https://en.wikipedia.org/wiki/Moving_average ? – Weather Vane Oct 26 '15 at 18:47
  • I have uploaded one image here. Please refer the image. Currently, I am able to calculate the average based on following method. I am using constant value 15 to calculate upper and lower limit. Now I want to calculate this constant which can change based on signals minimum and maximum value. – Kunal Sonone Oct 26 '15 at 18:55
  • @ Weather Vane I am declaring the long variable which is not initialized. To remove any unwanted bits I am shifting it. – Kunal Sonone Oct 26 '15 at 18:58
  • Why didn't you just initialise it? – Weather Vane Oct 26 '15 at 19:15
  • I agree with your point but the code which I have got to work on declares the unsigned long variables but never initialize it to some value. And as the value from adc is 10 bit, to remove the bit 9 and 10 shifting is done (to obtain 0-255 range). – Kunal Sonone Oct 26 '15 at 19:27
  • You can't force a 10-bit value to an 8-bit value just by removing the upper bits. You must **scale** the ADC input conversion counter (for that is what it is) to your actual range. – Weather Vane Oct 26 '15 at 19:38
  • when you adc saturates at 255, it's more like a hardware problem. you need to increase the reference voltage on the adc, or decrease the signal. you signal also have a high DC offset, which limits your AC dynamic range a lot. – user3528438 Oct 26 '15 at 19:40
  • 2
    If the ADC output is 10 bits, using only the lower 8 bits will not do what you want. If you want an 8-bit average, mask off the upper 6 bits (AND with 0xFC00) then downshift by 2. And masking the upper 8 bits by shifting up then down is both slower than and-ing the data with 0xFF00, it's also not portable, since doing that on a 32-bit system will do absolutely nothing. – Erik Johnson Oct 26 '15 at 19:45
  • what could be the solution regarding the lower limit calculation. The variation in lower signal is more frequent and uneven. – Kunal Sonone Oct 26 '15 at 19:57
  • I'm sorry, I'm still confused as to what you're trying to do, particularly what "lower limit" and "upper limit" are supposed to represent. In your reference image (http://i.stack.imgur.com/d1Hld.jpg) is that your expected output given the input (which I assume is the oscillating blue-ish line that clips)? if not, could you provide us an image with your expected results? – Russ Schultz Oct 27 '15 at 02:31
  • The image i have posted is the final result what I am getting after calculating the Moving average. Upper and lower limit of voltage is calculated by this formula : upper_limit = avg + Delta(x), and lower_limit = avg - Delta(x). To implement this I am assuming Delta(x) as 15. But for flexibility I want to calculate the value of Delta(x) as the signal is acquired. – Kunal Sonone Oct 27 '15 at 19:26
  • I am not sure how Delta(x) can be calculated? The highest value from adc is 255 but the lowest signal always vary which makes it difficult to hard code Delta(x) value. I want to design a system where Delta(x) is function of variation in max and min val of signal. – Kunal Sonone Oct 27 '15 at 19:35
  • I must be dense because it still doesn't make sense to me. What do you WANT `upper_limit` and `lower_limit` to represent, based on the data? The minimum/maximum value of the entire data set? The envelope of the input? We can't help you come up with how to calculate Delta(x) if we don't know what it's supposed to represent. – Russ Schultz Oct 28 '15 at 00:26
  • I am using an optical sensor and to design an encoder I do need a proper digital signal to distinguish holes and tap detected by Tx-Rx pair. And to convert the analog output to an digital pulse I want to implement a voltage comparator. Upper and lower limit defines the threshold for 1's and 0's. – Kunal Sonone Oct 28 '15 at 11:50

1 Answers1

1

Now with the description of what's going on, I think you want three running averages:

  1. The input signal. Lightly average it to help tamp down noise.
  2. upper_limit When you determine local maximums, push them into this average.
  3. lower_limit When you determine local minimums, push them into this average.

Your delta would be (upper_limit-lower_limit)/8 (or 4, or whatever). Your hysteresis points would be upper_limit - delta and lower_limit + delta.

Every time you transition to '1', push the current local minimum into the lower_limit moving average and then begin searching for a new local maximum. When you transition to '0', push the local maximum into the upper_limit moving average and begin searching for a new local minimum.

There is a problem if your signal strength is wildly varying (you could get to a point where your signal suddenly drops into the hysteresis band and you never get any more transitions). You could solve this a few ways:

  1. Count how much time you spend in the hysteresis band and reset everything if you spend too much time.

Or

  1. for each sample in the hysteresis band, bring upper_limit and lower_limit slightly closer together. Eventually they'd collapse to the point where you start detecting transitions again.

Take this with a grain of salt. If you're doing this for a school project, it almost certainly wont match whatever scholarly method your professor is looking for.

Russ Schultz
  • 2,545
  • 20
  • 22
  • I have implemented this functionality on my system. it is working fine now. But, now i am running in to one another problem. I want to lock the value of Delta. As my system is depend on the motion of tap with respect to optical sensor. As tap moves the average of signal starts either from Maximum value(255) , Minimum value (0) or in between these range based on tap position. As my system rest value of Delta(x) becomes 0. – Kunal Sonone Oct 30 '15 at 20:31
  • Now, if I have to detect the holes and tap first I have to run the tap for few seconds and then I can start getting 1's and 0's( hole or tap). In this case my system is not reliable and I do need to move tap all the time before it gives me right results. Now I am trying to save the value of Delta when system is running and then once it restarted I want to use previous values of Delta so I don't need to move the tap again to make t work. I am trying hard from last two days but still not able to figure out solution. Please advice – Kunal Sonone Oct 30 '15 at 20:38
  • you're either averaging too many samples together, or not sampling quick enough. At this point, you need to put your budding engineering mind together and come up with a solution. Or ask your TA. – Russ Schultz Oct 30 '15 at 20:45