This is a doorbell which will play .wav files. Select your favorite tune, add it to the SD card – and wait for unwanted guests to arrive!
The doorBell plays .wav files
An Arduino Uno is triggered by closing one of two switches – either the doorbell button on the front door, or the doorbell button on the back door. A Wave Shield holds the audio of choice, which in this case is the familiar Jetsons door chime, and Louie Louie (yes, in its entirety – TOGA PARTY!!!).
The doorBell uses the existing wiring from both the utility room and the exterior doorbell buttons. A simple bypass of the transformer in the utility room removes the 18VAC which powers a traditional doorbell.
The audio amplification is handled by the convenient-yet-loud PAM8403. These are convenient because they are powered by 5V and need no additional components – simply put line-level audio in, and receive 3W of power to drive a speaker or two.
A volume pot is accessed through the top of the MDF, so the audio level can be comfortably set – or simply turned off.
Ahh, the dream of a custom Jetsons doorbell… achieved!
CODE:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 |
/* --doorBell-- http://creativetechnical.ca/doorbell/ A doorbell which plays .wav files from a SD card thru a Wave Shield. */ #include <FatReader.h> #include <SdReader.h> #include <avr/pgmspace.h> #include "WaveUtil.h" #include "WaveHC.h" SdReader card; // This object holds the information for the card FatVolume vol; // This holds the information for the partition on the card FatReader root; // This holds the information for the filesystem on the card FatReader f; // This holds the information for the file we're play WaveHC wave; // This is the only wave (audio) object, since we will only play one at a time #define DOORBELL 6 #define REAR_DOORBELL 7 #define DEBOUNCE 5 // button debouncer int doorbellState = 0; int reardoorbellState = 0; // here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc byte buttons[] = {14, 15, 16, 17, 18, 19}; // This handy macro lets us determine how big the array up above is, by checking the size #define NUMBUTTONS sizeof(buttons) // we will track if a button is just pressed, just released, or 'pressed' (the current state volatile byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS]; // this handy function will return the number of bytes currently free in RAM, great for debugging! int freeRam(void) { extern int __bss_end; extern int *__brkval; int free_memory; if((int)__brkval == 0) { free_memory = ((int)&free_memory) - ((int)&__bss_end); } else { free_memory = ((int)&free_memory) - ((int)__brkval); } return free_memory; } void sdErrorCheck(void) { if (!card.errorCode()) return; putstring("\n\rSD I/O error: "); Serial.print(card.errorCode(), HEX); putstring(", "); Serial.println(card.errorData(), HEX); while(1); } //////////////////////////////////////////////////////////////////////////////////////////// void setup() { byte i; // set up serial port Serial.begin(9600); putstring_nl("WaveHC with "); Serial.print(NUMBUTTONS, DEC); putstring_nl("buttons"); putstring("Free RAM: "); // This can help with debugging, running out of RAM is bad Serial.println(freeRam()); // if this is under 150 bytes it may spell trouble! // Set the output pins for the DAC control. This pins are defined in the library pinMode(2, OUTPUT); pinMode(3, OUTPUT); pinMode(4, OUTPUT); pinMode(5, OUTPUT); pinMode(DOORBELL, INPUT_PULLUP); pinMode(REAR_DOORBELL, INPUT_PULLUP); // Make input & enable pull-up resistors on switch pins for (i=0; i< NUMBUTTONS; i++) { pinMode(buttons[i], INPUT); digitalWrite(buttons[i], HIGH); } // if (!card.init(true)) //play with 4 MHz spi if 8MHz isn't working for you if (!card.init()) //play with 8 MHz spi (default faster!) { putstring_nl("Card init. failed!"); // Something went wrong, lets print out why sdErrorCheck(); while(1); // then 'halt' - do nothing! } // enable optimize read - some cards may timeout. Disable if you're having problems card.partialBlockRead(true); // Now we will look for a FAT partition! uint8_t part; for (part = 0; part < 5; part++) { // we have up to 5 slots to look in if (vol.init(card, part)) break; // we found one, lets bail } if (part == 5) { // if we ended up not finding one :( putstring_nl("No valid FAT partition!"); sdErrorCheck(); // Something went wrong, lets print out why while(1); // then 'halt' - do nothing! } // Lets tell the user about what we found putstring("Using partition "); Serial.print(part, DEC); putstring(", type is FAT"); Serial.println(vol.fatType(),DEC); // FAT16 or FAT32? // Try to open the root directory if (!root.openRoot(vol)) { putstring_nl("Can't open root dir!"); // Something went wrong, while(1); // then 'halt' - do nothing! } // Whew! We got past the tough parts. putstring_nl("Ready!"); TCCR2A = 0; TCCR2B = 1<<CS22 | 1<<CS21 | 1<<CS20; //Timer2 Overflow Interrupt Enable TIMSK2 |= 1<<TOIE2; delay(1000); playcomplete("HELLOWOR.WAV"); //after boot, play "HELLO" } ///////////////////////////////////////////////////////////////////////////////////////////// SIGNAL(TIMER2_OVF_vect) { check_switches(); } void check_switches() { static byte previousstate[NUMBUTTONS]; static byte currentstate[NUMBUTTONS]; byte index; for (index = 0; index < NUMBUTTONS; index++) { currentstate[index] = digitalRead(buttons[index]); // read the button /* Serial.print(index, DEC); Serial.print(": cstate="); Serial.print(currentstate[index], DEC); Serial.print(", pstate="); Serial.print(previousstate[index], DEC); Serial.print(", press="); */ if (currentstate[index] == previousstate[index]) { if ((pressed[index] == LOW) && (currentstate[index] == LOW)) { // just pressed justpressed[index] = 1; } else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) { // just released justreleased[index] = 1; } pressed[index] = !currentstate[index]; // remember, digital HIGH means NOT pressed } //Serial.println(pressed[index], DEC); previousstate[index] = currentstate[index]; // keep a running tally of the buttons } } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// void loop() {//DOORBELL=high: off; DOORBELL=low: song plays int doorbellState = digitalRead(DOORBELL); int reardoorbellState = digitalRead(REAR_DOORBELL); // Serial.println(doorbellState); while((doorbellState == 1) && (reardoorbellState == 1)) //while button input pin (A5) is HIGH, read the state of A5. If state is HIGH, stay in braces. { doorbellState = digitalRead(DOORBELL); reardoorbellState = digitalRead(REAR_DOORBELL); // Serial.print(doorbellState); // Serial.println("inWhileloop"); } if(doorbellState == 0) //front doorbell { playcomplete("DOORBELL.WAV"); } else //rear doorbell { playcomplete("LOUIELOU.WAV"); } } /////////////////////////////////////////////////////////////////////////////////////////////////// // Plays a full file from beginning to end with no pause. void playcomplete(char *name) { // call our helper to find and play this name playfile(name); while (wave.isplaying) { // do nothing while its playing } // now its done playing } void playfile(char *name) { // see if the wave object is currently doing something if (wave.isplaying) {// already playing something, so stop it! wave.stop(); // stop it } // look in the root directory and open the file if (!f.open(root, name)) { putstring("Couldn't open file "); Serial.print(name); return; } // OK read the file and turn it into a wave object if (!wave.create(f)) { putstring_nl("Not a valid WAV"); return; } // ok time to play! start playback wave.play(); } |