読者です 読者をやめる 読者になる 読者になる

久々の電子工作

といっても 電子工作っぽいことは終わっているので プログラミングだったりしますがw

今回は和音を鳴らす前段階として、複数の音を合成して鳴らすというのに挑戦してみました。

武器としてはDACを予定していたのだが、使い方はわかったもののいろいろ処理が追いつかない予感がしたので(僕の技量不足)原点回帰ということでPWMを使うことにした。

PWMを変化する周期を制御し複数の音が鳴るように調整した。

3つの音が合成されるようにし、そのそれぞれをスライドバー、ボリューム(つまみ)で調整できるようにした(本当は全部スライドバーにしたかったんだけど家になかった)

ずっと鳴っているとうるさいので、タクトスイッチを押している間音が鳴るようにした。

アンプ回路や、Arduinoを構成する部分は前回の電子工作で作った部分そのままだったので楽チンだった


前回(http://d.hatena.ne.jp/inajob/20090712)は単音しかならなかったのでまぁ大きな進歩といえよう、前回は(http://d.hatena.ne.jp/nishiohirokazu/20090713/1247458741)こんな風にメロディICを使った人もいた。楽そうでいいなぁ。しかしこうやってPWMでちろちろ鳴らすのも味があって良いではないかと思うのだった。(負け惜しみ)



結構和音が鳴ったのがうれしくて思わず動画にしてしまった。
NiVE( http://nicoae.if.land.to/ )が使いやすくてびっくりだ。

ニコニコ動画より
D
http://www.nicovideo.jp/watch/sm8955384

覚書的にソースもはっつけておく(Arduinoのソースです)

これで動かして壊れたとか言われても僕は知らないよ!
突っ込みとか待ってますw

int ledPin =  7;    // LED connected to digital pin 13
int spkPin = 5;
int swPin = 8;

int anPin1 = 0;  //入力は3つ
int anPin2 = 1;
int anPin3 = 2;

void setup()   {                
  pinMode(ledPin, OUTPUT);
  pinMode(spkPin, OUTPUT); 

  pinMode(swPin,INPUT);
  digitalWrite(swPin,HIGH); //タクトスイッチ プルアップしておく
  TCCR0B = TCCR0B & 0b11111000 | 0x01; //PWMの周波数を最速に
}

//ここに値を積んでいく
short osc1 = 0;
short osc2 = 0;
short osc3 = 0;

void loop()                     
{
  int sw = digitalRead(swPin);
  if(sw==LOW){          //スイッチが押されていると音が鳴る (LOWって逆?)
    //調整できればなんでも良い
    //---------freq1------------>|
    //                 <--freq2--|
    //             <----freq3----|
    int freq1 = (analogRead(anPin2) >> 5) +8;    //8はおまじない
    int freq2 = -(analogRead(anPin1) >> 6) + freq1;
    int freq3 = -(analogRead(anPin3) >> 6) + freq1;

    for(int i=0;i<1000;i++){
      osc1 = (osc1+1)%(freq1);
      osc2 = (osc2+1)%(freq2);
      osc3 = (osc3+1)%(freq3);
      //足しても255を超えないように気をつける
      analogWrite(spkPin,(osc1*85/(freq1) + osc2*85 /(freq2) + osc3*85/(freq3)));
    }
  }
  else{
    analogWrite(spkPin,0);
  }
  digitalWrite(ledPin, HIGH);   // 動作確認用
}