I've scrapped the Winbond, which is both good and bad. The Winbond would have been great for making bird sounds, but the Arduino Mini is so much more compact and easy to work with. It makes sound too, but the computery noises it makes are not very bird-like. In fact, they're just downright annoying.
I'm using the Play Melody code from an Arduino tutorial to get started. I had to add a couple of extra octaves (by halving the frequency of each tone for each octave), and now I'm working on getting the melody to play at the appropriate time.
Right now my code will play a little ditty after 15 seconds if someone is not in front of the IR sensor. I need more parameters, but it's not bad for a proof of concept. Consider is an implementation prototype.
My code is after the jump, by the way
Some photos:
The Whole Mess
Here is my arudino mini, hooked up to the arduino as a usb connector. Also featured within the mess of wires is an IR sensor, a speaker (bigger than the one I'll end up using, actually), and some fine LEDS to help me figure out what's going on when). The Red LED comes on when the IR is on and reading something is close, and Yellow LED comes on when the IR is reading that nothing is in front of it anymore.
A Close Up
This is just a close up shot of the Arduino Mini, connected to things. I'll be taking it off of the bread board as soon as I'm happy with my code. Until then, it stays, which unfortunately is holding me back from making Birdie look and feel prototypes.
A video is coming soon!!
/*Play Melody
* -----------
*/
// TONES ==========================================
// Start by defining the relationship between
// note, period, & frequency.
#define c 3830 // 261 Hz
#define d 3400 // 294 Hz
#define e 3038 // 329 Hz
#define f 2864 // 349 Hz
#define g 2550 // 392 Hz
#define a 2272 // 440 Hz
#define b 2028 // 493 Hz
#define C 1912 // 523 Hz
#define D 1700
#define E 1519
#define F 1432
#define G 1275
#define A 1136
#define B 1014
#define CC 956
#define DD 850
#define EE 759
#define FF 716
#define GG 637
#define AA 568
#define BB 507
#define CCC 478
#define DDD 425
#define DDDS 441
#define EEE 379
// Define a special note, 'R', to represent a rest
#define R 0
#define NUMREADINGS 50
// SETUP ============================================
int readings[NUMREADINGS]; // the readings from the analog input
int index = 0; // the index of the current reading
int total = 0; // the running total
int average = 0; // the average
int closeValue = 0;
int speakerOut = 9; // Set up speaker on a PWM pin
int irSensor = 3;
int DEBUG = 1; // Do we want debugging on serial out? 1 for yes, 0 for no
int redLED = 8;
int otherLED = 6;
void setup() {
pinMode(speakerOut, OUTPUT);
pinMode(irSensor, INPUT);
if (DEBUG) {
Serial.begin(9600); // Set serial out if we want debugging
for (int i = 0; i < NUMREADINGS; i++)
readings[i] = 0; // initialize all the readings to 0
}
}
// MELODY and TIMING =======================================
// melody[] is an array of notes, accompanied by beats[],
// which sets each note's relative length (higher #, longer note)
//birdy1
//int melody[] = { e, g, C, e, g, C, R, e, g, C };
//int beats[] = { 16, 16, 16, 8, 8, 8, 32, 16, 16, 16, };
//int melody[] = { C, D, E, F, G, A, B, R };
//int beats[] = { 8, 8, 8, 8, 8, 8, 8, 16 };
//int melody[] = { CC, DD, EE, FF, GG, AA, BB, CCC, DD, CCC, DD, CCC, DD, R };
//int beats[] = { 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 16 };
//birdy2
//int melody[] = { BB, BB, AA, AA, AA, AA, AA , AA, AA, EEE, R };
//int beats[] = { 32, 32, 16, 16, 16, 16, 16, 16, 16 , 16, 32, 8 };
//int melody[] = { DDD, CCC, DDD, CCC, CCC, R, DDD, CCC, DDD, CCC, DDD, CCC, R };
//int beats[] = { 16, 32, 16, 32, 16, 16, 16, 32, 16, 32, 16, 32 , 8};
int melody[]= {B, D, G, R};
int beats[] = {32, 32, 64, 64};
int MAX_COUNT = sizeof(melody) / 2; // Melody length, for looping.
long tempo = 10000; // Set overall tempo
int pause = 1000; // Set length of pause between notes
int rest_count = 100; //// Loop variable to increase Rest length <-BLETCHEROUS HACK; See NOTES
// Initialize core variables
//int tone = 0;
//int beat = 0;
//long duration = 0;
// PLAY TONE ==============================================
// Pulse the speaker to play a tone for a particular duration
void playTone(int tone, long duration) {
long elapsed_time = 0;
if (tone > 0) { // if this isn't a Rest beat, while the tone has
// played less long than 'duration', pulse speaker HIGH and LOW
while (elapsed_time < duration) {
digitalWrite(speakerOut,HIGH);
delayMicroseconds(tone / 2);
// DOWN
digitalWrite(speakerOut, LOW);
delayMicroseconds(tone / 2);
// Keep track of how long we pulsed
elapsed_time += (tone);
}
}
else { // Rest beat; loop times delay
for (int j = 0; j < rest_count; j++) { // See NOTE on rest_count
delayMicroseconds(duration);
}
}
}
// LET THE WILD RUMPUS BEGIN =============================
void loop() {
int milliSeconds = millis();
analogWrite(redLED, 255);
analogWrite(otherLED, 0);
//averaging code taken from M Bethancourt's divine 3 LED IR code
total -= readings[index]; // subtract the last reading
readings[index] = analogRead(irSensor); // read from the sensor
total += readings[index]; // add the reading to the total
index = (index + 1); // advance to the next index
if (index >= NUMREADINGS) // if we're at the end of the array...
index = 0; // ...wrap around to the beginning
average = total / NUMREADINGS; // calculate the average
Serial.println(average); // send it to the computer (as ASCII digits)
closeValue = average;
// Set up a counter to pull from melody[] and beats[]
if(closeValue <80){
analogWrite(redLED, 0);
analogWrite(otherLED, 255);
if (milliSeconds > 15000){
for (int i=0; i<50; i++) {
int tone = melody[i];
int beat = beats[i];
long duration = beat * tempo; // Set up timing
playTone(tone, duration);
// A pause between notes...
delayMicroseconds(pause);
}
}
if (DEBUG) {
Serial.print("IR: ");
Serial.println(analogRead(irSensor));
Serial.print("Milli: ");
Serial.println(milliSeconds);
}
}
}
Comments
You can follow this conversation by subscribing to the comment feed for this post.