Door Bell
History
The door bell seems like a simple project but it's not! There is one major difficulty it's to generate a sine wave via Pulse Width Modulation.
The output of OC1A from ATMega8 oscillates at 32 kHz and the pulse width determined value from a sine look up table. A low pass filter of 1.8 kHz removes the 32 kHz. The resulting output is a pure sine wave. To archive a better sound I used two sine waves at the same note but at a different octave. You can listen this song here. The decay of each note is done via another PWM which control the gain of the output amplifier.
Features
|
|
Many different songs can be done |
|
|
Nice sound |
Pictures
Click to enlarge
|
Song |
One note |
Sources codes & Schematics
//**************************************************************************
// AVRDoorBell
// Version 1.0 Fev 2003
//
// 1.0 -> -First Release
//
// Sylvain Bissonnette
//**************************************************************************
/*********************************************************/
/* I N C L U D E */
/*********************************************************/
#include "macros.h"
#include "iom8v.h"
/*********************************************************/
/* P R O T O T Y P E */
/*********************************************************/
void Delay(int del);
void Timer1_CompA(void);
void Note(unsigned char N1,unsigned char N2,unsigned char Time);
void Song(const unsigned char *Ptr);
void main(void);
/*********************************************************/
/* D E F I N E */
/*********************************************************/
#define TRUE 1
#define FALSE 0
#define A2 57 // 220hz
#define A2d 60 // 233hz
#define B2 64 // 247hz
#define C2 68 // 262hz
#define C2d 72 // 277hz
#define D2 76 // 294hz
#define D2d 80 // 311hz
#define E2 85 // 330hz
#define F2 90 // 349hz
#define F2d 96 // 370hz
#define G2 101 // 392hz
#define G2d 107 // 415hz
#define A3 114 // 440hz
#define A3d 120 // 466hz
#define B3 128 // 494hz
#define C3 136 // 523hz
#define C3d 144 // 554hz
#define D3 152 // 587hz
#define D3d 160 // 622hz
#define E3 170 // 659hz
#define F3 180 // 698hz
#define F3d 192 // 740hz
#define G3 202 // 784hz
#define G3d 214 // 830hz
#define N0 0
#define T1 1
#define T2 2
#define T3 3
#define T4 4
#define T5 5
#define T6 6
#define T7 7
#define T8 8
#define T9 9
/*********************************************************/
/* C O N S T A N T */
/*********************************************************/
// SineTable
const unsigned char SineTable[256] = {133,136,139,142,
145,149,152,155,
158,161,164,167,
169,172,175,178,
181,184,186,189,
192,194,197,200,
202,205,207,209,
212,214,216,218,
220,222,224,226,
228,230,232,233,
235,237,238,240,
241,242,243,245,
246,247,248,248,
249,250,251,251,
252,252,252,253,
253,253,253,253,
253,253,252,252,
252,251,251,250,
249,248,248,247,
246,245,243,242,
241,240,238,237,
235,233,232,230,
228,226,224,222,
220,218,216,214,
212,209,207,205,
202,200,197,194,
192,189,186,184,
181,178,175,172,
169,167,164,161,
158,155,152,149,
145,142,139,136,
133,130,127,124,
121,118,115,112,
109,105,102,99,
96,93,90,87,
85,82,79,76,
73,70,68,65,
62,60,57,54,
52,49,47,45,
42,40,38,36,
34,32,30,28,
26,24,22,21,
19,17,16,14,
13,12,11,9,
8,7,6,6,
5,4,3,3,
2,2,2,1,
1,1,1,1,
1,1,2,2,
2,3,3,4,
5,6,6,7,
8,9,11,12,
13,14,16,17,
19,21,22,24,
26,28,30,32,
34,36,38,40,
42,45,47,49,
52,54,57,60,
62,65,68,70,
73,76,79,82,
85,87,90,93,
96,99,102,105,
109,112,115,118,
121,124,127,127};
// Gingle Bell
const unsigned char Song1[50] = {E2,E3,T3,
E2,E3,T3,
E2,E3,T3,
N0,N0,T3,
E2,E3,T3,
E2,E3,T3,
E2,E3,T3,
N0,N0,T3,
E2,E3,T3,
G2,G3,T3,
C2,C3,T3,
D2,D3,T3,
E2,E3,T3,
N0,N0,N0};
// Happy Birday
const unsigned char Song2[75] = {C2,C3,T2,
C2,C3,T2,
D2,D3,T3,
C2,C3,T3,
F2,F3,T3,
E2,E3,T3,
N0,N0,T3,
C2,C3,T2,
C2,C3,T2,
D2,D3,T3,
C2,C3,T3,
G2,G3,T3,
F2,F3,T3,
N0,N0,N0};
// Test3
const unsigned char Song3[10] = {C2,C3,T2,
C2,C3,T2,
N0,N0,N0};
// Test4
const unsigned char Song4[10] = {D2,D3,T2,
D2,D3,T2,
N0,N0,N0};
// Test5
const unsigned char Song5[10] = {E2,E3,T2,
E2,E3,T2,
N0,N0,N0};
// Test6
const unsigned char Song6[10] = {F2,F3,T2,
F2,F3,T2,
N0,N0,N0};
// Test7
const unsigned char Song7[10] = {G2,G3,T2,
G2,G3,T2,
N0,N0,N0};
// Test8
const unsigned char Song8[10] = {A2,A3,T2,
A2,A3,T2,
N0,N0,N0};
/*********************************************************/
/* G L O B A L V A R I A B L E S */
/*********************************************************/
unsigned char StepWidth1 = 0x00;
unsigned int LookUpExt1 = 0x00;
unsigned char LookUpAct1;
unsigned char StepWidth2 = 0x00;
unsigned int LookUpExt2 = 0x00;
unsigned char LookUpAct2;
unsigned int Total;
/*********************************************************/
void Delay(int del)
{
int i,j;
for (j=0;j<del;j++)
{
for (i=0;i<100;i++);
WDR();
}
}
/*********************************************************/
#pragma interrupt_handler Timer1_CompA:7
void Timer1_CompA(void)
{
LookUpExt1 += StepWidth1;
LookUpAct1 = (char)(LookUpExt1 >> 5);
LookUpExt2 += StepWidth2;
LookUpAct2 = (char)(LookUpExt2 >> 5);
Total = (SineTable[LookUpAct1] + SineTable[LookUpAct2])>>2;
OCR1A = Total;
}
/*********************************************************/
void Note(unsigned char N1,unsigned char N2,unsigned char Time)
{
unsigned char i;
if (N1 != 0)
{
StepWidth1 = N1;
StepWidth2 = N2;
for (i=255;i>1;i--)
{
Delay(Time);
OCR1B = i;
}
}
else
{
for (i=255;i>1;i--) Delay(Time);
}
}
/*********************************************************/
void Song(const unsigned char *Ptr)
{
while (*(Ptr+2) != N0)
{
Note(*Ptr,*(Ptr+1),*(Ptr+2));
Ptr = Ptr + 3;
}
}
/*********************************************************/
void main(void)
{
unsigned char i = 0;
UCSRB = 0x00; // Disable UART
DDRB = 0x0f; // PB0,1,2,3 as output
PORTD = 0xff;
DDRD = 0x00;
TIMSK = 0x10;
TCCR1A = 0xa1;
TCCR1B = 0x09;
WDR();
WDTCR = 0x0e; // Enable WatchDog at 0.97 sec
SEI();
while(1)
{
WDR();
if ((PIND & 0x01) == 0x00) Song(Song1);
if ((PIND & 0x02) == 0x00) Song(Song2);
if ((PIND & 0x04) == 0x00) Song(Song3);
if ((PIND & 0x08) == 0x00) Song(Song4);
if ((PIND & 0x10) == 0x00) Song(Song5);
if ((PIND & 0x20) == 0x00) Song(Song6);
if ((PIND & 0x40) == 0x00) Song(Song7);
if ((PIND & 0x80) == 0x00) Song(Song8);
}
}