前回の記事でも言ってましたが、なんか音の出るものを作りたかったのでその開発をしてみました。

 インターフェースを面白くしたかったのですが、技術力が足りないのでいつか使った"CapSense"を使いました。

 1オクターブは12音なので、これをCapSenceで読み取るには12個のデジタルピンが必要になります。これは一台のArduino UNOで扱うのは厳しいです。また、なるべく出力側のコードは軽くしたいので、Arduino MEGAも使い、Arduino2台体制で作ることになりました。そのほかにもいろいろこだわりがあり、大まかなシステムはこのようになりました。electronium
 今回初めて知ったのですが、Arduino MEGAはSCL,SDAはD20,D21ピンでUNOとは違うのでその点注意しなければなりません。

DSC01284
DSC01283
 LCDを使いたかったのはただの趣味です。
________________________________
|押してるキー 選択してるオクターブ |
|出力周波数                                            |
|_______________________________|
 こんな感じに表示させます。

DSC01281
 入力インターフェースはこんな感じです。
 前に書いた記事のセンサーを大量に並べただけです。


 プログラムはこのようになりました。難しいことは何もやってません。
・Master
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F, 16, 2); // I2C: 0x3F, 16x2 LCD

int ca, cb;
int freq;
void setup() {
  Wire.begin();
  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
  pinMode(13, OUTPUT);
}

void loop() {
  Wire.requestFrom(8, 2);

  while (Wire.available()) {
    ca = Wire.read();
    cb = Wire.read();
    Serial.print(ca);
    Serial.print(",");
    Serial.println(cb);
  }


  lcd.setCursor(0, 0);
  if (ca < 10) {
    lcd.print(" ");
  }
  lcd.print(ca);
  lcd.setCursor(3, 0);
  lcd.print(cb);

  lcd.setCursor(0, 1);
  freq = 440 * pow(2, (ca + 3 + (cb - 2) * 12) / 12.0);
  if (ca == 13) {
    lcd.print("No Sounds");
    delay(10);
    noTone(13);
  } else {
    if (freq < 1000) {
      lcd.print(" ");
    }
    lcd.print(freq);
    lcd.print("Hz   ");
    tone(13, freq);
  }
  delayMicroseconds(1000000 / freq);
}

・Slave
#include <Wire.h>
#include <CapSense.h>

#define thre 60

CapSense   cs_35_22 = CapSense(35, 22);
CapSense   cs_35_23 = CapSense(35, 23);
CapSense   cs_35_24 = CapSense(35, 24);
CapSense   cs_35_25 = CapSense(35, 25);
CapSense   cs_35_26 = CapSense(35, 26);
CapSense   cs_35_27 = CapSense(35, 27);
CapSense   cs_35_28 = CapSense(35, 28);
CapSense   cs_35_29 = CapSense(35, 29);
CapSense   cs_35_30 = CapSense(35, 30);
CapSense   cs_35_31 = CapSense(35, 31);
CapSense   cs_35_32 = CapSense(35, 32);
CapSense   cs_35_33 = CapSense(35, 33);
CapSense   cs_35_34 = CapSense(35, 34);

CapSense   cs_38_36 = CapSense(38, 36);
CapSense   cs_38_37 = CapSense(38, 37);

int freqa;
int freqb=3;
int numbb=2;

void setup() {
  Wire.begin(8);
  Wire.onRequest(requestEvent);
}

void loop() {
  int tonea[14];
  tonea[0] =  cs_35_22.capSense(30);
  tonea[1] =  cs_35_23.capSense(30);
  tonea[2] =  cs_35_24.capSense(30);
  tonea[3] =  cs_35_25.capSense(30);
  tonea[4] =  cs_35_26.capSense(30);
  tonea[5] =  cs_35_27.capSense(30);
  tonea[6] =  cs_35_28.capSense(30);
  tonea[7] =  cs_35_29.capSense(30);
  tonea[8] =  cs_35_30.capSense(30);
  tonea[9] =  cs_35_31.capSense(30);
  tonea[10] =  cs_35_32.capSense(30);
  tonea[11] =  cs_35_33.capSense(30);
  tonea[12] =  cs_35_34.capSense(30);
  tonea[13] = 0;
  
  int toneb[6];
  toneb[0] =  cs_38_36.capSense(30);
  toneb[1] =  cs_38_37.capSense(30);
  toneb[2] = 0;
  
  int numa = 13;
  int numb = 2;

  for (int i = 0; i < 13; i++) {
    if (tonea[i] > tonea[numa]) {
      numa = i;
    }
  }
  if (tonea[numa] < 60) {
    numa = 13;
  }
  freqa = numa;
  
  for (int i = 0; i < 2; i++) {
    if (toneb[i] > toneb[numb]) {
      numb = i;
    }
  }
  if (toneb[numb] < 60) {
    numb = 2;
  }
  
  if(numbb==2 && numb==0 &&freqb>0){
    freqb--;
  }
  
  if(numbb==2 && numb==1 &&freqb<4){
    freqb++;
  }
  
  numbb=numb;
  
  delay(10);
}

void requestEvent() {

  Wire.write(freqa);
  Wire.write(freqb);
}

 こんな感じです。適当なプログラムですが、自分では満足しているのでよしとします。

 ほんとはこれにフィルターとかエフェクターとか掛けようとも思っていたんですが、自分に音楽センスがないので止めました。その代わりなんか面白いことできないかと思ってたんですが、モーターを鳴らしたことがなかったので鳴らしてみました。
 まあただ出力信号を2sk2232で増幅してモーターに流すだけです。
 こんな感じでなります。

 今回はここまでです。なんか全然まとまってないんですがまあいいです。最近はデスク周りの整備をしたので次回はその記事でも書きます。それではまた今度。