Go Down

Topic: PWM volume control has audible glitches (solved) (Read 928 times) previous topic - next topic

megapix

Nov 11, 2012, 11:14 pm Last Edit: Nov 13, 2012, 07:50 am by megapix Reason: 1
I'm trying to drive a voice coil with a low frequency (around 100Hz) and I need to set the "on" time and volume of the drive pulse independently. I am using a higher frequency PWM to control volume. I turn analogWrite on and off to set the "on" time, and adjust duty cycle to change the volume. The problem is that I can hear a glitch or buzz occuring twice a second with the code as shown. If I use delay instead of delayMicroseconds the glitches are more erratic but still present. Using a "for" loop instead of delay gave a different pattern of noise, but still getting the noise. Any suggestions?
Code: [Select]

/*
PWM volume control
Low frequency signal turns on high frequency PWM
*/

int Outpin = 9;  //TP4
long ontime = 5;  //sets the ontime to half a cycle at 100Hz
int DutyCycle = 25;  //duty cycle of 25/255 for testing.

void setup()  
{
 pinMode(Outpin, OUTPUT);
 TCCR1B = TCCR1B & 0b11111000|0b1;
 
}

void loop()
{
 analogWrite(Outpin,DutyCycle);
 delay(ontime);
 digitalWrite(Outpin, LOW);
 delay(ontime); //"off" time equal to "on" time for testing
}

Grumpy_Mike

It is rather a dubious thing you are trying to do.

Quote
The problem is that I can hear a glitch or buzz occuring twice a second with the code as shown.

Not surprising because there are interrupts running to keep the millis() timer updated and this is going asynchronously with your code.
Not a lot you can do about it if you program it that way. You can get an audio output using interrupts though. I am not sure what the "on time" is and how the PWM amplitude modulates it.

Can you draw a circuit to show what sort of filtering you have on the PWM output.

Nick Gammon

The hardware timers can run continuously, therefore there will be no glitches as interrupts kick in. Some info here:

http://www.gammon.com.au/forum/?id=11504
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

megapix

Thanks for the replies.
Grumpy_Mike
I've attached a crude picture if that helps.
Nick
Quote
therefore there will be no glitches as interrupts kick in

That's why I'm confused. There are glitches, but I don't know why. Thanks for the link, I'll see if I can find any insight there.


megapix

#4
Nov 13, 2012, 08:02 am Last Edit: Nov 13, 2012, 08:05 am by megapix Reason: 1
Yippee, problem solved. Because the PWM signal was being turned on by an asynchronous signal (whatever the loop time happens to be), sometimes the counter value would be such that the first pulse would be extra long. By resetting Timer1 before I turn on PWM with analogWrite, I never get the extra long first pulse.
Code: [Select]

/*
PWM volume control
Low frequency signal turns on high frequency PWM
*/

int Outpin = 9;  //TP4
long ontime = 5;  //sets the ontime to half a cycle at 100Hz
int DutyCycle = 25;  //duty cycle of 25/255 for testing.

void setup()  
{
 pinMode(Outpin, OUTPUT);
 TCCR1B = TCCR1B & 0b11111000|0b1; //raising the PWM frequency to about 32kHz
 
}

void loop()
{
 TCNT1=0;  //Resets the counter in Timer1 to zero each time
 analogWrite(Outpin,DutyCycle);
 delay(ontime);
 digitalWrite(Outpin, LOW);
 delay(ontime); //"off" time equal to "on" time for testing
}

Go Up