Skip to main content

Onuncu Yıl Marşı - Arduino

Bir önceki çalışmamızda sizlere Arduino'nun hazır melodilerinden dinletiler sunmuştuk.
Bu gün ise sınırları biraz daha zorlayıp Nokia 3310 Besteleyici deneyimime güvendiğim için kodları kurcalayarak bestelediğim Onuncu Yıl Marşı'nı bayrak sallayarak dinletmek istiyorum. Eğer gerçekten Onuncu Yıl Marşı olarak dinlerseniz öyle oluyor, lütfen biraz ön yargı :)
(3310'nun besteleyisinden kat be kat zor bir iş olduğunu itiraf etmeliyim)



Servo ucuna bağladığım bayrağı sürekli olarak bir sağa bir sola sallama isteğim, Tone.h kütüphanesinin Servo.h kütüphanesini yanında barındırmak istememesi üzerine sekteye uğradı. Timer hatası sebebiyle bunu yapamadım, fakat yılmadım servo'yu direkt melodi sinyalinin geldiği bacağa bağladım.

Bu ise her ne kadar dolu dolu bir bayrak sallayış olmasa da gönlümüzü etmeye yetiyor :)

Gerekli malzemeler:
  • Servo
  • Hoparlör
  • Bağlantı Kabloları
  • Olmazsa olmazımız bayrağımız.



Bağlantının nasıl yapılacağına gelecek olursak Hoparlörün sinyal bacağına servonun sinyal pinini de eklememiz yeterli.


Son bir sürpriz : Devreyi kurup kodu çalıştırdıktan sonra hoparlörü çıkarıp sinyali sadece servoya verin, ve dinleyin bakalım servodan nasıl sesler geliyor ?

Koda ulaşmak için :



#include <Tone.h>

Tone tone1;

#define OCTAVE_OFFSET 0

int notes[] = { 0,
NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4, NOTE_FS4, NOTE_G4, NOTE_GS4, NOTE_A4, NOTE_AS4, NOTE_B4,
NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5,
NOTE_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6,
NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7, NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7
};
char *song = "Onuncu yil:d=4,o=5,b=250:2c,8p.,g,2c,2a,2f,2d,2c,2p,2f,8p.,f,2d,8p.,a,2d,2c,2e,8p. ,2d,8p.,d,1f,e,8p.,f,c,2d,8p.,1e,2f,a,d,2c";

void setup(void)
{
  Serial.begin(9600);
  tone1.begin(9);
}

#define isdigit(n) (n >= '0' && n <= '9')

void play_rtttl(char *p)
{
  // Absolutely no error checking in here

  byte default_dur = 4;
  byte default_oct = 6;
  int bpm = 63;
  int num;
  long wholenote;
  long duration;
  byte note;
  byte scale;

  // format: d=N,o=N,b=NNN:
  // find the start (skip name, etc)

  while(*p != ':') p++;    // ignore name
  p++;                     // skip ':'

  // get default duration
  if(*p == 'd')
  {
    p++; p++;              // skip "d="
    num = 0;
    while(isdigit(*p))
    {
      num = (num * 10) + (*p++ - '0');
    }
    if(num > 0) default_dur = num;
    p++;                   // skip comma
  }

  Serial.print("ddur: "); Serial.println(default_dur, 10);

  // get default octave
  if(*p == 'o')
  {
    p++; p++;              // skip "o="
    num = *p++ - '0';
    if(num >= 3 && num <=7) default_oct = num;
    p++;                   // skip comma
  }

  Serial.print("doct: "); Serial.println(default_oct, 10);

  // get BPM
  if(*p == 'b')
  {
    p++; p++;              // skip "b="
    num = 0;
    while(isdigit(*p))
    {
      num = (num * 10) + (*p++ - '0');
    }
    bpm = num;
    p++;                   // skip colon
  }

  Serial.print("bpm: "); Serial.println(bpm, 10);

  // BPM usually expresses the number of quarter notes per minute
  wholenote = (60 * 1000L / bpm) * 4;  // this is the time for whole note (in milliseconds)

  Serial.print("wn: "); Serial.println(wholenote, 10);


  // now begin note loop
  while(*p)
  {
    // first, get note duration, if available
    num = 0;
    while(isdigit(*p))
    {
      num = (num * 10) + (*p++ - '0');
    }
    
    if(num) duration = wholenote / num;
    else duration = wholenote / default_dur;  // we will need to check if we are a dotted note after

    // now get the note
    note = 0;

    switch(*p)
    {
      case 'c':
        note = 1;
        break;
      case 'd':
        note = 3;
        break;
      case 'e':
        note = 5;
        break;
      case 'f':
        note = 6;
        break;
      case 'g':
        note = 8;
        break;
      case 'a':
        note = 10;
        break;
      case 'b':
        note = 12;
        break;
      case 'p':
      default:
        note = 0;
    }
    p++;

    // now, get optional '#' sharp
    if(*p == '#')
    {
      note++;
      p++;
    }

    // now, get optional '.' dotted note
    if(*p == '.')
    {
      duration += duration/2;
      p++;
    }
  
    // now, get scale
    if(isdigit(*p))
    {
      scale = *p - '0';
      p++;
    }
    else
    {
      scale = default_oct;
    }

    scale += OCTAVE_OFFSET;

    if(*p == ',')
      p++;       // skip comma for next note (or we may be at the end)

    // now play the note

    if(note)
    {
      Serial.print("Playing: ");
      Serial.print(scale, 10); Serial.print(' ');
      Serial.print(note, 10); Serial.print(" (");
      Serial.print(notes[(scale - 4) * 12 + note], 10);
      Serial.print(") ");
      Serial.println(duration, 10);
      tone1.play(notes[(scale - 4) * 12 + note]);
      delay(duration);
      tone1.stop();
    }
    else
    {
      Serial.print("Pausing: ");
      Serial.println(duration, 10);
      delay(duration);
    }
  }
}

void loop(void)
{
  play_rtttl(song);
  Serial.println("Done.");
  while(1);
}



Comments

Post a Comment

Popular posts from this blog

Artificial Horizon and Compass Using Arduino-Processing-MPU6050

Hi everyone, Today we will realize our artificial horizon using Arduino, Processing and MPU 6050 IMU. In this application I use Arduino Uno, If you should use different card, you should examine i2c communication for your card. For Arduino Uno connections will be like that: MPU6050 Pins       Arduino Uno Pins Vcc                        3.3V Gnd                       Gnd SCL                       A5 SDA                      A4 INT                       2 (Digital Pin) This my MPU6050, if you want more information about it: http://www.invensense.com/mems/gyro/documents/PS-MPU-6000A-00v3.4.pdf After it we connecting the MPU6050 to Arduino. If our Arduino-MPU6050 sy...

Görüntü işleme için Uçuş Denemesi

Merhabalar, Bu çalışmamızda havandan görüntü almak isteyen veyahut bu görüntüleri işlemek isteyen arkadaşlara referans olsun diye iki adet video paylaşacağım. Videoları kişisel bilgisayarınıza indirip görüntü işleme açısından çalışmalar yapabilirsiniz. Diğer taraftan yerde belirlediğimiz bir nesnenin boyutunun irtifa değerlerine göre ekranda kapladığı piksel değişimini inceleyebilirsiniz. Ya da en azından belirli irtifa değerlerinden nesneler ve insanların nasıl göründüğü hakkında genel kültür olur :) İlk videoda 70cm x 70cm beyaz bir levha kullanıldı, diğer taraftan oturan, ayakta ve yürüyen insan figürleri de videoda mevcut. Bunların çeşitli irtifa değerlerine göre dikey şekilde konumlandırılmış, yere doğru bakan kameradan nasıl göründüğü konusunda fikir sahibi olmanıza sebep olacağını düşünmekteyim. İkinci videoda 30-100 metre arasında dolaşan (genelinde 45 metre civarında) bir insansız hava aracından alınan görüntüler mevcut. Aşağı konumlandırılmış hedefler 70 cm x ...