The Jitters

Greetings Everybody,

I would value your collective advice on a problem I'm having using a Sharp IR Proximity Detector as an analogue input in a midi controller project I'm working on. Quite simply, the reading obtained from the sensor on an analogue input is very 'jittery', which in turn is making the parameter controlled by it ( for example, midi control change 7) vary erratically. Any ideas?

Cheers

Any ideas on why it's jittery or any ideas on what to do about it?

Jitter is to be expected on a sensor like this. Just how much jitter are you seeing?

You can try to filter out the jitter, either electrically (RC filter is the simplest) or in software, using something simple like averaging N samples or a bit more highbrow like an IIR filter (there's an example IIR filter C++ class implementation in our Gadget Shield library code -- look at the Accelerometer demo).

--
Beat707: MIDI drum machine / sequencer / groove-box for Arduino

Thanks Rugged Circuits,

I can't give you exact figures for the amount of jitter as my midi gear is elsewhere at the moment. I was
asking what to do about it (the jitter), rather than what was causing it and having followed the kindly supplied links am now slightly more baffled than before. :astonished: I need to go now and force my head round some code, being a newcomer to this game (but a veteran midi dude) this may prove a challenge. RC filter, that seems more within my capabilities at the moment.

Do you perhaps know of a proximity sensor with a smoother/more stable output?

Thanks again.

Do you perhaps know of a proximity sensor with a smoother/more stable output?

No :slight_smile: It's an inherently noisy process given the hobbyist-level sensor and hobbyist-level cost of the sensor.

--
The Gadget Shield: accelerometer, RGB LED, IR transmit/receive, speaker, microphone, light sensor, potentiometer, pushbuttons

If you are confused by complicated code, I can offer a simple snippet that does really REALLY simple software based low-pass filtering

float x;

void loop()
{
  float oldValue = x;
  x = oldValue * 0.9 + analogRead(pinNumberGoesHere) * 0.1;
}

think for a minute and you'll realize what the math is doing. since a small bit of the new reading is mixed with a large bit of old readings, sudden changes (the jitter) will become suppressed. this makes a low-pass filter with software.

you can adjust 0.9 and 0.1 to change the cut-off frequency of the filter, which also depends on the loop frequency, make sure 0.9 and 0.1 adds up to 1 in the end or else it won't work.

Thanks, frank26080115.

I'll give that a go. Cheers.

I'd like to give Joe Pardue of Smiley Micros credit for me learning this, if you want a quick, dirty, and efficient way to input on your ADC with less jitter, do a bit shifting 3 bit trick as follows:

int thisval;
int total=0;

for ( int x=0; x<8; x++) //Inputs the value from pin (now variable a) in a for loop.

{
total += analogRead(xpin); //Compound addition operation
} //Equivalent to total = total + AnalogInput

thisval = total >> 3; //Averages the eight values the for loop added via bit shifting to smooth out sensor noise/inaccuracy, and thus also helps with digital debouncing. (false

//triggering if value is a level threshold measurement)

// There are a couple tricks here, first +=, which you can study on compound addition in the reference section, second, and less easy to grasp, is what's happening with: total >>3;
// Like I said before, here's where the savings starts. You get to do an average without doing floating point math. You shift the sum of eight numbers 3 bits over and you'll pretty much //end up with the average of the eight and bit shifting is easier on a microprocessor than floating point math. These efficiency savings add up, even though my program worked fine while I //was doing an average of three numbers.

dshay:
I'd like to give Joe Pardue of Smiley Micros credit for me learning this, if you want a quick, dirty, and efficient way to input on your ADC with less jitter, do a bit shifting 3 bit trick as follows:

int thisval;
int total=0;

for ( int x=0; x<8; x++) //Inputs the value from pin (now variable a) in a for loop.

{
total += analogRead(xpin); //Compound addition operation
} //Equivalent to total = total + AnalogInput

thisval = total >> 3; //Averages the eight values the for loop added via bit shifting to smooth out sensor noise/inaccuracy, and thus also helps with digital debouncing. (false

//triggering if value is a level threshold measurement)

// There are a couple tricks here, first +=, which you can study on compound addition in the reference section, second, and less easy to grasp, is what's happening with: total >>3;
// Like I said before, here's where the savings starts. You get to do an average without doing floating point math. You shift the sum of eight numbers 3 bits over and you'll pretty much //end up with the average of the eight and bit shifting is easier on a microprocessor than floating point math. These efficiency savings add up, even though my program worked fine while I //was doing an average of three numbers.

This method is expensive time-wise during 8 consecutive calls to analogRead

You can also keep the 8 previous samples in a buffer and only execute analogRead once per iteration instead of 8, much faster at the cost of more memory for the buffer.

frank26080115:
This method is expensive time-wise during 8 consecutive calls to analogRead

You can also keep the 8 previous samples in a buffer and only execute analogRead once per iteration instead of 8, much faster at the cost of more memory for the buffer.

If concern for time is an overriding factor the greatest time hog will be sensor noise/bounce being transmitted at a serial baud rate of 32150 constantly, a debounce function would also help,
but even then the project would keep transmitting at a duty cycle of whatever the debounce length is.

Musical projects need control and repeatability. With light sensing you'd need an average of as many readings as you can get away with before lag and if it's only one sensor eight readings definitely isn't a problem, and also, one could create the buffer array you speak of to save on time.

Take Reading

Reading different than last?

Send Controller Change Message.

Without doing a good amount of averaging change messages would be sent repeatedly, even when nothing is being sensed or the musician is holding perfectly still.

Although by analysis .1(current reading) + .9(last value) is pretty close to the average of eight. Each multiplication in that equation takes up one operation cycle. If I knew how to simulate in AVR studio I could analyze this. I'm going to get on that one of these days.

I think I like your method better come to think of it but mine works on my current project.