Arduino: smoothing series of numbers
So I have my Arduino, running a slightly modified Arduino2Max and reading the analog pins from a potentiometer. I can get the numbers into Max no problem, but there's some jitter when the pot is still (fluctuating up and down about 5 values).
I'd like to smooth those out to get an average. I tried using peak, which works great for numbers going up, but not down.
The mean object works, but when ramping up or down it takes those into the equation.
Any help would be appreciated. This seems like there must be a very simple solution.
Thanks!
Jeff
The most reliable method I found when I experienced the same problem was
just dividing the input in order to limit the range. There may be a better
solution out there, but this is probably the most simple. Might also be
worth dividing the signal at the arduino side if you want to save CPU
cycles.
On 14/03/2008, Jeff Thompson wrote:
>
>
> So I have my Arduino, running a slightly modified Arduino2Max and reading
> the analog pins from a potentiometer. I can get the numbers into Max no
> problem, but there's some jitter when the pot is still (fluctuating up and
> down about 5 values).
>
> I'd like to smooth those out to get an average. I tried using peak, which
> works great for numbers going up, but not down.
>
> The mean object works, but when ramping up or down it takes those into the
> equation.
>
> Any help would be appreciated. This seems like there must be a very
> simple solution.
>
> Thanks!
>
> Jeff
>
You could just smooth them over a short time span using [line] or
[line] depending on your needs. This will compromise the
responsiveness slightly, but you can tweak it for the optimum
tradeoff. I use something like the attached patch for a number of
uses, mostly for smoothing out discontinuities in incoming data, but
it might serve your purposes, as well. Alternatively you could use
something like [past] to create an auto-adjustable threshold for
accepting input if it exceeds the amplitude of the input jitter.
Perhaps some combination of the two might work even better?
save as control-smooth.mxb:
save as control-smooth.help
On Mar 14, 2008, at 12:49 PM, Jeff Thompson wrote:
>
> So I have my Arduino, running a slightly modified Arduino2Max and
> reading the analog pins from a potentiometer. I can get the
> numbers into Max no problem, but there's some jitter when the pot
> is still (fluctuating up and down about 5 values).
>
> I'd like to smooth those out to get an average. I tried using
> peak, which works great for numbers going up, but not down.
>
> The mean object works, but when ramping up or down it takes those
> into the equation.
>
> Any help would be appreciated. This seems like there must be a
> very simple solution.
----
Steven M. Miller
Professor, Contemporary Music Program
College of Santa Fe
Home
SFIFEM
Atrium Sound Space
OVOS
CMP
hi jeff,
have a look at the slide object. dividing will not solve the
unsteadiness, just shift it to another level. doing additional
computation on your arduino is also not necessary, since your computer
is about 100 times faster as your arduino.
marius.
marius.
Joe Bicker wrote:
> The most reliable method I found when I experienced the same problem was
> just dividing the input in order to limit the range. There may be a better
> solution out there, but this is probably the most simple. Might also be
> worth dividing the signal at the arduino side if you want to save CPU
> cycles.
>
> On 14/03/2008, Jeff Thompson wrote:
>>
>> So I have my Arduino, running a slightly modified Arduino2Max and reading
>> the analog pins from a potentiometer. I can get the numbers into Max no
>> problem, but there's some jitter when the pot is still (fluctuating up and
>> down about 5 values).
>>
>> I'd like to smooth those out to get an average. I tried using peak, which
>> works great for numbers going up, but not down.
>>
>> The mean object works, but when ramping up or down it takes those into the
>> equation.
>>
>> Any help would be appreciated. This seems like there must be a very
>> simple solution.
>>
>> Thanks!
>>
>> Jeff
>>
>
>
> ------------------------------------------------------------------------
>
Quote: mail@jeffreythompson.org wrote on Fri, 14 March 2008 11:49
----------------------------------------------------
> So I have my Arduino, running a slightly modified Arduino2Max and reading the analog pins from a potentiometer. I can get the numbers into Max no problem, but there's some jitter when the pot is still (fluctuating up and down about 5 values).
>
> I'd like to smooth those out to get an average. I tried using peak, which works great for numbers going up, but not down.
>
> The mean object works, but when ramping up or down it takes those into the equation.
>
> Any help would be appreciated. This seems like there must be a very simple solution.
>
> Thanks!
>
> Jeff
----------------------------------------------------
I made a one-pole lowpass filter for this kind of thing. In the CNMAT MMJ Depot here:
mz
Thanks for all the responses. I've tried the smooth object, which seems to essentially ramp numbers.
It reduces the jitter when set high enough, but then reduces the speed with which I can actually change numbers (it ramps slowly up and down).
I'm trying to think of a way to add a threshold to the smooth object, where it will perform a high level of smoothing until the change is greater than, say 8, and then it shuts off.
I can't patch it up right now, but I was thinking that perhaps some
way of changing the control input to [slide] based on the magnitude
of the difference between successive input data.
some sort of looping algorithm:
subtract current input from previous input
take absolute value
scale result to desired range
use output from scaling operation to set [slide] control
send current input through [slide] to output
store current input as previous
start loop again
That way the (presumably) small magnitude of the jitter gets filtered
but the larger magnitude 'real' input does not.
Just an idea...
On Mar 16, 2008, at 9:10 AM, Jeff Thompson wrote:
>
> Thanks for all the responses. I've tried the smooth object, which
> seems to essentially ramp numbers.
>
> It reduces the jitter when set high enough, but then reduces the
> speed with which I can actually change numbers (it ramps slowly up
> and down).
>
> I'm trying to think of a way to add a threshold to the smooth
> object, where it will perform a high level of smoothing until the
> change is greater than, say 8, and then it shuts off.
----
Steven M. Miller
Professor, Contemporary Music Program
College of Santa Fe
Home
SFIFEM
Atrium Sound Space
OVOS
CMP
Here you go Jeff. Is this what you had in mind?
Zachary
And here's a javascript way to do it.
Zachary
Here's the max patch:
save this as pathEasing.js
//Smooth out mouse movements
var mouse;
var mouseEase = 0;
var easing = 0.1;
var minDist = 0.1;
if (jsarguments.length>1)
easing = jsarguments[1];
minDist = jsarguments[2];
function bang()
{
outlet(0,mouseEase);
}
function msg_float(v1)
{
mouse = v1;
var distance = mouse - mouseEase;
if (Math.abs(distance) < minDist)
{
mouseEase += distance * easing;
}
else
mouseEase = mouse;
bang();
}
function setEasing(v) // set easing amount (0.01 will ease more than 0.9)
{
easing = v;
}
function setMinDist(d) // set minimum distance
{
minDist = d;
}
Thanks, Zach. Sorry - I don't know how to use the Javascript patch. Do I copy.paste it like a Max patch?
The problem with the Max one you made is that the sensitivity when making intentional transitions is still low. If I adjust the numbers quickly it still takes a while to reach the peak.
I know this is a Max forum, not an electronics one, but maybe this is a problem better solved through hardware?
Quote: mail@jeffreythompson.org wrote on Mon, 17 March 2008 20:04
----------------------------------------------------
> I know this is a Max forum, not an electronics one, but maybe this is a problem better solved through hardware?
----------------------------------------------------
Hey there. I don't know if this is any help but I made something similar using a different micro-controller and experienced similar problems. It turned out the problem was one of the batteries I was using to power the device was dying and replacing all the batteries gave me a stable output. Hope that helps.
-Theo
Another possible cause is the sensors themselves. I know that some
companies (for example Electrotap) do some on-sensor conditioning to
reduce jitter, etc. You might look into physical computing type
website for info on debouncing and other sensor conditioning
techniques you can use.
On Mar 18, 2008, at 12:56 PM, Theo wrote:
>
> Quote: mail@jeffreythompson.org wrote on Mon, 17 March 2008 20:04
> ----------------------------------------------------
>> I know this is a Max forum, not an electronics one, but maybe this
>> is a problem better solved through hardware?
> ----------------------------------------------------
>
> Hey there. I don't know if this is any help but I made something
> similar using a different micro-controller and experienced similar
> problems. It turned out the problem was one of the batteries I was
> using to power the device was dying and replacing all the batteries
> gave me a stable output. Hope that helps.
----
Steven M. Miller
Professor, Contemporary Music Program
College of Santa Fe
Home
SFIFEM
Atrium Sound Space
OVOS
CMP
Thanks, those are good suggestions.
I'm powering the Arduino from USB, so I should try an external source too.
Not finding much on conditioning the signal through hardware, and since this isn't really the forum for that, I'll post the question on the Arduino site.
Another type of filter that can be very effective in signal
conditioning is a median filter. It is more expensive computationally
than a running average, but has the very nice feature of not being
tweaked by a few erroneous spikes.
Peter McCulloch
Hi Jeff,
For the javascript file, save it pathEasing.js and put the file in the same folder as the max patch (posted above).
Those posts do what you asked about in your earlier post:
"I'm trying to think of a way to add a threshold to the smooth object, where it will perform a high level of smoothing until the change is greater than, say 8, and then it shuts off."
Can you give a little more info about the numbers coming in? What's the range? What are the fluctations when the sensor is at rest?
Zachary
This look pretty interesting, thanks for the tip. Has anybody
implemented one of these as a Max and/or MSP external? There's a link
to a C implementation (GPL license) at the bottom of the Wikipedia
page . Failing that, how
about a Java implementation?
On Mar 18, 2008, at 8:47 PM, Peter McCulloch wrote:
> Another type of filter that can be very effective in signal
> conditioning is a median filter. It is more expensive
> computationally than a running average, but has the very nice
> feature of not being tweaked by a few erroneous spikes.
----
Steven M. Miller
Professor, Contemporary Music Program
College of Santa Fe
Home
SFIFEM
Atrium Sound Space
OVOS
CMP
Thanks Zach, I should be able to try that tonight and see if it works.
The numbers range from 0-1025 (10 bit digital conversion). The fluctuation, when at rest, is about 5-8 up and down.
Someone on the Arduino forum suggested a few hardware changes, which I hope to try soon and see if they solve the problem.
Here's a simple abstraction solution, though Emmanuel Jordan's
external would be faster. Use bucket, etc. to create your running
lists going into it. Nice to know about zl!
Also, I've included PM.Zones, which is a patch that classifies an
input into various zones specified in the right inlet.
Peter McCulloch
PM.Median:
PM.Zones:
On 19 Mar 2008, at 17:53, Steven Miller wrote:
> This look pretty interesting, thanks for the tip. Has anybody
> implemented one of these as a Max and/or MSP external?
in addition to what has been proposed already, you can find a c
external here:
osx only.
filters float or int data streams.
volker
I have the same issue. In the Arduino I divide (actually bitshift) by 4, so it's only 8-bit, but that's enough resolution. This helps. Then I also don't let any values out unless they change by two or more (store temp variable, compare, etc.) This also helps. But the jitter remains... so... depends on what you're going to do with it, it may not be an issue, then again it might be a deal-breaker...
After you get these values into Max, you might be able to apply some of the additional filtering discussed here. This is just a way to clean it up before it gets there.
It certainly makes me respect commercial MIDI controllers, whose knobs and sliders don't have this issue.
--CJ
It is helpful to try to eradicate these issues at the hardware/chip
level. First, make sure you have a stable power supply for the ADC.
USB power can be pretty noisy. You might also experiment with using a
different power supply for your sensors than the board.
If you have MCU cycles to spare, you can try doing over-sampling and
decimation to get more stable and precise ADC results. There is an AVR
application note here that explains the theory behind this technique:
http://atmel.com/dyn/resources/prod_documents/doc8003.pdf
I used this for an AVR-based analog infrared ranger project and found it
to help tremendously.
Also, try some different pots. Some pots are noisier than others.
Best of luck,
Andrew B.
andrew, thanks for the info, fact is i'm struggling right now with the sharp
ir range finder jitter. its responsiveness is nice (surgeon general warning,
watch out for light sources that generate competing infra light, like hot
lights and sun).
back to topic, most the oversampling rutine reside on the controller
(arduino)?
from reading the pdf i cant understand whats the difference between what
they write in p. 5 and normal window average. the writer clearly
distinguishes between the two but the math looks to give the same output.
normal average (collect 16 samples > sum > divide by 16)
oversample (collect 16 samples > sum > right bit shift by 2 > divide by 4)
http://tinyurl.com/2jlqrg (googlecode search for oversampling resualt)
On Mon, Mar 24, 2008 at 8:15 PM, Andrew Benson
wrote:
> It is helpful to try to eradicate these issues at the hardware/chip
> level. First, make sure you have a stable power supply for the ADC.
> USB power can be pretty noisy. You might also experiment with using a
> different power supply for your sensors than the board.
> If you have MCU cycles to spare, you can try doing over-sampling and
> decimation to get more stable and precise ADC results. There is an AVR
> application note here that explains the theory behind this technique:
> http://atmel.com/dyn/resources/prod_documents/doc8003.pdf
> I used this for an AVR-based analog infrared ranger project and found it
> to help tremendously.
>
> Also, try some different pots. Some pots are noisier than others.
>
> Best of luck,
> Andrew B.
>
>
>
With averaging, you are maintaining the same bit precision. The idea
here is to improve the bit-precision of your ADC samples while trying to
eliminate errors from noise. This is super useful for the Sharp IR
rangers because they have a high-impedance and non-linear response, so
you will lose some accuracy in certain ranges unless you can find a way
to upsample. The right-shifting is there to counteract the inaccuracy
that would build up from taking subsequent samples with 1-bit of
inaccuracy each.
The reason for keeping this on the MCU is that it is often
computationally more efficient to do several samples and some
bit-shifting on the board than it is to send 16 10-bit values over
serial and try to do it in MaxMSP just as fast.
The design I was working on was for a standalone embedded object
anyways, so I had to do all my signal-conditioning on-chip/board. If
you are working with the Sharp sensors, I would also highly recommend
using a buffer op-amp, and maybe even scaling the signal a little bit to
take full advantage of your ADC resolution. There is a great tutorial
on op-amp sensor conditioning circuits on the Electrotap website.
Best of luck,
Andrew
Yair,
BTW, that code you linked to just does an averaging of several samples.
For a better demonstration of the oversampling/decimation method,
download the example code for the application note here:
http://atmel.com/dyn/products/app_notes.asp?family_id=607
(AVR121)
Best,
Andrew B.
thanks Andrew,
if any one is interested, here is an example of a the raw output from the sharp range sensor.
in this the sensor start idle then the beam is broken by a hand, two range changes then beam unbroken and some more idle time.
Thanks for all the great feedback, I really appreciate it!
I think I came up with a solution that I'm actually really happy with, though after hours and hours of wrangling.
I ended up using the peak and trough objects and used their value to prevent fluctuations back down or up depending on direction of rotation.
The patch, below, scales the data 1-127, 0-1, and degrees of rotation.