Trying a PWM audio application. I can't figure out why I'm getting a loud beep overlapping my sound
$begingroup$
I want to play some short audio clips (they range from 50ms to 100ms) from my atmega168 microcontroller and output it to a cheap speaker.
I was following this tutorial but because I'm using a atmega168 and not a atmega2560, I had to modify my code as well as replaced the sound.
Like in the tutorial, I'm using a 8MHz internal oscillator (I set LFUSE = 0xE2 in the Makefile) and all the PWM settings are the same...which means
- Using a 16 Timer/Counter1 with 8-bit PWM resolution
- Set OC1A on compare match (and clear on bottom)
- No prescaling
As for the sound clip, I sampled it at 15.625 kHz and exported it to a 8-bit PCM wav file. I then get a hex dump via xxd -i which gives me the output c file. I didn't remove the header as I figured I can just skip it by just going to the 44th position of the output array as it is the data position.
The problem I'm having is that while I do get my (distorted and soft) sound, there is this loud beeping noise that is overlapping with my sound and I have no idea what is causing it.
Unfortunately I don't have access to an oscilloscope, so I can't really nail down if it is the way I sampled my sound, or if my sound is way too short or something that's beyond my current understanding.
Main.c
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/power.h>
#include <util/setbaud.h>
#include <avr/interrupt.h>
#include "switch.h"
#define WAV_DATA_POSITION 44
#define BASE_LEVEL 0xff
unsigned int count=WAV_DATA_POSITION;;
volatile uint16_t timerOverflowCount;
unsigned char sample_count =2;
// This interrupt service reads new data,
ISR(TIMER1_OVF_vect){
sample_count--;
if(sample_count ==0)
{
sample_count = 2;
if (count < switchResampled_len){
OCR1A= pgm_read_byte(&switch_raw[count]);
count++;
}
}
else{
OCR1A= BASE_LEVEL;
}
}
void pwm_init()
{
SREG |=0x80;
//select Fast PWM with 8-bit resolution,set OC1A on compare match and clear at bottom
TCCR1A|=(1<<COM1A1)|(1<<COM1A0)|(1<<WGM10);
//No prescaling therefore timer frequency = 8 MHz and PWM frequency = 31250 Hz
TCCR1B|=(1<<WGM12)|(1<<CS10);
TCNT1=0x00;
OCR1A=BASE_LEVEL;
//Enable the timer interrupt
TIMSK1 |= ( 1 <<TOIE1);
//Clear all interupt flags
TIFR1|=(1<<ICF1)|(1<<OCF1B)|(1<<OCF1A)|(1<<TOV1);
//Enable interrupts
sei();
}
int main(void)
{
//PB1 is OC1A. Use this for output
DDRB |= (1 << PB1);
pwm_init();
/* insert your hardware initialization here */
for(;;){
/* insert your main loop code here */
}
return 0; /* never reached */
}
Switch.h (Sound file)
const unsigned char switch_raw PROGMEM = {
0x52, 0x49, 0x46, 0x46, 0x0d, 0x04, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45,
0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
0x09, 0x3d, 0x00, 0x00, 0x09, 0x3d, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00,
0x64, 0x61, 0x74, 0x61, 0x4b, 0x03, 0x00, 0x00, 0x80, 0x7f, 0x7f, 0x7e,
0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x7e, 0x7f, 0x80, 0x7f, 0x7e, 0x7e,
0x7f, 0x80, 0x7f, 0x7f, 0x7e, 0x7d, 0x7f, 0x81, 0x7e, 0x7e, 0x7f, 0x7f,
0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7d, 0x80, 0x81, 0x7e, 0x7b, 0x7e, 0x7f,
0x7f, 0x81, 0x7e, 0x7e, 0x7d, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e,
0x80, 0x80, 0x7e, 0x7c, 0x7d, 0x7f, 0x81, 0x7f, 0x7e, 0x81, 0x7d, 0x7b,
0x80, 0x7f, 0x7f, 0x83, 0x7f, 0x7b, 0x7f, 0x80, 0x7f, 0x82, 0x7f, 0x7e,
0x80, 0x7e, 0x81, 0x7f, 0x7f, 0x81, 0x7d, 0x7e, 0x80, 0x7e, 0x80, 0x7e,
0x7f, 0x85, 0x80, 0x83, 0x7b, 0x77, 0x83, 0x81, 0x86, 0x7e, 0x7b, 0x7e,
0x81, 0x83, 0x7f, 0x7f, 0x7f, 0x7f, 0x81, 0x82, 0x7f, 0x7e, 0x7e, 0x7e,
0x81, 0x83, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x81, 0x7e, 0x7e, 0x80, 0x83,
0x7f, 0x7d, 0x7b, 0x80, 0x80, 0x94, 0x79, 0x68, 0x87, 0x75, 0x98, 0x87,
0x6e, 0x7f, 0x8c, 0x81, 0x54, 0x7c, 0xc4, 0x8a, 0x46, 0x31, 0x72, 0xe2,
0xc1, 0x8a, 0x41, 0x2f, 0x71, 0xb3, 0xc8, 0x96, 0x51, 0x41, 0x67, 0x9c,
0xb1, 0x98, 0x74, 0x57, 0x5f, 0x76, 0x99, 0xa8, 0x96, 0x72, 0x5b, 0x64,
0x7e, 0x97, 0xa1, 0x8f, 0x6f, 0x56, 0x66, 0x89, 0xa0, 0x9d, 0x7e, 0x62,
0x5c, 0x78, 0x93, 0x9d, 0x90, 0x70, 0x58, 0x68, 0x88, 0x9c, 0x95, 0x7c,
0x66, 0x64, 0x7c, 0x90, 0x95, 0x82, 0x6f, 0x6b, 0x75, 0x86, 0x8e, 0x88,
0x79, 0x72, 0x75, 0x80, 0x88, 0x89, 0x81, 0x78, 0x74, 0x78, 0x84, 0x85,
0x84, 0x7d, 0x7b, 0x7c, 0x7b, 0x80, 0x85, 0x87, 0x81, 0x76, 0x74, 0x7e,
0x82, 0x89, 0x84, 0x7c, 0x77, 0x78, 0x84, 0x83, 0x84, 0x7c, 0x78, 0x7b,
0x83, 0x83, 0x80, 0x83, 0x80, 0x7d, 0x7a, 0x7e, 0x83, 0x87, 0x82, 0x79,
0x78, 0x7e, 0x87, 0x8b, 0x80, 0x76, 0x79, 0x7e, 0x87, 0x87, 0x80, 0x7a,
0x7a, 0x80, 0x82, 0x84, 0x81, 0x7f, 0x7e, 0x7d, 0x7a, 0x82, 0x88, 0x7f,
0x7a, 0x79, 0x7f, 0x85, 0x85, 0x7f, 0x7d, 0x7a, 0x7d, 0x83, 0x87, 0x7e,
0x78, 0x7e, 0x7d, 0x83, 0x7e, 0x81, 0x81, 0x80, 0x7f, 0x81, 0x81, 0x7c,
0x7e, 0x7a, 0x81, 0x82, 0x81, 0x84, 0x82, 0x79, 0x78, 0x84, 0x86, 0x7d,
0x7b, 0x7e, 0x7f, 0x7c, 0x7d, 0x7d, 0x82, 0x80, 0x80, 0x7e, 0x7d, 0x85,
0x84, 0x7b, 0x75, 0x7c, 0x7d, 0x84, 0x88, 0x84, 0x7b, 0x7b, 0x7d, 0x7c,
0x88, 0x88, 0x7b, 0x78, 0x78, 0x78, 0x88, 0x8d, 0x80, 0x78, 0x7f, 0x86,
0x86, 0x83, 0x7c, 0x71, 0x76, 0x84, 0x97, 0x93, 0x70, 0x6d, 0x68, 0x78,
0xc5, 0xb6, 0x5f, 0x37, 0x2a, 0x69, 0xc1, 0xc9, 0xa0, 0x7a, 0x52, 0x50,
0x71, 0x8a, 0x9d, 0xa0, 0x8b, 0x69, 0x67, 0x68, 0x79, 0x94, 0x96, 0x87,
0x7b, 0x81, 0x84, 0x7e, 0x7d, 0x7e, 0x75, 0x72, 0x89, 0x8e, 0x88, 0x86,
0x6d, 0x6d, 0x7a, 0x82, 0x8d, 0x8e, 0x78, 0x76, 0x7f, 0x7d, 0x7e, 0x82,
0x80, 0x7b, 0x7d, 0x7a, 0x7b, 0x86, 0x89, 0x80, 0x7b, 0x75, 0x77, 0x7f,
0x83, 0x84, 0x86, 0x81, 0x81, 0x7e, 0x73, 0x7c, 0x83, 0x7f, 0x85, 0x82,
0x7d, 0x83, 0x7d, 0x7d, 0x80, 0x7b, 0x7c, 0x86, 0x85, 0x7e, 0x7b, 0x74,
0x7d, 0x86, 0x85, 0x8b, 0x81, 0x76, 0x78, 0x78, 0x7e, 0x89, 0x83, 0x7e,
0x80, 0x78, 0x7f, 0x84, 0x81, 0x84, 0x7a, 0x77, 0x7f, 0x81, 0x84, 0x81,
0x78, 0x7a, 0x7e, 0x84, 0x8e, 0x81, 0x72, 0x75, 0x77, 0x83, 0x8b, 0x84,
0x84, 0x7b, 0x72, 0x7a, 0x83, 0x84, 0x85, 0x7e, 0x78, 0x7e, 0x7d, 0x7f,
0x82, 0x80, 0x7f, 0x7e, 0x7f, 0x81, 0x7e, 0x7b, 0x80, 0x85, 0x84, 0x82,
0x7d, 0x7a, 0x7d, 0x7f, 0x84, 0x84, 0x7f, 0x79, 0x7b, 0x82, 0x80, 0x80,
0x81, 0x80, 0x81, 0x81, 0x7f, 0x7e, 0x79, 0x79, 0x81, 0x86, 0x85, 0x82,
0x7d, 0x77, 0x7a, 0x7e, 0x86, 0x8b, 0x84, 0x7a, 0x7a, 0x7d, 0x7e, 0x83,
0x83, 0x80, 0x7e, 0x7c, 0x7c, 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x80, 0x7e,
0x7f, 0x80, 0x7f, 0x7c, 0x80, 0x7d, 0x7e, 0x85, 0x81, 0x7c, 0x7d, 0x7b,
0x7c, 0x81, 0x80, 0x7d, 0x7f, 0x80, 0x7d, 0x82, 0x84, 0x7e, 0x7a, 0x7e,
0x7e, 0x7f, 0x82, 0x7d, 0x7e, 0x81, 0x7f, 0x7d, 0x7e, 0x81, 0x83, 0x83,
0x80, 0x79, 0x77, 0x7c, 0x83, 0x87, 0x86, 0x7f, 0x75, 0x79, 0x7e, 0x85,
0x86, 0x80, 0x7a, 0x78, 0x7c, 0x7f, 0x83, 0x81, 0x82, 0x7d, 0x7a, 0x7f,
0x81, 0x80, 0x80, 0x7c, 0x7b, 0x80, 0x7e, 0x80, 0x85, 0x84, 0x7d, 0x7b,
0x7a, 0x7f, 0x83, 0x82, 0x80, 0x7c, 0x7e, 0x7e, 0x80, 0x81, 0x7f, 0x7f,
0x7e, 0x7f, 0x82, 0x7f, 0x7c, 0x7b, 0x7b, 0x82, 0x84, 0x83, 0x7e, 0x7c,
0x7b, 0x7e, 0x83, 0x81, 0x7f, 0x7d, 0x7e, 0x7f, 0x83, 0x81, 0x7e, 0x7d,
0x7b, 0x7d, 0x80, 0x82, 0x81, 0x80, 0x7f, 0x7d, 0x7f, 0x80, 0x7f, 0x80,
0x81, 0x80, 0x7f, 0x7d, 0x7d, 0x7e, 0x81, 0x82, 0x80, 0x7d, 0x7f, 0x81,
0x80, 0x7f, 0x7d, 0x7c, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7f,
0x7d, 0x7e, 0x80, 0x81, 0x80, 0x7f, 0x7e, 0x7c, 0x7f, 0x81, 0x80, 0x80,
0x80, 0x7f, 0x7e, 0x7e, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x81, 0x80, 0x7d,
0x7c, 0x7f, 0x80, 0x83, 0x81, 0x7c, 0x7b, 0x7c, 0x7f, 0x82, 0x82, 0x7f,
0x7d, 0x7c, 0x7e, 0x80, 0x81, 0x81, 0x7f, 0x7f, 0x7d, 0x7d, 0x80, 0x82,
0x7f, 0x7e, 0x7d, 0x7d, 0x80, 0x83, 0x82, 0x7f, 0x7f, 0x7a, 0x7d, 0x80,
0x81, 0x81, 0x80, 0x7e, 0x7f, 0x80, 0x7e, 0x7e, 0x7f, 0x80, 0x7f, 0x80,
0x7f, 0x7e, 0x7d, 0x7f, 0x7e, 0x80, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7e,
0x7e, 0x7d, 0x80, 0x7f, 0x80, 0x81, 0x7f, 0x7e, 0x7e, 0x7c, 0x7f, 0x82,
0x7f, 0x80, 0x7f, 0x7d, 0x7d, 0x7f, 0x7f, 0x80, 0x80, 0x7f, 0x7e, 0x7f,
0x7f, 0x7f, 0x80, 0x7e, 0x7f, 0x7f, 0x80, 0x81, 0x7f, 0x7e, 0x7d, 0x7d,
0x81, 0x82, 0x80, 0x7e, 0x7d, 0x7e, 0x80, 0x81, 0x7f, 0x80, 0x80, 0x7f,
0x7f, 0x7d, 0x7f, 0x81, 0x80, 0x7f, 0x80, 0x7f, 0x7e, 0x7d, 0x7e, 0x4c,
0x49, 0x53, 0x54, 0x48, 0x00, 0x00, 0x00, 0x49, 0x4e, 0x46, 0x4f, 0x49,
0x43, 0x52, 0x44, 0x12, 0x00, 0x00, 0x00, 0x32, 0x30, 0x31, 0x36, 0x2d,
0x31, 0x30, 0x2d, 0x31, 0x37, 0x20, 0x31, 0x37, 0x3a, 0x32, 0x37, 0x00,
0x00, 0x49, 0x53, 0x46, 0x54, 0x22, 0x00, 0x00, 0x00, 0x4c, 0x61, 0x76,
0x66, 0x35, 0x37, 0x2e, 0x37, 0x32, 0x2e, 0x31, 0x30, 0x31, 0x20, 0x28,
0x6c, 0x69, 0x62, 0x73, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x31,
0x2e, 0x30, 0x2e, 0x32, 0x34, 0x29, 0x00, 0x69, 0x64, 0x33, 0x20, 0x46,
0x00, 0x00, 0x00, 0x49, 0x44, 0x33, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3c, 0x54, 0x58, 0x58, 0x58, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x00, 0x4c, 0x61, 0x76,
0x66, 0x35, 0x37, 0x2e, 0x37, 0x32, 0x2e, 0x31, 0x30, 0x31, 0x54, 0x44,
0x52, 0x43, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x32, 0x30, 0x31,
0x36, 0x2d, 0x31, 0x30, 0x2d, 0x31, 0x37, 0x20, 0x31, 0x37, 0x3a, 0x32,
0x37
};
const long switchResampled_len = 1045;
audio pwm atmega
$endgroup$
add a comment |
$begingroup$
I want to play some short audio clips (they range from 50ms to 100ms) from my atmega168 microcontroller and output it to a cheap speaker.
I was following this tutorial but because I'm using a atmega168 and not a atmega2560, I had to modify my code as well as replaced the sound.
Like in the tutorial, I'm using a 8MHz internal oscillator (I set LFUSE = 0xE2 in the Makefile) and all the PWM settings are the same...which means
- Using a 16 Timer/Counter1 with 8-bit PWM resolution
- Set OC1A on compare match (and clear on bottom)
- No prescaling
As for the sound clip, I sampled it at 15.625 kHz and exported it to a 8-bit PCM wav file. I then get a hex dump via xxd -i which gives me the output c file. I didn't remove the header as I figured I can just skip it by just going to the 44th position of the output array as it is the data position.
The problem I'm having is that while I do get my (distorted and soft) sound, there is this loud beeping noise that is overlapping with my sound and I have no idea what is causing it.
Unfortunately I don't have access to an oscilloscope, so I can't really nail down if it is the way I sampled my sound, or if my sound is way too short or something that's beyond my current understanding.
Main.c
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/power.h>
#include <util/setbaud.h>
#include <avr/interrupt.h>
#include "switch.h"
#define WAV_DATA_POSITION 44
#define BASE_LEVEL 0xff
unsigned int count=WAV_DATA_POSITION;;
volatile uint16_t timerOverflowCount;
unsigned char sample_count =2;
// This interrupt service reads new data,
ISR(TIMER1_OVF_vect){
sample_count--;
if(sample_count ==0)
{
sample_count = 2;
if (count < switchResampled_len){
OCR1A= pgm_read_byte(&switch_raw[count]);
count++;
}
}
else{
OCR1A= BASE_LEVEL;
}
}
void pwm_init()
{
SREG |=0x80;
//select Fast PWM with 8-bit resolution,set OC1A on compare match and clear at bottom
TCCR1A|=(1<<COM1A1)|(1<<COM1A0)|(1<<WGM10);
//No prescaling therefore timer frequency = 8 MHz and PWM frequency = 31250 Hz
TCCR1B|=(1<<WGM12)|(1<<CS10);
TCNT1=0x00;
OCR1A=BASE_LEVEL;
//Enable the timer interrupt
TIMSK1 |= ( 1 <<TOIE1);
//Clear all interupt flags
TIFR1|=(1<<ICF1)|(1<<OCF1B)|(1<<OCF1A)|(1<<TOV1);
//Enable interrupts
sei();
}
int main(void)
{
//PB1 is OC1A. Use this for output
DDRB |= (1 << PB1);
pwm_init();
/* insert your hardware initialization here */
for(;;){
/* insert your main loop code here */
}
return 0; /* never reached */
}
Switch.h (Sound file)
const unsigned char switch_raw PROGMEM = {
0x52, 0x49, 0x46, 0x46, 0x0d, 0x04, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45,
0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
0x09, 0x3d, 0x00, 0x00, 0x09, 0x3d, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00,
0x64, 0x61, 0x74, 0x61, 0x4b, 0x03, 0x00, 0x00, 0x80, 0x7f, 0x7f, 0x7e,
0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x7e, 0x7f, 0x80, 0x7f, 0x7e, 0x7e,
0x7f, 0x80, 0x7f, 0x7f, 0x7e, 0x7d, 0x7f, 0x81, 0x7e, 0x7e, 0x7f, 0x7f,
0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7d, 0x80, 0x81, 0x7e, 0x7b, 0x7e, 0x7f,
0x7f, 0x81, 0x7e, 0x7e, 0x7d, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e,
0x80, 0x80, 0x7e, 0x7c, 0x7d, 0x7f, 0x81, 0x7f, 0x7e, 0x81, 0x7d, 0x7b,
0x80, 0x7f, 0x7f, 0x83, 0x7f, 0x7b, 0x7f, 0x80, 0x7f, 0x82, 0x7f, 0x7e,
0x80, 0x7e, 0x81, 0x7f, 0x7f, 0x81, 0x7d, 0x7e, 0x80, 0x7e, 0x80, 0x7e,
0x7f, 0x85, 0x80, 0x83, 0x7b, 0x77, 0x83, 0x81, 0x86, 0x7e, 0x7b, 0x7e,
0x81, 0x83, 0x7f, 0x7f, 0x7f, 0x7f, 0x81, 0x82, 0x7f, 0x7e, 0x7e, 0x7e,
0x81, 0x83, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x81, 0x7e, 0x7e, 0x80, 0x83,
0x7f, 0x7d, 0x7b, 0x80, 0x80, 0x94, 0x79, 0x68, 0x87, 0x75, 0x98, 0x87,
0x6e, 0x7f, 0x8c, 0x81, 0x54, 0x7c, 0xc4, 0x8a, 0x46, 0x31, 0x72, 0xe2,
0xc1, 0x8a, 0x41, 0x2f, 0x71, 0xb3, 0xc8, 0x96, 0x51, 0x41, 0x67, 0x9c,
0xb1, 0x98, 0x74, 0x57, 0x5f, 0x76, 0x99, 0xa8, 0x96, 0x72, 0x5b, 0x64,
0x7e, 0x97, 0xa1, 0x8f, 0x6f, 0x56, 0x66, 0x89, 0xa0, 0x9d, 0x7e, 0x62,
0x5c, 0x78, 0x93, 0x9d, 0x90, 0x70, 0x58, 0x68, 0x88, 0x9c, 0x95, 0x7c,
0x66, 0x64, 0x7c, 0x90, 0x95, 0x82, 0x6f, 0x6b, 0x75, 0x86, 0x8e, 0x88,
0x79, 0x72, 0x75, 0x80, 0x88, 0x89, 0x81, 0x78, 0x74, 0x78, 0x84, 0x85,
0x84, 0x7d, 0x7b, 0x7c, 0x7b, 0x80, 0x85, 0x87, 0x81, 0x76, 0x74, 0x7e,
0x82, 0x89, 0x84, 0x7c, 0x77, 0x78, 0x84, 0x83, 0x84, 0x7c, 0x78, 0x7b,
0x83, 0x83, 0x80, 0x83, 0x80, 0x7d, 0x7a, 0x7e, 0x83, 0x87, 0x82, 0x79,
0x78, 0x7e, 0x87, 0x8b, 0x80, 0x76, 0x79, 0x7e, 0x87, 0x87, 0x80, 0x7a,
0x7a, 0x80, 0x82, 0x84, 0x81, 0x7f, 0x7e, 0x7d, 0x7a, 0x82, 0x88, 0x7f,
0x7a, 0x79, 0x7f, 0x85, 0x85, 0x7f, 0x7d, 0x7a, 0x7d, 0x83, 0x87, 0x7e,
0x78, 0x7e, 0x7d, 0x83, 0x7e, 0x81, 0x81, 0x80, 0x7f, 0x81, 0x81, 0x7c,
0x7e, 0x7a, 0x81, 0x82, 0x81, 0x84, 0x82, 0x79, 0x78, 0x84, 0x86, 0x7d,
0x7b, 0x7e, 0x7f, 0x7c, 0x7d, 0x7d, 0x82, 0x80, 0x80, 0x7e, 0x7d, 0x85,
0x84, 0x7b, 0x75, 0x7c, 0x7d, 0x84, 0x88, 0x84, 0x7b, 0x7b, 0x7d, 0x7c,
0x88, 0x88, 0x7b, 0x78, 0x78, 0x78, 0x88, 0x8d, 0x80, 0x78, 0x7f, 0x86,
0x86, 0x83, 0x7c, 0x71, 0x76, 0x84, 0x97, 0x93, 0x70, 0x6d, 0x68, 0x78,
0xc5, 0xb6, 0x5f, 0x37, 0x2a, 0x69, 0xc1, 0xc9, 0xa0, 0x7a, 0x52, 0x50,
0x71, 0x8a, 0x9d, 0xa0, 0x8b, 0x69, 0x67, 0x68, 0x79, 0x94, 0x96, 0x87,
0x7b, 0x81, 0x84, 0x7e, 0x7d, 0x7e, 0x75, 0x72, 0x89, 0x8e, 0x88, 0x86,
0x6d, 0x6d, 0x7a, 0x82, 0x8d, 0x8e, 0x78, 0x76, 0x7f, 0x7d, 0x7e, 0x82,
0x80, 0x7b, 0x7d, 0x7a, 0x7b, 0x86, 0x89, 0x80, 0x7b, 0x75, 0x77, 0x7f,
0x83, 0x84, 0x86, 0x81, 0x81, 0x7e, 0x73, 0x7c, 0x83, 0x7f, 0x85, 0x82,
0x7d, 0x83, 0x7d, 0x7d, 0x80, 0x7b, 0x7c, 0x86, 0x85, 0x7e, 0x7b, 0x74,
0x7d, 0x86, 0x85, 0x8b, 0x81, 0x76, 0x78, 0x78, 0x7e, 0x89, 0x83, 0x7e,
0x80, 0x78, 0x7f, 0x84, 0x81, 0x84, 0x7a, 0x77, 0x7f, 0x81, 0x84, 0x81,
0x78, 0x7a, 0x7e, 0x84, 0x8e, 0x81, 0x72, 0x75, 0x77, 0x83, 0x8b, 0x84,
0x84, 0x7b, 0x72, 0x7a, 0x83, 0x84, 0x85, 0x7e, 0x78, 0x7e, 0x7d, 0x7f,
0x82, 0x80, 0x7f, 0x7e, 0x7f, 0x81, 0x7e, 0x7b, 0x80, 0x85, 0x84, 0x82,
0x7d, 0x7a, 0x7d, 0x7f, 0x84, 0x84, 0x7f, 0x79, 0x7b, 0x82, 0x80, 0x80,
0x81, 0x80, 0x81, 0x81, 0x7f, 0x7e, 0x79, 0x79, 0x81, 0x86, 0x85, 0x82,
0x7d, 0x77, 0x7a, 0x7e, 0x86, 0x8b, 0x84, 0x7a, 0x7a, 0x7d, 0x7e, 0x83,
0x83, 0x80, 0x7e, 0x7c, 0x7c, 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x80, 0x7e,
0x7f, 0x80, 0x7f, 0x7c, 0x80, 0x7d, 0x7e, 0x85, 0x81, 0x7c, 0x7d, 0x7b,
0x7c, 0x81, 0x80, 0x7d, 0x7f, 0x80, 0x7d, 0x82, 0x84, 0x7e, 0x7a, 0x7e,
0x7e, 0x7f, 0x82, 0x7d, 0x7e, 0x81, 0x7f, 0x7d, 0x7e, 0x81, 0x83, 0x83,
0x80, 0x79, 0x77, 0x7c, 0x83, 0x87, 0x86, 0x7f, 0x75, 0x79, 0x7e, 0x85,
0x86, 0x80, 0x7a, 0x78, 0x7c, 0x7f, 0x83, 0x81, 0x82, 0x7d, 0x7a, 0x7f,
0x81, 0x80, 0x80, 0x7c, 0x7b, 0x80, 0x7e, 0x80, 0x85, 0x84, 0x7d, 0x7b,
0x7a, 0x7f, 0x83, 0x82, 0x80, 0x7c, 0x7e, 0x7e, 0x80, 0x81, 0x7f, 0x7f,
0x7e, 0x7f, 0x82, 0x7f, 0x7c, 0x7b, 0x7b, 0x82, 0x84, 0x83, 0x7e, 0x7c,
0x7b, 0x7e, 0x83, 0x81, 0x7f, 0x7d, 0x7e, 0x7f, 0x83, 0x81, 0x7e, 0x7d,
0x7b, 0x7d, 0x80, 0x82, 0x81, 0x80, 0x7f, 0x7d, 0x7f, 0x80, 0x7f, 0x80,
0x81, 0x80, 0x7f, 0x7d, 0x7d, 0x7e, 0x81, 0x82, 0x80, 0x7d, 0x7f, 0x81,
0x80, 0x7f, 0x7d, 0x7c, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7f,
0x7d, 0x7e, 0x80, 0x81, 0x80, 0x7f, 0x7e, 0x7c, 0x7f, 0x81, 0x80, 0x80,
0x80, 0x7f, 0x7e, 0x7e, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x81, 0x80, 0x7d,
0x7c, 0x7f, 0x80, 0x83, 0x81, 0x7c, 0x7b, 0x7c, 0x7f, 0x82, 0x82, 0x7f,
0x7d, 0x7c, 0x7e, 0x80, 0x81, 0x81, 0x7f, 0x7f, 0x7d, 0x7d, 0x80, 0x82,
0x7f, 0x7e, 0x7d, 0x7d, 0x80, 0x83, 0x82, 0x7f, 0x7f, 0x7a, 0x7d, 0x80,
0x81, 0x81, 0x80, 0x7e, 0x7f, 0x80, 0x7e, 0x7e, 0x7f, 0x80, 0x7f, 0x80,
0x7f, 0x7e, 0x7d, 0x7f, 0x7e, 0x80, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7e,
0x7e, 0x7d, 0x80, 0x7f, 0x80, 0x81, 0x7f, 0x7e, 0x7e, 0x7c, 0x7f, 0x82,
0x7f, 0x80, 0x7f, 0x7d, 0x7d, 0x7f, 0x7f, 0x80, 0x80, 0x7f, 0x7e, 0x7f,
0x7f, 0x7f, 0x80, 0x7e, 0x7f, 0x7f, 0x80, 0x81, 0x7f, 0x7e, 0x7d, 0x7d,
0x81, 0x82, 0x80, 0x7e, 0x7d, 0x7e, 0x80, 0x81, 0x7f, 0x80, 0x80, 0x7f,
0x7f, 0x7d, 0x7f, 0x81, 0x80, 0x7f, 0x80, 0x7f, 0x7e, 0x7d, 0x7e, 0x4c,
0x49, 0x53, 0x54, 0x48, 0x00, 0x00, 0x00, 0x49, 0x4e, 0x46, 0x4f, 0x49,
0x43, 0x52, 0x44, 0x12, 0x00, 0x00, 0x00, 0x32, 0x30, 0x31, 0x36, 0x2d,
0x31, 0x30, 0x2d, 0x31, 0x37, 0x20, 0x31, 0x37, 0x3a, 0x32, 0x37, 0x00,
0x00, 0x49, 0x53, 0x46, 0x54, 0x22, 0x00, 0x00, 0x00, 0x4c, 0x61, 0x76,
0x66, 0x35, 0x37, 0x2e, 0x37, 0x32, 0x2e, 0x31, 0x30, 0x31, 0x20, 0x28,
0x6c, 0x69, 0x62, 0x73, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x31,
0x2e, 0x30, 0x2e, 0x32, 0x34, 0x29, 0x00, 0x69, 0x64, 0x33, 0x20, 0x46,
0x00, 0x00, 0x00, 0x49, 0x44, 0x33, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3c, 0x54, 0x58, 0x58, 0x58, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x00, 0x4c, 0x61, 0x76,
0x66, 0x35, 0x37, 0x2e, 0x37, 0x32, 0x2e, 0x31, 0x30, 0x31, 0x54, 0x44,
0x52, 0x43, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x32, 0x30, 0x31,
0x36, 0x2d, 0x31, 0x30, 0x2d, 0x31, 0x37, 0x20, 0x31, 0x37, 0x3a, 0x32,
0x37
};
const long switchResampled_len = 1045;
audio pwm atmega
$endgroup$
1
$begingroup$
That is likely the fundamental PWM rate, wherein you are modifying the DUTY CYCLE but not the repetition rate.
$endgroup$
– analogsystemsrf
Dec 21 '18 at 2:38
3
$begingroup$
1045 samples at 15.625kHz is only 67mSec worth of data. How are you hearing anything in only 67mSec?
$endgroup$
– brhans
Dec 21 '18 at 2:46
$begingroup$
By the way, instead of using PWM, there are cheap and accessible microcontrollers with true analog outputs (e.g. 12-bit resolution).
$endgroup$
– Nayuki
Dec 21 '18 at 7:20
$begingroup$
@analogsystemsrf What do you mean by "repetition rate"?
$endgroup$
– cheunste
Dec 23 '18 at 0:57
$begingroup$
@brhans The original file is 67 ms long...or at least according to audacity. These are sound effect files, so I wasn't joking when I said they're short sound clips.
$endgroup$
– cheunste
Dec 23 '18 at 0:58
add a comment |
$begingroup$
I want to play some short audio clips (they range from 50ms to 100ms) from my atmega168 microcontroller and output it to a cheap speaker.
I was following this tutorial but because I'm using a atmega168 and not a atmega2560, I had to modify my code as well as replaced the sound.
Like in the tutorial, I'm using a 8MHz internal oscillator (I set LFUSE = 0xE2 in the Makefile) and all the PWM settings are the same...which means
- Using a 16 Timer/Counter1 with 8-bit PWM resolution
- Set OC1A on compare match (and clear on bottom)
- No prescaling
As for the sound clip, I sampled it at 15.625 kHz and exported it to a 8-bit PCM wav file. I then get a hex dump via xxd -i which gives me the output c file. I didn't remove the header as I figured I can just skip it by just going to the 44th position of the output array as it is the data position.
The problem I'm having is that while I do get my (distorted and soft) sound, there is this loud beeping noise that is overlapping with my sound and I have no idea what is causing it.
Unfortunately I don't have access to an oscilloscope, so I can't really nail down if it is the way I sampled my sound, or if my sound is way too short or something that's beyond my current understanding.
Main.c
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/power.h>
#include <util/setbaud.h>
#include <avr/interrupt.h>
#include "switch.h"
#define WAV_DATA_POSITION 44
#define BASE_LEVEL 0xff
unsigned int count=WAV_DATA_POSITION;;
volatile uint16_t timerOverflowCount;
unsigned char sample_count =2;
// This interrupt service reads new data,
ISR(TIMER1_OVF_vect){
sample_count--;
if(sample_count ==0)
{
sample_count = 2;
if (count < switchResampled_len){
OCR1A= pgm_read_byte(&switch_raw[count]);
count++;
}
}
else{
OCR1A= BASE_LEVEL;
}
}
void pwm_init()
{
SREG |=0x80;
//select Fast PWM with 8-bit resolution,set OC1A on compare match and clear at bottom
TCCR1A|=(1<<COM1A1)|(1<<COM1A0)|(1<<WGM10);
//No prescaling therefore timer frequency = 8 MHz and PWM frequency = 31250 Hz
TCCR1B|=(1<<WGM12)|(1<<CS10);
TCNT1=0x00;
OCR1A=BASE_LEVEL;
//Enable the timer interrupt
TIMSK1 |= ( 1 <<TOIE1);
//Clear all interupt flags
TIFR1|=(1<<ICF1)|(1<<OCF1B)|(1<<OCF1A)|(1<<TOV1);
//Enable interrupts
sei();
}
int main(void)
{
//PB1 is OC1A. Use this for output
DDRB |= (1 << PB1);
pwm_init();
/* insert your hardware initialization here */
for(;;){
/* insert your main loop code here */
}
return 0; /* never reached */
}
Switch.h (Sound file)
const unsigned char switch_raw PROGMEM = {
0x52, 0x49, 0x46, 0x46, 0x0d, 0x04, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45,
0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
0x09, 0x3d, 0x00, 0x00, 0x09, 0x3d, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00,
0x64, 0x61, 0x74, 0x61, 0x4b, 0x03, 0x00, 0x00, 0x80, 0x7f, 0x7f, 0x7e,
0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x7e, 0x7f, 0x80, 0x7f, 0x7e, 0x7e,
0x7f, 0x80, 0x7f, 0x7f, 0x7e, 0x7d, 0x7f, 0x81, 0x7e, 0x7e, 0x7f, 0x7f,
0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7d, 0x80, 0x81, 0x7e, 0x7b, 0x7e, 0x7f,
0x7f, 0x81, 0x7e, 0x7e, 0x7d, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e,
0x80, 0x80, 0x7e, 0x7c, 0x7d, 0x7f, 0x81, 0x7f, 0x7e, 0x81, 0x7d, 0x7b,
0x80, 0x7f, 0x7f, 0x83, 0x7f, 0x7b, 0x7f, 0x80, 0x7f, 0x82, 0x7f, 0x7e,
0x80, 0x7e, 0x81, 0x7f, 0x7f, 0x81, 0x7d, 0x7e, 0x80, 0x7e, 0x80, 0x7e,
0x7f, 0x85, 0x80, 0x83, 0x7b, 0x77, 0x83, 0x81, 0x86, 0x7e, 0x7b, 0x7e,
0x81, 0x83, 0x7f, 0x7f, 0x7f, 0x7f, 0x81, 0x82, 0x7f, 0x7e, 0x7e, 0x7e,
0x81, 0x83, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x81, 0x7e, 0x7e, 0x80, 0x83,
0x7f, 0x7d, 0x7b, 0x80, 0x80, 0x94, 0x79, 0x68, 0x87, 0x75, 0x98, 0x87,
0x6e, 0x7f, 0x8c, 0x81, 0x54, 0x7c, 0xc4, 0x8a, 0x46, 0x31, 0x72, 0xe2,
0xc1, 0x8a, 0x41, 0x2f, 0x71, 0xb3, 0xc8, 0x96, 0x51, 0x41, 0x67, 0x9c,
0xb1, 0x98, 0x74, 0x57, 0x5f, 0x76, 0x99, 0xa8, 0x96, 0x72, 0x5b, 0x64,
0x7e, 0x97, 0xa1, 0x8f, 0x6f, 0x56, 0x66, 0x89, 0xa0, 0x9d, 0x7e, 0x62,
0x5c, 0x78, 0x93, 0x9d, 0x90, 0x70, 0x58, 0x68, 0x88, 0x9c, 0x95, 0x7c,
0x66, 0x64, 0x7c, 0x90, 0x95, 0x82, 0x6f, 0x6b, 0x75, 0x86, 0x8e, 0x88,
0x79, 0x72, 0x75, 0x80, 0x88, 0x89, 0x81, 0x78, 0x74, 0x78, 0x84, 0x85,
0x84, 0x7d, 0x7b, 0x7c, 0x7b, 0x80, 0x85, 0x87, 0x81, 0x76, 0x74, 0x7e,
0x82, 0x89, 0x84, 0x7c, 0x77, 0x78, 0x84, 0x83, 0x84, 0x7c, 0x78, 0x7b,
0x83, 0x83, 0x80, 0x83, 0x80, 0x7d, 0x7a, 0x7e, 0x83, 0x87, 0x82, 0x79,
0x78, 0x7e, 0x87, 0x8b, 0x80, 0x76, 0x79, 0x7e, 0x87, 0x87, 0x80, 0x7a,
0x7a, 0x80, 0x82, 0x84, 0x81, 0x7f, 0x7e, 0x7d, 0x7a, 0x82, 0x88, 0x7f,
0x7a, 0x79, 0x7f, 0x85, 0x85, 0x7f, 0x7d, 0x7a, 0x7d, 0x83, 0x87, 0x7e,
0x78, 0x7e, 0x7d, 0x83, 0x7e, 0x81, 0x81, 0x80, 0x7f, 0x81, 0x81, 0x7c,
0x7e, 0x7a, 0x81, 0x82, 0x81, 0x84, 0x82, 0x79, 0x78, 0x84, 0x86, 0x7d,
0x7b, 0x7e, 0x7f, 0x7c, 0x7d, 0x7d, 0x82, 0x80, 0x80, 0x7e, 0x7d, 0x85,
0x84, 0x7b, 0x75, 0x7c, 0x7d, 0x84, 0x88, 0x84, 0x7b, 0x7b, 0x7d, 0x7c,
0x88, 0x88, 0x7b, 0x78, 0x78, 0x78, 0x88, 0x8d, 0x80, 0x78, 0x7f, 0x86,
0x86, 0x83, 0x7c, 0x71, 0x76, 0x84, 0x97, 0x93, 0x70, 0x6d, 0x68, 0x78,
0xc5, 0xb6, 0x5f, 0x37, 0x2a, 0x69, 0xc1, 0xc9, 0xa0, 0x7a, 0x52, 0x50,
0x71, 0x8a, 0x9d, 0xa0, 0x8b, 0x69, 0x67, 0x68, 0x79, 0x94, 0x96, 0x87,
0x7b, 0x81, 0x84, 0x7e, 0x7d, 0x7e, 0x75, 0x72, 0x89, 0x8e, 0x88, 0x86,
0x6d, 0x6d, 0x7a, 0x82, 0x8d, 0x8e, 0x78, 0x76, 0x7f, 0x7d, 0x7e, 0x82,
0x80, 0x7b, 0x7d, 0x7a, 0x7b, 0x86, 0x89, 0x80, 0x7b, 0x75, 0x77, 0x7f,
0x83, 0x84, 0x86, 0x81, 0x81, 0x7e, 0x73, 0x7c, 0x83, 0x7f, 0x85, 0x82,
0x7d, 0x83, 0x7d, 0x7d, 0x80, 0x7b, 0x7c, 0x86, 0x85, 0x7e, 0x7b, 0x74,
0x7d, 0x86, 0x85, 0x8b, 0x81, 0x76, 0x78, 0x78, 0x7e, 0x89, 0x83, 0x7e,
0x80, 0x78, 0x7f, 0x84, 0x81, 0x84, 0x7a, 0x77, 0x7f, 0x81, 0x84, 0x81,
0x78, 0x7a, 0x7e, 0x84, 0x8e, 0x81, 0x72, 0x75, 0x77, 0x83, 0x8b, 0x84,
0x84, 0x7b, 0x72, 0x7a, 0x83, 0x84, 0x85, 0x7e, 0x78, 0x7e, 0x7d, 0x7f,
0x82, 0x80, 0x7f, 0x7e, 0x7f, 0x81, 0x7e, 0x7b, 0x80, 0x85, 0x84, 0x82,
0x7d, 0x7a, 0x7d, 0x7f, 0x84, 0x84, 0x7f, 0x79, 0x7b, 0x82, 0x80, 0x80,
0x81, 0x80, 0x81, 0x81, 0x7f, 0x7e, 0x79, 0x79, 0x81, 0x86, 0x85, 0x82,
0x7d, 0x77, 0x7a, 0x7e, 0x86, 0x8b, 0x84, 0x7a, 0x7a, 0x7d, 0x7e, 0x83,
0x83, 0x80, 0x7e, 0x7c, 0x7c, 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x80, 0x7e,
0x7f, 0x80, 0x7f, 0x7c, 0x80, 0x7d, 0x7e, 0x85, 0x81, 0x7c, 0x7d, 0x7b,
0x7c, 0x81, 0x80, 0x7d, 0x7f, 0x80, 0x7d, 0x82, 0x84, 0x7e, 0x7a, 0x7e,
0x7e, 0x7f, 0x82, 0x7d, 0x7e, 0x81, 0x7f, 0x7d, 0x7e, 0x81, 0x83, 0x83,
0x80, 0x79, 0x77, 0x7c, 0x83, 0x87, 0x86, 0x7f, 0x75, 0x79, 0x7e, 0x85,
0x86, 0x80, 0x7a, 0x78, 0x7c, 0x7f, 0x83, 0x81, 0x82, 0x7d, 0x7a, 0x7f,
0x81, 0x80, 0x80, 0x7c, 0x7b, 0x80, 0x7e, 0x80, 0x85, 0x84, 0x7d, 0x7b,
0x7a, 0x7f, 0x83, 0x82, 0x80, 0x7c, 0x7e, 0x7e, 0x80, 0x81, 0x7f, 0x7f,
0x7e, 0x7f, 0x82, 0x7f, 0x7c, 0x7b, 0x7b, 0x82, 0x84, 0x83, 0x7e, 0x7c,
0x7b, 0x7e, 0x83, 0x81, 0x7f, 0x7d, 0x7e, 0x7f, 0x83, 0x81, 0x7e, 0x7d,
0x7b, 0x7d, 0x80, 0x82, 0x81, 0x80, 0x7f, 0x7d, 0x7f, 0x80, 0x7f, 0x80,
0x81, 0x80, 0x7f, 0x7d, 0x7d, 0x7e, 0x81, 0x82, 0x80, 0x7d, 0x7f, 0x81,
0x80, 0x7f, 0x7d, 0x7c, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7f,
0x7d, 0x7e, 0x80, 0x81, 0x80, 0x7f, 0x7e, 0x7c, 0x7f, 0x81, 0x80, 0x80,
0x80, 0x7f, 0x7e, 0x7e, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x81, 0x80, 0x7d,
0x7c, 0x7f, 0x80, 0x83, 0x81, 0x7c, 0x7b, 0x7c, 0x7f, 0x82, 0x82, 0x7f,
0x7d, 0x7c, 0x7e, 0x80, 0x81, 0x81, 0x7f, 0x7f, 0x7d, 0x7d, 0x80, 0x82,
0x7f, 0x7e, 0x7d, 0x7d, 0x80, 0x83, 0x82, 0x7f, 0x7f, 0x7a, 0x7d, 0x80,
0x81, 0x81, 0x80, 0x7e, 0x7f, 0x80, 0x7e, 0x7e, 0x7f, 0x80, 0x7f, 0x80,
0x7f, 0x7e, 0x7d, 0x7f, 0x7e, 0x80, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7e,
0x7e, 0x7d, 0x80, 0x7f, 0x80, 0x81, 0x7f, 0x7e, 0x7e, 0x7c, 0x7f, 0x82,
0x7f, 0x80, 0x7f, 0x7d, 0x7d, 0x7f, 0x7f, 0x80, 0x80, 0x7f, 0x7e, 0x7f,
0x7f, 0x7f, 0x80, 0x7e, 0x7f, 0x7f, 0x80, 0x81, 0x7f, 0x7e, 0x7d, 0x7d,
0x81, 0x82, 0x80, 0x7e, 0x7d, 0x7e, 0x80, 0x81, 0x7f, 0x80, 0x80, 0x7f,
0x7f, 0x7d, 0x7f, 0x81, 0x80, 0x7f, 0x80, 0x7f, 0x7e, 0x7d, 0x7e, 0x4c,
0x49, 0x53, 0x54, 0x48, 0x00, 0x00, 0x00, 0x49, 0x4e, 0x46, 0x4f, 0x49,
0x43, 0x52, 0x44, 0x12, 0x00, 0x00, 0x00, 0x32, 0x30, 0x31, 0x36, 0x2d,
0x31, 0x30, 0x2d, 0x31, 0x37, 0x20, 0x31, 0x37, 0x3a, 0x32, 0x37, 0x00,
0x00, 0x49, 0x53, 0x46, 0x54, 0x22, 0x00, 0x00, 0x00, 0x4c, 0x61, 0x76,
0x66, 0x35, 0x37, 0x2e, 0x37, 0x32, 0x2e, 0x31, 0x30, 0x31, 0x20, 0x28,
0x6c, 0x69, 0x62, 0x73, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x31,
0x2e, 0x30, 0x2e, 0x32, 0x34, 0x29, 0x00, 0x69, 0x64, 0x33, 0x20, 0x46,
0x00, 0x00, 0x00, 0x49, 0x44, 0x33, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3c, 0x54, 0x58, 0x58, 0x58, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x00, 0x4c, 0x61, 0x76,
0x66, 0x35, 0x37, 0x2e, 0x37, 0x32, 0x2e, 0x31, 0x30, 0x31, 0x54, 0x44,
0x52, 0x43, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x32, 0x30, 0x31,
0x36, 0x2d, 0x31, 0x30, 0x2d, 0x31, 0x37, 0x20, 0x31, 0x37, 0x3a, 0x32,
0x37
};
const long switchResampled_len = 1045;
audio pwm atmega
$endgroup$
I want to play some short audio clips (they range from 50ms to 100ms) from my atmega168 microcontroller and output it to a cheap speaker.
I was following this tutorial but because I'm using a atmega168 and not a atmega2560, I had to modify my code as well as replaced the sound.
Like in the tutorial, I'm using a 8MHz internal oscillator (I set LFUSE = 0xE2 in the Makefile) and all the PWM settings are the same...which means
- Using a 16 Timer/Counter1 with 8-bit PWM resolution
- Set OC1A on compare match (and clear on bottom)
- No prescaling
As for the sound clip, I sampled it at 15.625 kHz and exported it to a 8-bit PCM wav file. I then get a hex dump via xxd -i which gives me the output c file. I didn't remove the header as I figured I can just skip it by just going to the 44th position of the output array as it is the data position.
The problem I'm having is that while I do get my (distorted and soft) sound, there is this loud beeping noise that is overlapping with my sound and I have no idea what is causing it.
Unfortunately I don't have access to an oscilloscope, so I can't really nail down if it is the way I sampled my sound, or if my sound is way too short or something that's beyond my current understanding.
Main.c
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/power.h>
#include <util/setbaud.h>
#include <avr/interrupt.h>
#include "switch.h"
#define WAV_DATA_POSITION 44
#define BASE_LEVEL 0xff
unsigned int count=WAV_DATA_POSITION;;
volatile uint16_t timerOverflowCount;
unsigned char sample_count =2;
// This interrupt service reads new data,
ISR(TIMER1_OVF_vect){
sample_count--;
if(sample_count ==0)
{
sample_count = 2;
if (count < switchResampled_len){
OCR1A= pgm_read_byte(&switch_raw[count]);
count++;
}
}
else{
OCR1A= BASE_LEVEL;
}
}
void pwm_init()
{
SREG |=0x80;
//select Fast PWM with 8-bit resolution,set OC1A on compare match and clear at bottom
TCCR1A|=(1<<COM1A1)|(1<<COM1A0)|(1<<WGM10);
//No prescaling therefore timer frequency = 8 MHz and PWM frequency = 31250 Hz
TCCR1B|=(1<<WGM12)|(1<<CS10);
TCNT1=0x00;
OCR1A=BASE_LEVEL;
//Enable the timer interrupt
TIMSK1 |= ( 1 <<TOIE1);
//Clear all interupt flags
TIFR1|=(1<<ICF1)|(1<<OCF1B)|(1<<OCF1A)|(1<<TOV1);
//Enable interrupts
sei();
}
int main(void)
{
//PB1 is OC1A. Use this for output
DDRB |= (1 << PB1);
pwm_init();
/* insert your hardware initialization here */
for(;;){
/* insert your main loop code here */
}
return 0; /* never reached */
}
Switch.h (Sound file)
const unsigned char switch_raw PROGMEM = {
0x52, 0x49, 0x46, 0x46, 0x0d, 0x04, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45,
0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
0x09, 0x3d, 0x00, 0x00, 0x09, 0x3d, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00,
0x64, 0x61, 0x74, 0x61, 0x4b, 0x03, 0x00, 0x00, 0x80, 0x7f, 0x7f, 0x7e,
0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x7e, 0x7f, 0x80, 0x7f, 0x7e, 0x7e,
0x7f, 0x80, 0x7f, 0x7f, 0x7e, 0x7d, 0x7f, 0x81, 0x7e, 0x7e, 0x7f, 0x7f,
0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7d, 0x80, 0x81, 0x7e, 0x7b, 0x7e, 0x7f,
0x7f, 0x81, 0x7e, 0x7e, 0x7d, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e,
0x80, 0x80, 0x7e, 0x7c, 0x7d, 0x7f, 0x81, 0x7f, 0x7e, 0x81, 0x7d, 0x7b,
0x80, 0x7f, 0x7f, 0x83, 0x7f, 0x7b, 0x7f, 0x80, 0x7f, 0x82, 0x7f, 0x7e,
0x80, 0x7e, 0x81, 0x7f, 0x7f, 0x81, 0x7d, 0x7e, 0x80, 0x7e, 0x80, 0x7e,
0x7f, 0x85, 0x80, 0x83, 0x7b, 0x77, 0x83, 0x81, 0x86, 0x7e, 0x7b, 0x7e,
0x81, 0x83, 0x7f, 0x7f, 0x7f, 0x7f, 0x81, 0x82, 0x7f, 0x7e, 0x7e, 0x7e,
0x81, 0x83, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x81, 0x7e, 0x7e, 0x80, 0x83,
0x7f, 0x7d, 0x7b, 0x80, 0x80, 0x94, 0x79, 0x68, 0x87, 0x75, 0x98, 0x87,
0x6e, 0x7f, 0x8c, 0x81, 0x54, 0x7c, 0xc4, 0x8a, 0x46, 0x31, 0x72, 0xe2,
0xc1, 0x8a, 0x41, 0x2f, 0x71, 0xb3, 0xc8, 0x96, 0x51, 0x41, 0x67, 0x9c,
0xb1, 0x98, 0x74, 0x57, 0x5f, 0x76, 0x99, 0xa8, 0x96, 0x72, 0x5b, 0x64,
0x7e, 0x97, 0xa1, 0x8f, 0x6f, 0x56, 0x66, 0x89, 0xa0, 0x9d, 0x7e, 0x62,
0x5c, 0x78, 0x93, 0x9d, 0x90, 0x70, 0x58, 0x68, 0x88, 0x9c, 0x95, 0x7c,
0x66, 0x64, 0x7c, 0x90, 0x95, 0x82, 0x6f, 0x6b, 0x75, 0x86, 0x8e, 0x88,
0x79, 0x72, 0x75, 0x80, 0x88, 0x89, 0x81, 0x78, 0x74, 0x78, 0x84, 0x85,
0x84, 0x7d, 0x7b, 0x7c, 0x7b, 0x80, 0x85, 0x87, 0x81, 0x76, 0x74, 0x7e,
0x82, 0x89, 0x84, 0x7c, 0x77, 0x78, 0x84, 0x83, 0x84, 0x7c, 0x78, 0x7b,
0x83, 0x83, 0x80, 0x83, 0x80, 0x7d, 0x7a, 0x7e, 0x83, 0x87, 0x82, 0x79,
0x78, 0x7e, 0x87, 0x8b, 0x80, 0x76, 0x79, 0x7e, 0x87, 0x87, 0x80, 0x7a,
0x7a, 0x80, 0x82, 0x84, 0x81, 0x7f, 0x7e, 0x7d, 0x7a, 0x82, 0x88, 0x7f,
0x7a, 0x79, 0x7f, 0x85, 0x85, 0x7f, 0x7d, 0x7a, 0x7d, 0x83, 0x87, 0x7e,
0x78, 0x7e, 0x7d, 0x83, 0x7e, 0x81, 0x81, 0x80, 0x7f, 0x81, 0x81, 0x7c,
0x7e, 0x7a, 0x81, 0x82, 0x81, 0x84, 0x82, 0x79, 0x78, 0x84, 0x86, 0x7d,
0x7b, 0x7e, 0x7f, 0x7c, 0x7d, 0x7d, 0x82, 0x80, 0x80, 0x7e, 0x7d, 0x85,
0x84, 0x7b, 0x75, 0x7c, 0x7d, 0x84, 0x88, 0x84, 0x7b, 0x7b, 0x7d, 0x7c,
0x88, 0x88, 0x7b, 0x78, 0x78, 0x78, 0x88, 0x8d, 0x80, 0x78, 0x7f, 0x86,
0x86, 0x83, 0x7c, 0x71, 0x76, 0x84, 0x97, 0x93, 0x70, 0x6d, 0x68, 0x78,
0xc5, 0xb6, 0x5f, 0x37, 0x2a, 0x69, 0xc1, 0xc9, 0xa0, 0x7a, 0x52, 0x50,
0x71, 0x8a, 0x9d, 0xa0, 0x8b, 0x69, 0x67, 0x68, 0x79, 0x94, 0x96, 0x87,
0x7b, 0x81, 0x84, 0x7e, 0x7d, 0x7e, 0x75, 0x72, 0x89, 0x8e, 0x88, 0x86,
0x6d, 0x6d, 0x7a, 0x82, 0x8d, 0x8e, 0x78, 0x76, 0x7f, 0x7d, 0x7e, 0x82,
0x80, 0x7b, 0x7d, 0x7a, 0x7b, 0x86, 0x89, 0x80, 0x7b, 0x75, 0x77, 0x7f,
0x83, 0x84, 0x86, 0x81, 0x81, 0x7e, 0x73, 0x7c, 0x83, 0x7f, 0x85, 0x82,
0x7d, 0x83, 0x7d, 0x7d, 0x80, 0x7b, 0x7c, 0x86, 0x85, 0x7e, 0x7b, 0x74,
0x7d, 0x86, 0x85, 0x8b, 0x81, 0x76, 0x78, 0x78, 0x7e, 0x89, 0x83, 0x7e,
0x80, 0x78, 0x7f, 0x84, 0x81, 0x84, 0x7a, 0x77, 0x7f, 0x81, 0x84, 0x81,
0x78, 0x7a, 0x7e, 0x84, 0x8e, 0x81, 0x72, 0x75, 0x77, 0x83, 0x8b, 0x84,
0x84, 0x7b, 0x72, 0x7a, 0x83, 0x84, 0x85, 0x7e, 0x78, 0x7e, 0x7d, 0x7f,
0x82, 0x80, 0x7f, 0x7e, 0x7f, 0x81, 0x7e, 0x7b, 0x80, 0x85, 0x84, 0x82,
0x7d, 0x7a, 0x7d, 0x7f, 0x84, 0x84, 0x7f, 0x79, 0x7b, 0x82, 0x80, 0x80,
0x81, 0x80, 0x81, 0x81, 0x7f, 0x7e, 0x79, 0x79, 0x81, 0x86, 0x85, 0x82,
0x7d, 0x77, 0x7a, 0x7e, 0x86, 0x8b, 0x84, 0x7a, 0x7a, 0x7d, 0x7e, 0x83,
0x83, 0x80, 0x7e, 0x7c, 0x7c, 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x80, 0x7e,
0x7f, 0x80, 0x7f, 0x7c, 0x80, 0x7d, 0x7e, 0x85, 0x81, 0x7c, 0x7d, 0x7b,
0x7c, 0x81, 0x80, 0x7d, 0x7f, 0x80, 0x7d, 0x82, 0x84, 0x7e, 0x7a, 0x7e,
0x7e, 0x7f, 0x82, 0x7d, 0x7e, 0x81, 0x7f, 0x7d, 0x7e, 0x81, 0x83, 0x83,
0x80, 0x79, 0x77, 0x7c, 0x83, 0x87, 0x86, 0x7f, 0x75, 0x79, 0x7e, 0x85,
0x86, 0x80, 0x7a, 0x78, 0x7c, 0x7f, 0x83, 0x81, 0x82, 0x7d, 0x7a, 0x7f,
0x81, 0x80, 0x80, 0x7c, 0x7b, 0x80, 0x7e, 0x80, 0x85, 0x84, 0x7d, 0x7b,
0x7a, 0x7f, 0x83, 0x82, 0x80, 0x7c, 0x7e, 0x7e, 0x80, 0x81, 0x7f, 0x7f,
0x7e, 0x7f, 0x82, 0x7f, 0x7c, 0x7b, 0x7b, 0x82, 0x84, 0x83, 0x7e, 0x7c,
0x7b, 0x7e, 0x83, 0x81, 0x7f, 0x7d, 0x7e, 0x7f, 0x83, 0x81, 0x7e, 0x7d,
0x7b, 0x7d, 0x80, 0x82, 0x81, 0x80, 0x7f, 0x7d, 0x7f, 0x80, 0x7f, 0x80,
0x81, 0x80, 0x7f, 0x7d, 0x7d, 0x7e, 0x81, 0x82, 0x80, 0x7d, 0x7f, 0x81,
0x80, 0x7f, 0x7d, 0x7c, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7f,
0x7d, 0x7e, 0x80, 0x81, 0x80, 0x7f, 0x7e, 0x7c, 0x7f, 0x81, 0x80, 0x80,
0x80, 0x7f, 0x7e, 0x7e, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x81, 0x80, 0x7d,
0x7c, 0x7f, 0x80, 0x83, 0x81, 0x7c, 0x7b, 0x7c, 0x7f, 0x82, 0x82, 0x7f,
0x7d, 0x7c, 0x7e, 0x80, 0x81, 0x81, 0x7f, 0x7f, 0x7d, 0x7d, 0x80, 0x82,
0x7f, 0x7e, 0x7d, 0x7d, 0x80, 0x83, 0x82, 0x7f, 0x7f, 0x7a, 0x7d, 0x80,
0x81, 0x81, 0x80, 0x7e, 0x7f, 0x80, 0x7e, 0x7e, 0x7f, 0x80, 0x7f, 0x80,
0x7f, 0x7e, 0x7d, 0x7f, 0x7e, 0x80, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7e,
0x7e, 0x7d, 0x80, 0x7f, 0x80, 0x81, 0x7f, 0x7e, 0x7e, 0x7c, 0x7f, 0x82,
0x7f, 0x80, 0x7f, 0x7d, 0x7d, 0x7f, 0x7f, 0x80, 0x80, 0x7f, 0x7e, 0x7f,
0x7f, 0x7f, 0x80, 0x7e, 0x7f, 0x7f, 0x80, 0x81, 0x7f, 0x7e, 0x7d, 0x7d,
0x81, 0x82, 0x80, 0x7e, 0x7d, 0x7e, 0x80, 0x81, 0x7f, 0x80, 0x80, 0x7f,
0x7f, 0x7d, 0x7f, 0x81, 0x80, 0x7f, 0x80, 0x7f, 0x7e, 0x7d, 0x7e, 0x4c,
0x49, 0x53, 0x54, 0x48, 0x00, 0x00, 0x00, 0x49, 0x4e, 0x46, 0x4f, 0x49,
0x43, 0x52, 0x44, 0x12, 0x00, 0x00, 0x00, 0x32, 0x30, 0x31, 0x36, 0x2d,
0x31, 0x30, 0x2d, 0x31, 0x37, 0x20, 0x31, 0x37, 0x3a, 0x32, 0x37, 0x00,
0x00, 0x49, 0x53, 0x46, 0x54, 0x22, 0x00, 0x00, 0x00, 0x4c, 0x61, 0x76,
0x66, 0x35, 0x37, 0x2e, 0x37, 0x32, 0x2e, 0x31, 0x30, 0x31, 0x20, 0x28,
0x6c, 0x69, 0x62, 0x73, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x31,
0x2e, 0x30, 0x2e, 0x32, 0x34, 0x29, 0x00, 0x69, 0x64, 0x33, 0x20, 0x46,
0x00, 0x00, 0x00, 0x49, 0x44, 0x33, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3c, 0x54, 0x58, 0x58, 0x58, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x00, 0x4c, 0x61, 0x76,
0x66, 0x35, 0x37, 0x2e, 0x37, 0x32, 0x2e, 0x31, 0x30, 0x31, 0x54, 0x44,
0x52, 0x43, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x32, 0x30, 0x31,
0x36, 0x2d, 0x31, 0x30, 0x2d, 0x31, 0x37, 0x20, 0x31, 0x37, 0x3a, 0x32,
0x37
};
const long switchResampled_len = 1045;
audio pwm atmega
audio pwm atmega
asked Dec 21 '18 at 2:26
cheunstecheunste
784
784
1
$begingroup$
That is likely the fundamental PWM rate, wherein you are modifying the DUTY CYCLE but not the repetition rate.
$endgroup$
– analogsystemsrf
Dec 21 '18 at 2:38
3
$begingroup$
1045 samples at 15.625kHz is only 67mSec worth of data. How are you hearing anything in only 67mSec?
$endgroup$
– brhans
Dec 21 '18 at 2:46
$begingroup$
By the way, instead of using PWM, there are cheap and accessible microcontrollers with true analog outputs (e.g. 12-bit resolution).
$endgroup$
– Nayuki
Dec 21 '18 at 7:20
$begingroup$
@analogsystemsrf What do you mean by "repetition rate"?
$endgroup$
– cheunste
Dec 23 '18 at 0:57
$begingroup$
@brhans The original file is 67 ms long...or at least according to audacity. These are sound effect files, so I wasn't joking when I said they're short sound clips.
$endgroup$
– cheunste
Dec 23 '18 at 0:58
add a comment |
1
$begingroup$
That is likely the fundamental PWM rate, wherein you are modifying the DUTY CYCLE but not the repetition rate.
$endgroup$
– analogsystemsrf
Dec 21 '18 at 2:38
3
$begingroup$
1045 samples at 15.625kHz is only 67mSec worth of data. How are you hearing anything in only 67mSec?
$endgroup$
– brhans
Dec 21 '18 at 2:46
$begingroup$
By the way, instead of using PWM, there are cheap and accessible microcontrollers with true analog outputs (e.g. 12-bit resolution).
$endgroup$
– Nayuki
Dec 21 '18 at 7:20
$begingroup$
@analogsystemsrf What do you mean by "repetition rate"?
$endgroup$
– cheunste
Dec 23 '18 at 0:57
$begingroup$
@brhans The original file is 67 ms long...or at least according to audacity. These are sound effect files, so I wasn't joking when I said they're short sound clips.
$endgroup$
– cheunste
Dec 23 '18 at 0:58
1
1
$begingroup$
That is likely the fundamental PWM rate, wherein you are modifying the DUTY CYCLE but not the repetition rate.
$endgroup$
– analogsystemsrf
Dec 21 '18 at 2:38
$begingroup$
That is likely the fundamental PWM rate, wherein you are modifying the DUTY CYCLE but not the repetition rate.
$endgroup$
– analogsystemsrf
Dec 21 '18 at 2:38
3
3
$begingroup$
1045 samples at 15.625kHz is only 67mSec worth of data. How are you hearing anything in only 67mSec?
$endgroup$
– brhans
Dec 21 '18 at 2:46
$begingroup$
1045 samples at 15.625kHz is only 67mSec worth of data. How are you hearing anything in only 67mSec?
$endgroup$
– brhans
Dec 21 '18 at 2:46
$begingroup$
By the way, instead of using PWM, there are cheap and accessible microcontrollers with true analog outputs (e.g. 12-bit resolution).
$endgroup$
– Nayuki
Dec 21 '18 at 7:20
$begingroup$
By the way, instead of using PWM, there are cheap and accessible microcontrollers with true analog outputs (e.g. 12-bit resolution).
$endgroup$
– Nayuki
Dec 21 '18 at 7:20
$begingroup$
@analogsystemsrf What do you mean by "repetition rate"?
$endgroup$
– cheunste
Dec 23 '18 at 0:57
$begingroup$
@analogsystemsrf What do you mean by "repetition rate"?
$endgroup$
– cheunste
Dec 23 '18 at 0:57
$begingroup$
@brhans The original file is 67 ms long...or at least according to audacity. These are sound effect files, so I wasn't joking when I said they're short sound clips.
$endgroup$
– cheunste
Dec 23 '18 at 0:58
$begingroup$
@brhans The original file is 67 ms long...or at least according to audacity. These are sound effect files, so I wasn't joking when I said they're short sound clips.
$endgroup$
– cheunste
Dec 23 '18 at 0:58
add a comment |
2 Answers
2
active
oldest
votes
$begingroup$
A 4MHz PWM generator (8MHz/2) At 8 bits has a 15.625kHz fundamental. If you are not filtering this out with at least a 7kHz high-order low-pass you will hear it loud and clear.
You need to bring this fundamental to at least above 20kHz or so to get it out of your hearing range, it will still annoy your dog though.
$endgroup$
$begingroup$
Or maybe he could use a notch filter.
$endgroup$
– Harry Svensson
Dec 21 '18 at 4:06
$begingroup$
Not sure this is the problem here, probably something more "fundamental" if you excuse the pun. As brhans mentions in a comment, he only plays 67 ms of audio. Where's the beep? You wouldn't even have time to react other than "Yeah, something made a burst of noise". Besides, the PWM frequency is 32 kHz according to the description.
$endgroup$
– pipe
Dec 21 '18 at 10:32
$begingroup$
@HarrySvensson what would be the point in letting through signals with a higher frequency as the fundamental. PWM needs low pass filtering, no matter how. You can even simply use a speaker with a bad high frequency response as a low pass.
$endgroup$
– wiebel
Dec 21 '18 at 11:30
1
$begingroup$
The fast PWM in the ATmega168 runs at the main clock frequency, there's no extra division involved.
$endgroup$
– pipe
Dec 21 '18 at 15:27
1
$begingroup$
@EdgarBrown There's no need to guess, the datasheet is public.
$endgroup$
– pipe
Dec 21 '18 at 20:36
|
show 4 more comments
$begingroup$
The code you copied has a bug, which probably caused the issues he also writes about.
sample_count--;
if(sample_count ==0)
{
sample_count = 2;
if (count < switchResampled_len){
OCR1A= pgm_read_byte(&switch_raw[count]);
count++;
}
}
else{
OCR1A= BASE_LEVEL;
}
Every other tick you set OCR1A=BASE_LEVEL and the next tick you set it to your sample level, but the comments in the example code hints that the else
statement is misplaced. Try this:
sample_count--;
if(sample_count ==0)
{
sample_count = 2;
if (count < switchResampled_len){
OCR1A= pgm_read_byte(&switch_raw[count]);
count++;
}
else{
OCR1A= BASE_LEVEL;
}
}
(It was difficult not to reformat this to use consistent indents and bracket placement!)
$endgroup$
$begingroup$
I fixed the code, but that didn't seem to help unfortunately.
$endgroup$
– cheunste
Dec 22 '18 at 14:04
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
return StackExchange.using("schematics", function () {
StackExchange.schematics.init();
});
}, "cicuitlab");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "135"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2felectronics.stackexchange.com%2fquestions%2f413276%2ftrying-a-pwm-audio-application-i-cant-figure-out-why-im-getting-a-loud-beep-o%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
A 4MHz PWM generator (8MHz/2) At 8 bits has a 15.625kHz fundamental. If you are not filtering this out with at least a 7kHz high-order low-pass you will hear it loud and clear.
You need to bring this fundamental to at least above 20kHz or so to get it out of your hearing range, it will still annoy your dog though.
$endgroup$
$begingroup$
Or maybe he could use a notch filter.
$endgroup$
– Harry Svensson
Dec 21 '18 at 4:06
$begingroup$
Not sure this is the problem here, probably something more "fundamental" if you excuse the pun. As brhans mentions in a comment, he only plays 67 ms of audio. Where's the beep? You wouldn't even have time to react other than "Yeah, something made a burst of noise". Besides, the PWM frequency is 32 kHz according to the description.
$endgroup$
– pipe
Dec 21 '18 at 10:32
$begingroup$
@HarrySvensson what would be the point in letting through signals with a higher frequency as the fundamental. PWM needs low pass filtering, no matter how. You can even simply use a speaker with a bad high frequency response as a low pass.
$endgroup$
– wiebel
Dec 21 '18 at 11:30
1
$begingroup$
The fast PWM in the ATmega168 runs at the main clock frequency, there's no extra division involved.
$endgroup$
– pipe
Dec 21 '18 at 15:27
1
$begingroup$
@EdgarBrown There's no need to guess, the datasheet is public.
$endgroup$
– pipe
Dec 21 '18 at 20:36
|
show 4 more comments
$begingroup$
A 4MHz PWM generator (8MHz/2) At 8 bits has a 15.625kHz fundamental. If you are not filtering this out with at least a 7kHz high-order low-pass you will hear it loud and clear.
You need to bring this fundamental to at least above 20kHz or so to get it out of your hearing range, it will still annoy your dog though.
$endgroup$
$begingroup$
Or maybe he could use a notch filter.
$endgroup$
– Harry Svensson
Dec 21 '18 at 4:06
$begingroup$
Not sure this is the problem here, probably something more "fundamental" if you excuse the pun. As brhans mentions in a comment, he only plays 67 ms of audio. Where's the beep? You wouldn't even have time to react other than "Yeah, something made a burst of noise". Besides, the PWM frequency is 32 kHz according to the description.
$endgroup$
– pipe
Dec 21 '18 at 10:32
$begingroup$
@HarrySvensson what would be the point in letting through signals with a higher frequency as the fundamental. PWM needs low pass filtering, no matter how. You can even simply use a speaker with a bad high frequency response as a low pass.
$endgroup$
– wiebel
Dec 21 '18 at 11:30
1
$begingroup$
The fast PWM in the ATmega168 runs at the main clock frequency, there's no extra division involved.
$endgroup$
– pipe
Dec 21 '18 at 15:27
1
$begingroup$
@EdgarBrown There's no need to guess, the datasheet is public.
$endgroup$
– pipe
Dec 21 '18 at 20:36
|
show 4 more comments
$begingroup$
A 4MHz PWM generator (8MHz/2) At 8 bits has a 15.625kHz fundamental. If you are not filtering this out with at least a 7kHz high-order low-pass you will hear it loud and clear.
You need to bring this fundamental to at least above 20kHz or so to get it out of your hearing range, it will still annoy your dog though.
$endgroup$
A 4MHz PWM generator (8MHz/2) At 8 bits has a 15.625kHz fundamental. If you are not filtering this out with at least a 7kHz high-order low-pass you will hear it loud and clear.
You need to bring this fundamental to at least above 20kHz or so to get it out of your hearing range, it will still annoy your dog though.
answered Dec 21 '18 at 2:49
Edgar BrownEdgar Brown
3,673425
3,673425
$begingroup$
Or maybe he could use a notch filter.
$endgroup$
– Harry Svensson
Dec 21 '18 at 4:06
$begingroup$
Not sure this is the problem here, probably something more "fundamental" if you excuse the pun. As brhans mentions in a comment, he only plays 67 ms of audio. Where's the beep? You wouldn't even have time to react other than "Yeah, something made a burst of noise". Besides, the PWM frequency is 32 kHz according to the description.
$endgroup$
– pipe
Dec 21 '18 at 10:32
$begingroup$
@HarrySvensson what would be the point in letting through signals with a higher frequency as the fundamental. PWM needs low pass filtering, no matter how. You can even simply use a speaker with a bad high frequency response as a low pass.
$endgroup$
– wiebel
Dec 21 '18 at 11:30
1
$begingroup$
The fast PWM in the ATmega168 runs at the main clock frequency, there's no extra division involved.
$endgroup$
– pipe
Dec 21 '18 at 15:27
1
$begingroup$
@EdgarBrown There's no need to guess, the datasheet is public.
$endgroup$
– pipe
Dec 21 '18 at 20:36
|
show 4 more comments
$begingroup$
Or maybe he could use a notch filter.
$endgroup$
– Harry Svensson
Dec 21 '18 at 4:06
$begingroup$
Not sure this is the problem here, probably something more "fundamental" if you excuse the pun. As brhans mentions in a comment, he only plays 67 ms of audio. Where's the beep? You wouldn't even have time to react other than "Yeah, something made a burst of noise". Besides, the PWM frequency is 32 kHz according to the description.
$endgroup$
– pipe
Dec 21 '18 at 10:32
$begingroup$
@HarrySvensson what would be the point in letting through signals with a higher frequency as the fundamental. PWM needs low pass filtering, no matter how. You can even simply use a speaker with a bad high frequency response as a low pass.
$endgroup$
– wiebel
Dec 21 '18 at 11:30
1
$begingroup$
The fast PWM in the ATmega168 runs at the main clock frequency, there's no extra division involved.
$endgroup$
– pipe
Dec 21 '18 at 15:27
1
$begingroup$
@EdgarBrown There's no need to guess, the datasheet is public.
$endgroup$
– pipe
Dec 21 '18 at 20:36
$begingroup$
Or maybe he could use a notch filter.
$endgroup$
– Harry Svensson
Dec 21 '18 at 4:06
$begingroup$
Or maybe he could use a notch filter.
$endgroup$
– Harry Svensson
Dec 21 '18 at 4:06
$begingroup$
Not sure this is the problem here, probably something more "fundamental" if you excuse the pun. As brhans mentions in a comment, he only plays 67 ms of audio. Where's the beep? You wouldn't even have time to react other than "Yeah, something made a burst of noise". Besides, the PWM frequency is 32 kHz according to the description.
$endgroup$
– pipe
Dec 21 '18 at 10:32
$begingroup$
Not sure this is the problem here, probably something more "fundamental" if you excuse the pun. As brhans mentions in a comment, he only plays 67 ms of audio. Where's the beep? You wouldn't even have time to react other than "Yeah, something made a burst of noise". Besides, the PWM frequency is 32 kHz according to the description.
$endgroup$
– pipe
Dec 21 '18 at 10:32
$begingroup$
@HarrySvensson what would be the point in letting through signals with a higher frequency as the fundamental. PWM needs low pass filtering, no matter how. You can even simply use a speaker with a bad high frequency response as a low pass.
$endgroup$
– wiebel
Dec 21 '18 at 11:30
$begingroup$
@HarrySvensson what would be the point in letting through signals with a higher frequency as the fundamental. PWM needs low pass filtering, no matter how. You can even simply use a speaker with a bad high frequency response as a low pass.
$endgroup$
– wiebel
Dec 21 '18 at 11:30
1
1
$begingroup$
The fast PWM in the ATmega168 runs at the main clock frequency, there's no extra division involved.
$endgroup$
– pipe
Dec 21 '18 at 15:27
$begingroup$
The fast PWM in the ATmega168 runs at the main clock frequency, there's no extra division involved.
$endgroup$
– pipe
Dec 21 '18 at 15:27
1
1
$begingroup$
@EdgarBrown There's no need to guess, the datasheet is public.
$endgroup$
– pipe
Dec 21 '18 at 20:36
$begingroup$
@EdgarBrown There's no need to guess, the datasheet is public.
$endgroup$
– pipe
Dec 21 '18 at 20:36
|
show 4 more comments
$begingroup$
The code you copied has a bug, which probably caused the issues he also writes about.
sample_count--;
if(sample_count ==0)
{
sample_count = 2;
if (count < switchResampled_len){
OCR1A= pgm_read_byte(&switch_raw[count]);
count++;
}
}
else{
OCR1A= BASE_LEVEL;
}
Every other tick you set OCR1A=BASE_LEVEL and the next tick you set it to your sample level, but the comments in the example code hints that the else
statement is misplaced. Try this:
sample_count--;
if(sample_count ==0)
{
sample_count = 2;
if (count < switchResampled_len){
OCR1A= pgm_read_byte(&switch_raw[count]);
count++;
}
else{
OCR1A= BASE_LEVEL;
}
}
(It was difficult not to reformat this to use consistent indents and bracket placement!)
$endgroup$
$begingroup$
I fixed the code, but that didn't seem to help unfortunately.
$endgroup$
– cheunste
Dec 22 '18 at 14:04
add a comment |
$begingroup$
The code you copied has a bug, which probably caused the issues he also writes about.
sample_count--;
if(sample_count ==0)
{
sample_count = 2;
if (count < switchResampled_len){
OCR1A= pgm_read_byte(&switch_raw[count]);
count++;
}
}
else{
OCR1A= BASE_LEVEL;
}
Every other tick you set OCR1A=BASE_LEVEL and the next tick you set it to your sample level, but the comments in the example code hints that the else
statement is misplaced. Try this:
sample_count--;
if(sample_count ==0)
{
sample_count = 2;
if (count < switchResampled_len){
OCR1A= pgm_read_byte(&switch_raw[count]);
count++;
}
else{
OCR1A= BASE_LEVEL;
}
}
(It was difficult not to reformat this to use consistent indents and bracket placement!)
$endgroup$
$begingroup$
I fixed the code, but that didn't seem to help unfortunately.
$endgroup$
– cheunste
Dec 22 '18 at 14:04
add a comment |
$begingroup$
The code you copied has a bug, which probably caused the issues he also writes about.
sample_count--;
if(sample_count ==0)
{
sample_count = 2;
if (count < switchResampled_len){
OCR1A= pgm_read_byte(&switch_raw[count]);
count++;
}
}
else{
OCR1A= BASE_LEVEL;
}
Every other tick you set OCR1A=BASE_LEVEL and the next tick you set it to your sample level, but the comments in the example code hints that the else
statement is misplaced. Try this:
sample_count--;
if(sample_count ==0)
{
sample_count = 2;
if (count < switchResampled_len){
OCR1A= pgm_read_byte(&switch_raw[count]);
count++;
}
else{
OCR1A= BASE_LEVEL;
}
}
(It was difficult not to reformat this to use consistent indents and bracket placement!)
$endgroup$
The code you copied has a bug, which probably caused the issues he also writes about.
sample_count--;
if(sample_count ==0)
{
sample_count = 2;
if (count < switchResampled_len){
OCR1A= pgm_read_byte(&switch_raw[count]);
count++;
}
}
else{
OCR1A= BASE_LEVEL;
}
Every other tick you set OCR1A=BASE_LEVEL and the next tick you set it to your sample level, but the comments in the example code hints that the else
statement is misplaced. Try this:
sample_count--;
if(sample_count ==0)
{
sample_count = 2;
if (count < switchResampled_len){
OCR1A= pgm_read_byte(&switch_raw[count]);
count++;
}
else{
OCR1A= BASE_LEVEL;
}
}
(It was difficult not to reformat this to use consistent indents and bracket placement!)
answered Dec 21 '18 at 15:11
pipepipe
9,97442555
9,97442555
$begingroup$
I fixed the code, but that didn't seem to help unfortunately.
$endgroup$
– cheunste
Dec 22 '18 at 14:04
add a comment |
$begingroup$
I fixed the code, but that didn't seem to help unfortunately.
$endgroup$
– cheunste
Dec 22 '18 at 14:04
$begingroup$
I fixed the code, but that didn't seem to help unfortunately.
$endgroup$
– cheunste
Dec 22 '18 at 14:04
$begingroup$
I fixed the code, but that didn't seem to help unfortunately.
$endgroup$
– cheunste
Dec 22 '18 at 14:04
add a comment |
Thanks for contributing an answer to Electrical Engineering Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2felectronics.stackexchange.com%2fquestions%2f413276%2ftrying-a-pwm-audio-application-i-cant-figure-out-why-im-getting-a-loud-beep-o%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
$begingroup$
That is likely the fundamental PWM rate, wherein you are modifying the DUTY CYCLE but not the repetition rate.
$endgroup$
– analogsystemsrf
Dec 21 '18 at 2:38
3
$begingroup$
1045 samples at 15.625kHz is only 67mSec worth of data. How are you hearing anything in only 67mSec?
$endgroup$
– brhans
Dec 21 '18 at 2:46
$begingroup$
By the way, instead of using PWM, there are cheap and accessible microcontrollers with true analog outputs (e.g. 12-bit resolution).
$endgroup$
– Nayuki
Dec 21 '18 at 7:20
$begingroup$
@analogsystemsrf What do you mean by "repetition rate"?
$endgroup$
– cheunste
Dec 23 '18 at 0:57
$begingroup$
@brhans The original file is 67 ms long...or at least according to audacity. These are sound effect files, so I wasn't joking when I said they're short sound clips.
$endgroup$
– cheunste
Dec 23 '18 at 0:58