Submitted by Webbot on December 3, 2008 - 10:51pm.
In this example we will use a piezo sounder like this one

These devices can be attached directly to a microcontroller pin by connecting the red wire to the output pin and the black wire to ground.
If your output pin is set high then there is a voltage across the sounder - but this won't make a noise. A sounder needs to be turned on and off in rapid succession to make a tone. Each sounder is designed to give an optimal output for a given switching frequency. Check the datasheet for your sounder - but this figure is normally around 4kHz to 5kHz.
So we will assume a frequecy of 4kHz.
Unlike the previous examples: we will keep the duty cycle at 50% but instead we will vary the PWM frequency by changing the value of TOP. This implies that we need a mode of operation that allows us to specify TOP via the ICRx register.
Assume we are using the 1MHz ATMega8 from the $50 robot then the only Timer that allows us to change the value of TOP is Timer1 which has two channels. So we will use Timer1 channel A. We will use Fast PWM.
Using our formula:
TOP = (Clock_Speed / (Prescaler * Output_PWM_Frequency)) - 1
then
TOP = (1,000,000 / (1 * 4,000)) - 1 = 249 For a PWM frequency of 4kHz
So in summary:
TOP=249 for 4kHz
prescaler = 1
Mode = Fast PWM
Use Timer1 Channel A
Connect the sounder to pin OC1A
So here's the code:-
TCCR1A = 0; // Stop all PWM on Timer 1 when setting up
TCCR1A |= (1<<WGM13) | (1<<WGM12) | (1<<WGM11); // 16 bit Fast PWM using ICR1 for TOP
TCCR1B = 0;
TCCR1B |= (1<<CS10); // pre-scaler = 1
TCCR1A |= (1<<COM1A1); // enable channel A in non-inverting mode
ICR1 = 249; // 4kHz PWM
OCR1A = ICR1 / 2; // 50% duty cycle
We can then vary the frequency by changing ICR1 and by setting OCR1A to be half of that new value (in order to keep a 50% duty cycle). For example:
ICR1 = 300;
OCR1A = ICR1 / 2;
So here's a little challenge for you and your $50 robot. You've already created light sensors - so why not use one of them to decide on the frequency of the sounder so that it makes a difference noise depending on whether its in a dark place or a light place. The only hardware you need is a piezo sounder (expect to pay about 99p in the UK, so about $1.50).