Choice of capacitor to remove 50Hz hum - Page 1
Forum section: electronics / projects

author: robzy
author_rank: Regular Contributor
timestamp: December 30, 2021, 12:23:10 pm
content: Hi everyone, I've attached a schematic of how I've connected a potentiometer to an Arduino - the problem is that I get 50Hz hum on the arduino pins when I happen to touch the pins of the potentiometer.I want to put a capacitor on the Arduino pin to cancel out the 50Hz noise. The pot isn't used for super-duper real-time readings, so I don't care too much about eating into the response rate nor the phase shift.My question, what value of capacitor (C1) should I use to get rid of the 50Hz hum?I'm sure that this is pretty much a lowpass RC filter, but what is the implicit value of R that I should be using in the calculations?Thanks in advance!

author: NiHaoMike
author_rank: Super Contributor
timestamp: December 30, 2021, 12:30:26 pm
content: 50k is the highest impedance, so 1uF will give about 3Hz of bandwidth at the center.

author: Ian.M
author_rank: Super Contributor
timestamp: December 30, 2021, 12:58:28 pm
content: R varies with the pot's wiper position as for AC the upper and lower sections of the pot's track are effectively in parallel (seehttps://en.wikipedia.org/wiki/Th%C3%A9venin%27s_theorem). That means its 50K when exactly centered and quite low, possibly only a few ohms with the pot at either limit.However the ATmega32U4 datasheet states:Quote from: 24.7.1For nearly 80% of your pots range it will violate the source impedance under 10K recommendation, but the ArduinoanalogRead()function doesn't know that more sampling time is required.If you don't mind some (unpredictable) offset due to pin leakage currents the high source impedance can be mitigated by a capacitor to ground of at least 33nF at the ADC input pin, but if you want more predictable results, I'd strongly recommend using a pot of no more than 10K track resistance, which allows you to add a 4K7 resistor in series with its wiper for a source impedance that's always between 4.7 and 9.7 kiloohms, so you can actually select a suitable capacitor for your RC low pass filter. If you were sticking with the 100K pot, 10K added in series with its wiper would at least reduce the range to 10 to 60 kiloohms.The capacitor value required is also going to depend on the amplitude of the 'hum', how many bits of accuracy you need, and the maximum time constant you can tolerate. Remember that for a step change in the input you'll need to wait five time constants for it to settle to within 1% of its final value.

author: Kleinstein
author_rank: Super Contributor
timestamp: December 30, 2021, 02:22:39 pm
content: Hum is better suppressed digital: read the ADC a few times (e.g. 4 readings with 5 ms in between) and average. With the right combination this can give you very good 50 Hz suppression (e.g. 60 dB range if the timing is good). The idea is to sum up points where the hum parts is positive and negative, so that in the sum it cancels.

author: strawberry
author_rank: Super Contributor
timestamp: December 30, 2021, 03:07:56 pm
content: shielding

author: robzy
author_rank: Regular Contributor
timestamp: January 01, 2022, 05:01:04 am
content: Quote from: NiHaoMike on December 30, 2021, 12:30:26 pmThanks! I guess that the bandwidth will go up as the pot moves away from center, but that should be fine because it will be a lower resistance.Quote from: Ian.M on December 30, 2021, 12:58:28 pmThat's really interesting! I wasn't aware of that. Thanks for sharing. I realise now that increasing the sampling time would probably be the best way forward, but I'm not sure if Arduino will let me do it.Quote from: Ian.M on December 30, 2021, 12:58:28 pmWouldn't 10k in series with the wiper actually increase the range???Quote from: Kleinstein on December 30, 2021, 02:22:39 pmHrm. Interesting. I'll need to give that some thought because it would mean hacking a way at an existing Arduino sketch.

author: Ian.M
author_rank: Super Contributor
timestamp: January 01, 2022, 07:49:51 am
content: Adding the 10K resistor increases the source resistance, but decreases the proportional range. Take centered as 100%. Without the resistor, at the ends, the resistance drops to very near 0%. (50K => 0) With it, it only drops to 16.66% (60K => 10K).Here's what's in the Arduino AVR analogRead() function, stripped of the non ATmega32U4 stuff:Code:int analogRead(uint8_t pin){uint8_t low, high;#if defined(analogPinToChannel)if (pin >= 18) pin -= 18; // allow for channel or pin numberspin = analogPinToChannel(pin);#elseif (pin >= 18) pin -= 18; // allow for channel or pin numbers#endif// the MUX5 bit of ADCSRB selects whether we're reading from channels// 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);// set the analog reference (high two bits of ADMUX) and select the// channel (low 4 bits). this also sets ADLAR (left-adjust result)// to 0 (the default).ADMUX = (analog_reference << 6) | (pin & 0x07);// without a delay, we seem to read from the wrong channel//delay(1);// start the conversionsbi(ADCSRA, ADSC);// ADSC is cleared when the conversion finisheswhile (bit_is_set(ADCSRA, ADSC));// we have to read ADCL first; doing so locks both ADCL// and ADCH until ADCH is read. reading ADCL second would// cause the results of each conversion to be discarded,// as ADCL and ADCH would be locked when it completed.low = ADCL;high = ADCH;// combine the two bytesreturn (high << 8) | low;}You can see the only delay is commented out. If you ignore the source impedance recommendations of the datasheet, you'll need longer between selecting the channel and starting the ADC conversion. The easiest way to achieve that without delving into direct hardware register access is, whenever the channel (ADC pin) changes, to read the same channel twice with a delay in-between, discarding the first result. e.g. here's a 'wrapper' for analogRead() that does that:Code:int slowAnalogRead(uint8_t pin){static uint8_t last_pin;if(pin!=last_pin){analogRead(pin); // preset channel, discard resultdelayMicroseconds(100); // Adjust delay for your source impedancelast_pin=pin;}return analogRead(pin); // Do conversion without changing channels}