Birdie/Qwail work in progress…

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

Img_5597

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

Img_5609

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);
    }

  }
}