Eliminate ADC Jitter

Thread Starter

jwilk13

Joined Jun 15, 2011
228
I feel like I haven't been able to figure out anything recently, so alas, I am back to ask for more help.

I have another issue that popped up with some PIC18F45K20 programming, and I'm wondering if someone may be able to help. The code is for a PWM project that controls the brightness of two LED's. A standard 3-pin potentiometer is used to control the output duty cycle, but there's a twist: when the potentiometer is at center, there is no output; when the potentiometer is turned CW, PWM is output on RD5 and the LED lights up; when the potentiometer is turned CCW, PWM is output on RC2 and the other LED lights up.

This all works, except for one thing. I had to set up a "dead zone" in the potentiometer swing (slightly left and right of center) to avoid jitter in the outputs. When I turn the potentiometer I get variations in the ADC as follows:

0-450: RC2 output
451-574: Dead Zone, no output
575-1023: RD5 output

The problem is that I still get jitter at a certain point in the potentiometer swing because the ADC is going from say 448-452 rapidly between each instruction cycle, so the output "jitters" on and off, similar to button debouncing.

I've been pretty good at figuring stuff out with some simple suggestions from people, so maybe we can start there before I go posting a bunch of code. Has anyone encountered something similar, and if so, is there a method of fixing it? Thanks in advance :)
 

davebee

Joined Oct 22, 2008
540
It sounds like there is noise on the input. Why not also add hardware filtering, too; something as simple as a small series resistor followed by a capacitor to ground at the ADC input may eliminate much of the noise before the ADC even sees it.
 

Thread Starter

jwilk13

Joined Jun 15, 2011
228
Thanks dave. I thought the same thing and even just adding a 0.01 uF capacitor from the A/D input to ground helped quite a bit. There is still some jittering (i.e. PWM turning on and off rapidly), but I'm getting closer. I'm inclined to agree more with the noise theory now because when I run the debugger, every time I sample the A/D it returns the same value, which should mean that there should be no "jitter".

Thanks for the input, it's helping :)
 

eblc1388

Joined Nov 28, 2008
1,542
0-450: RC2 output
451-574: Dead Zone, no output
575-1023: RD5 output:)
Once there is output, change your goal post.

From centre(512): 450 - 0, RC2 output, change goal post to 460
Back to centre : output until 460, then no output
From centre(512): 575 - 1023 output, change goal post to 565
Back to centre : output until 565, then no output
 

Thread Starter

jwilk13

Joined Jun 15, 2011
228
Once there is output, change your goal post.

From centre(512): 450 - 0, RC2 output, change goal post to 460
Back to centre : output until 460, then no output
From centre(512): 575 - 1023 output, change goal post to 565
Back to centre : output until 565, then no output
Interesting idea, I'll give it a try. I ran into some other complications as well, but this might take care of those as well.
 

Thread Starter

jwilk13

Joined Jun 15, 2011
228
Worked like a charm. I'll have to make a note of this technique and pack it away for future use. Thanks.
 

eblc1388

Joined Nov 28, 2008
1,542
Glad to be of help. It is a technique we use everyday in electronics.

It is similar to hysteresis in voltage comparator.
 

Thread Starter

jwilk13

Joined Jun 15, 2011
228
Just an observation, with the "goal post" set at 460, there is still some on/off jitter. When that is changed to 470, however, it goes away completely. So apparently increasing the numerical distance between the two setpoints improves response? I'm not sure why yet, I just know it works based on some experimenting.
 

Thread Starter

jwilk13

Joined Jun 15, 2011
228
I don't know why I never realized this before, but I thank you guys for pointing it out. It's essentially the same concept as in a thermostat, where the past history is taken into account to avoid rapid switching of the output. Great info, thanks again.
 

Thread Starter

jwilk13

Joined Jun 15, 2011
228
As a piece of info for others who are looking to do something similar, if you are looking to eliminate chattering of an output from on to off, try something similar to the code below:

Rich (BB code):
unsigned int hysteresisValue = 10;
compareValue = 50;
				
if (duty_read < compareValue - hysteresisValue)
	set_bit(latd,3);
else if (duty_read > compareValue + hysteresisValue)
	clear_bit(latd,3);
The range of values being compared here is from 0-450 (ish), so the hysteresisValue variable is fairly large, however the concept is still the same.
 
Top