SX-150 を Arduino で制御する(お手軽版) [電子工作]

RIMG0937.JPG

組み立ても完了し無事完了し、いろいろ遊んでいましたが、やはり演奏が難しいので、Arduinoで制御する方法をいろいろ調べました。
参考にしたのは、Make: Japan: HOW TO - 学研SX-150をArduinoでコントロールしようで紹介されていたやりかた。

オリジナルの接続はまどろっこしいので、思い切ってシンプルに改造。
シリアルによるPCとの接続を省略して、直接Arduinoのソースからコントロールさせます。
音階の制御データ(オリジナルではシリアルで渡される)は、int型で一オクターブが+12となるので、自分なりの制御をするのは非常に簡単です。

DAコンバータ(MCP4921)は入手が困難なので、秋月でMCP4922を購入(約200円)。
4921が2個入りでお得ですが、今回は例にならって片チャンネルのみ使用します。

(1) 回路を組む。

SX-150のテスター棒とEXT.SOURCEを、みの虫クリップで接続します。RIMG0939.JPGRIMG0938.JPG





ブレッドボード上にMCP4922等を配置します。LEDはタイミング表示用の飾りなので省略しても良いです。
回路図はこのようになります。
SX-150-Arduino.jpg



(2) Arduino
ArduinoとMCP4922はSPIという方式での接続になるようです。こちらはまだArduinoではライブラリ化されていないので、サンプルのソースをそのままで行くことにします。
Serial処理部分を「がっつり」除去して、簡単なベースラインを演奏するようにしています。
void loop()
{
  NOTE(24); 
  NOTE(24+12);

この例は関数NOTE()の引数で音の高さを指定しています。1オクターブ上はプラス12になります。音の長さは固定です。これだけでもかなり70年代シークエンサー風の演奏が楽しめます。

(3)完成!

動作中の動画をYouTubeにアップしました。Arduinoって本当に便利。





[2009/2/3追記]
SPIインターフェースについてまじめに勉強するのであれば下記リンク先が参考になりそう。
Interfacing a Serial EEPROM Using SPI (Arduino.cc)
[2009/2/4追記]
MrBookさんのオリジナルBLOG(英文)のリンク先を

<参考>ソースコード
・ベースとなったソースのオリジナル照会元(英文)
//  SX-150 Controler 
//  Original Source created by Mrbook
//      http://mrbook.org/blog/2008/11/22/controlling-a-gakken-sx-150-synth-with-arduino/
#define DATAOUT 11//MOSI
#define DATAIN 12//MISO - not used, but part of builtin SPI
#define SPICLOCK  13//sck
#define SLAVESELECT 10//ss

#define LEDPin 8

void setup()
{
  byte clr;
  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK,OUTPUT);
  pinMode(SLAVESELECT,OUTPUT);
  digitalWrite(SLAVESELECT,HIGH); //disable device
  
  SPCR = (1&<&<SPE)|(1&<&<MSTR);
  clr=SPSR;
  clr=SPDR;
  delay(10);

  pinMode(LEDPin, OUTPUT);      // sets the digital pin as output
  digitalWrite(LEDPin,LOW);

  Serial.begin(9600);
}

void write_value(uint16_t sample)
{
  uint8_t dacSPI0 = 0;
  uint8_t dacSPI1 = 0;
  dacSPI0 = (sample &>&> 8) & 0x00FF;
  dacSPI0 |= 0x10;
  dacSPI1 = sample & 0x00FF;
  digitalWrite(SLAVESELECT,LOW);
  SPDR = dacSPI0;                    // Start the transmission
  while (!(SPSR & (1&<&<SPIF)))     // Wait the end of the transmission
  {
  };
  
  SPDR = dacSPI1;
  while (!(SPSR & (1&<&<SPIF)))     // Wait the end of the transmission
  {
  };  
  digitalWrite(SLAVESELECT,HIGH);
  delay(5);
}

void playNote(int incomingByte)
{
  int diff = 48 - incomingByte;
  diff *= 12;
  write_value (1125 - diff);
  // 1270 C4 60
  // 1125 C3 48
  // 980  C2 36    
  // 835  C1 24 
  // 690  C0 12      
}
void noteOff()
{
  write_value(0);
}
int incomingByte = 0;

void NOTE(int r) {
  static int flg=HIGH;

  if (flg == HIGH) {
    flg=LOW;
  } else {
    flg=HIGH;
  }

  digitalWrite(LEDPin,flg);
  playNote(r);
  delay(180);
  noteOff();
}


void loop()
{
  NOTE(24); 
  NOTE(24+12);
  NOTE(19);
  NOTE(19+12);
  NOTE(21);
  NOTE(21+12);
  NOTE(22);
  NOTE(22+12);


}




nice!(0)  コメント(0)  トラックバック(0) 
共通テーマ:趣味・カルチャー

nice! 0

コメント 0

コメントを書く

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

トラックバック 0

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