code for audio through atmega8

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey,so I finally managed to write a code for audio output through an atmega8. I am posting it below. I tried it on an LED and as expected LED was dimming with different brightness. I want to know if this dimming LED will be equivalent to audio output if i put a low pass RC filter at the OC1B pin and take output across-

1. A earphone I cutoff,and connect its signal and ground wire across the capacitor.
2. 8 ohm speaker.

What are the RC values i should use in both cases keeping in mind that an 8 ohm speaker doesn't cause loading.

PWM frequency=1Mhz/1024

P.S.- Please don't mind any questions that might seem trivial after all NOOB @ WORK

#include 
#include 
#include 
const uint8_t  sinewave[] PROGMEM= //256 values
{
0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,
0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8,
0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf5,
0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,
0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc,
0xda,0xd8,0xd5,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb3,
0xb0,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x98,0x95,0x92,0x8f,0x8c,0x89,0x86,0x83,
0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a,0x67,0x63,0x60,0x5d,0x5a,0x57,0x54,0x51,
0x4f,0x4c,0x49,0x46,0x43,0x40,0x3e,0x3b,0x38,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27,
0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x12,0x10,0x0f,0x0d,0x0c,0x0a,
0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,
0x09,0x0a,0x0c,0x0d,0x0f,0x10,0x12,0x13,0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23,
0x25,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36,0x38,0x3b,0x3e,0x40,0x43,0x46,0x49,0x4c,
0x4f,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,0x67,0x6a,0x6d,0x70,0x73,0x76,0x79,0x7c
};
uint8_t i=0;
ISR(TIMER1_COMPB_vect){
	OCR1B=pgm_read_byte(&sinewave[i]);
   i++;
	}
int main(void) {

DDRB=(1<<2);
// initial OCR1B value
OCR1B=80;
//COM1B0 and COM1B1 enabled
TCCR1A=0x31;
//prescaler 1024
TCCR1B |= _BV(CS12) | _BV(CS10);
//enable output compare interrupt for OCR1A
TIMSK=(1<<OCIE1B);
//enable global interrups
sei();
    while (1) {
   //loop for ever. Interrupts will do the job.
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Not exactly a GCC question, but hey-ho.

Don't connect the 8Ohm speaker directly to the pin. 8Ohms is practically a short circuit as far as the AVR is concerned.

If you have a 600Ohm earphone, then just go ahead and connect it, and you should hear something close to your desired audio.

If you want to low-pass filter, then you need a resistor in series with the pin, a capacitor to ground, and then the earphone. Something like this:

AVR   |
      |
      |--\/\/\/\--o------+
      |           |      |
      |          ---     o)
      |          ---     o)
      |           |      |
      |      -----o------o---- GND

Assuming a 32Ohm earphone (many are) then I would try about 470Ohm for the resistor and 1uF for the capacitor. It's difficult to predict what the volume level will be, but you should certainly hear something (if it were me, I wouldn't have the earphone anywhere near my ear the first time I tried, even though I suspect it won't be loud enough to do any damage).

Christopher Hicks
==

Last Edited: Wed. Jun 17, 2009 - 01:48 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yikes, I just noticed the PWM frequency is only about 1kHz (1MHz/1024). The audio quality is not going to be good, but speech might just about be intelligible.

CH
==

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hey thanks for the early reply,

1. I just took an earphone from a normal set i had and just cut it off,i hope connecting just the two wires coming out from it will make it work?

2. With 47k and 1uf what PWM frequency should i use,based on my assumption about 4khz??,(PWM frequency<=(1/2piRC))? For 4khz i think a prescaler of 256 should work. (1Mhz/256=4khz)

3. The code is alright in your opinion?.I tested it on LED's and they seemed to be dimming so I must get some output.Just want to get another opinion.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Or is the PWM frequency not a deciding circuit in my RC filter higher the PWM frequency more continous the wave reconstruction.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

abhishekbhardwaj007 wrote:
higher the PWM frequency more continous the wave reconstruction.
Broadly speaking, yes. I think you should aim for 8kHz PWM for intelligible speech.
abhishekbhardwaj007 wrote:
PWM frequency<=(1/2piRC))
That's the right formula, but assuming the circuit I sketched out above, the "R" in the formula is the parallel combination of the series resistor and earphone impedance (which for the sake of simplicity we will assume purely resistive, although that's not true). To find out why the parallel combination crops up here you need to look up "Thevenin source equivalent" or similar in an electronics textbook.

For a 32 Ohm earphone, 470 Ohm series resistor as I suggested (this will limit the pin current to about +/-10mA which the AVR should be OK with), and 8kHz PWM you want the cut-off frequency of the filter at about 4kHz. You can do the sums to work out C.

Quote:
3. The code is alright in your opinion?.I tested it on LED's and they seemed to be dimming so I must get some output.
It's a good sign.

CH
==

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Broadly speaking, yes. I think you should aim for 8kHz PWM for intelligible speech.

Personally I'd whack F_CPU up to 8MHz so you can then get a 31,250Hz PWM frequency using 8 bit. That should put the PWM frequency out of audio range so you don't need to worry too much about filtering it.

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Quote:

Broadly speaking, yes. I think you should aim for 8kHz PWM for intelligible speech.

Personally I'd whack F_CPU up to 8MHz so you can then get a 31,250Hz PWM frequency using 8 bit. That should put the PWM frequency out of audio range so you don't need to worry too much about filtering it.

Cliff

I suppose I should have put "at least" 8kHz. Yes, in general higher is better from the point of view of signal bandwidth and filtering requirements. However, you also have to bear in mind that

(a) you need sufficient resolution on the pulse width as well (for a fixed clock frequency, the resolution goes down as the frequency goes up), and

(b) you need CPU bandwidth to update the PWM width register, and a simple implementation would do this once per PWM cycle.

I didn't do the sums accurately on this, but you seem to be saying you can get 8 bit pulse-width resolution at a PWM frequency of 31kHz, which would yield pretty good speech. However, if you update the pulse width every cycle (which you must do to yield the full benefits of the high PWM frequency), I think you won't have much CPU bandwidth left for anything else.

CH
==

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

which would yield pretty good speech

It does. In my case I just updated OCR on every 4th tick. There was sufficient bandwidth to ADPCM decode the data. I did half on tick 1, half on tick 2, nothing on tick 3 and loaded OCR on tick 4