Pages: [1]   Go Down
Author Topic: PWM volume control has audible glitches (solved)  (Read 891 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
/*
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
}
« Last Edit: November 13, 2012, 01:50:32 am by megapix » Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 639
Posts: 34726
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Global Moderator
Melbourne, Australia
Online Online
Brattain Member
*****
Karma: 511
Posts: 19357
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

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

Please post technical questions on the forum - not to me by personal message. Thanks a lot.

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.



* pwm.jpg (16.67 KB, 840x525 - viewed 33 times.)
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
/*
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
}
« Last Edit: November 13, 2012, 02:05:34 am by megapix » Logged

Pages: [1]   Go Up
Jump to: