SSブログ

カエル 4匹 [Arduino]

前回のスケッチをいじって、圧電サウンダを4つ使い本当に輪唱にしてみました。
kaeru4.jpg

tone()では和音ができないようなので、1:1 dutyの矩形波を4つ自作しました。
digitalWrite()は処理に時間がかかるので、ポートを直接操作することにしました。
また今回分かったことですが、intではなく、unsigned intにすることでも高速化できました。

// カエルの歌 (4つの圧電サウンダ使用バージョン)
#define Do 262
#define Re 294
#define Mi 330
#define Fa 349
#define So 392
#define La 440
#define Ti 494

int kaeru[] = {
  Do,  0, Re,  0, Mi,  0, Fa,  0, Mi,  0, Re,  0, Do,  0,  0,  0,
  Mi,  0, Fa,  0, So,  0, La,  0, So,  0, Fa,  0, Mi,  0,  0,  0,
  Do,  0,  0,  0, Do,  0,  0,  0, Do,  0,  0,  0, Do,  0,  0,  0,
  Do, Do, Re, Re, Mi, Mi, Fa, Fa, Mi,  0, Re,  0, Do,  0,  0,  0 };
unsigned int kaeruT[128][4];          // 一音ごとの周期 T/10000
unsigned int t, part, i, bzData;

void setup() {
  for (t = 0; t < 128; t++) {
    for(part = 0; part < 4; part++) {
      kaeruT[t][part] = 65535;        // 無音で初期化、無音のときは周期は無限大(≒ 65535)
      if( (t/16-part+4)/4 == 1 ) {    // パートの演奏時間帯の場合
        if( kaeru[t-part*16] ) kaeruT[t][part] = 10000 / kaeru[t-part*16]; // 音があれば周期を指定
      }
    }
  }
  DDRD = DDRD | B11111100;            // ピン2~7を出力に設定
}

void loop() {
  for (t = 0; t < 128; t++) {
    for(i = 0; i < 5000; i++) {
      bzData = 0;                     // 出力するデータ初期化
      for(part = 0; part < 4; part++) {
        if( i % kaeruT[t][part] > kaeruT[t][part]/2 ) bzData |= 1 << part;
      }
      PORTD = bzData << 2;            // ピン2~5 に出力
    }
  }
}

周期T(kaeruT)は、10000 を周波数で割った値にしましたが、10000には根拠はありません。なんとなくきれいに聞こえた値です。(音程の周波数は適当です)


タグ: カエル
nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

カエルの輪唱踏切カンカン ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。