見出し画像

$5 Random Trigger - DIY Eurorack Modular Synthesizer

背景

自作モジュラーシンセの71作品目。

今年度の目標に、ATTINYを使ったDIYがある。
ATTINYは小型のマイコンで、市販のユーロラックモジュラーシンセにも、このATTINYを使用したモジュールがいくつかある。
MCUの性能は低いが、小型で安価、かつArduinoで開発が可能という特徴がある。
小型のMCUが使えれば、今後のDIYの選択肢が増えると思い、挑戦に至った。

制作物のスペック

ユーロラック規格 3U 6HPサイズ
電源:25mA( 5V )

ランダムトリガーモジュール。
外部クロックを受けたら、指定した確率でトリガーを出力する。
トリガーの出力はランダムで遅延し、その遅延量もコントロールできる。
トリガーする確率と、遅延量は、指定したSTEP数で固定でき、音楽的な周期性を持たすことができる。

RATE POT:トリガーの確率の制御。0%~100%で設定。
DELAY POT:トリガーの出力遅延時間の倍率。0~1倍で設定。
STEP POT:確率周期のSTEP数の設定。N/Aは周期性なしとなる。
RESET SW:スイッチを押すと、周期性がリセットされる。

TRIGGER IN:外部トリガーの入力
TRIGGER OUT:ランダムトリガーの出力

周期性について

STEP POTの設定が4以上の場合、指定したSTEP数でトリガー確率は周期性をもつ。
周期性はRESET SWを押すと、リセットされる。
以下の図はトリガー確率のイメージ。RATE POTで赤線の閾値を上下させて、赤線より以下の値のSTEPではTrigger出力をする。

トリガー遅延について

STEP POTの設定が4以上の場合、指定したSTEP数でトリガー遅延は周期性をもつ。
周期性はRESET SWを押すと、リセットされる。
DELAY POTが0のとき、倍率(Delay rate)=0となり、遅延は無い。
DELAY POTが0.5のとき、最大で300msec * 0.5 = 150msec遅延となる。

製作費

総額約$5
---------------------------------
Front panel $1
ATTINY85 $1.5
可変抵抗 $0.3*3pcs
他(汎用部品は下記リンク先参照)

ハードウェア

使用したMCUはATTINY85。
ADCを3pin、I/Oを2pin使用している。
I/Oの電圧定格は-0.5~Vcc+0.5Vなので、BAT43で保護している。
電流定格は40mAあるので、1kohmの制限抵抗で問題ない。

ATTINYは5Vで動作し、出力電圧は5Vで、電流も十分流せるので、モジュラーシンセのトリガーとして使用することができる。
処理能力は他のMCUに劣るため、ゲート出力や、簡単なCV出力のプロジェクトで使用するのが最適だろう。

ATTINYのプログラムの書き込みは、Arduino Unoを経由した。書き込み方法は他のwebページで紹介されているので、ここでは割愛する。

宣伝:オープンソースプロジェクトの支援をお願いします

DIYモジュラーシンセのオープンソースプロジェクトを継続するために、patreonというサービスでパトロンを募集しています。
コーヒー一杯の支援をいただけると嬉しいです。
また、パトロン限定のコンテンツも配信しています。

ソースコード

粗末だが公開する。

int chance, stp, stp_length, stp_count, random_val, random_dly;
int old_stp_length = 999;
float dly;
int chance_table[32];
int dly_table[32];
bool trig, old_trig, trig_flg;
long timer;

void setup() {
  pinMode(0, OUTPUT); // pin5,output
  pinMode(1, INPUT); // pin6,trigger input
  pinMode(A1, INPUT); //ADC
  pinMode(A2, INPUT); //ADC
  pinMode(A3, INPUT); //ADC
  timer = millis();
}

void loop() {
  old_trig = trig;
  old_stp_length = stp_length;

  chance = 1023 - analogRead(A1);
  dly = min(1000, analogRead(A3)) * 0.001;
  stp = analogRead(A2);

  if (stp < 204) {
    stp_length = 0;
    old_stp_length = 999;
  }
  else if (204 <= stp && stp < 409) {
    stp_length = 4;
  }
  else if (409 <= stp && stp < 613) {
    stp_length = 8;
  }
  else if (613 <= stp && stp < 818) {
    stp_length = 16;
  }
  else if (813 <= stp) {
    stp_length = 32;
  }

  if (old_stp_length != stp_length) {//reset table value
    for (int i = 0; i <= 31; i++) {
      chance_table[i] = random(0, 1023);
      dly_table[i] = random(0, 300);// max 300msec delay
    }
    stp_count = 0;
  }

  trig = digitalRead(1);
  if (old_trig == 0 && trig == 1) {//add step count
    stp_count++;
    if (stp_count >= stp_length) {//step count reset
      stp_count = 0;
    }
    random_val = chance_table[stp_count];
    random_dly = dly_table[stp_count];
    trig_flg = 1;
    timer = millis();
  }

  if (trig_flg == 1 && timer + random_dly * dly < millis()) {
    if (random_val > chance) {
      digitalWrite(0, HIGH);//trigger out high
      delay(50);//trig pulse time
      digitalWrite(0, LOW);//trigger out low
      trig_flg = 0;
    }
  }

}

この記事が気に入ったらサポートをしてみませんか?