試作したGateEXは、Korg SQ-1とつないで自作のKIK01にSync信号を送ると、SQ-1のSync信号が疎で特にハットの刻みが少なくイマイチでした。Sync信号の周期を分割してもっと細かくGate信号を送出できるように改良しました。
SQ-1から送られてくるSync信号の間隔を測定し、分割数で割った間隔でタイマ割り込みをかけ、Gate信号を送出するという動作にしました。
ハードウェアの変更は行わず、変更はファームウェアのみです。Gateタイムを設定していたPOTで、分割数を設定するように変更しました。自作のKIK01は信号の立ち上がりしか見ていないのでGateタイムはSQ-1のSync信号と同じく15msに固定しました。
Gateオフのタイミングと分割したGate出力のタイミングを同じMsTimer2でとっています。Gateオフ時に次のGate信号のTimer割り込みを設定しており、図のようにタイマ割り込みまでの待ち時間はInterval - PULSE_WIDTH[ms]となります。
1回目のGate信号送出はSync信号のハードウェア割り込み時となるため、MsTimer2によるタイマ割り込みは2回め以降になります。「1/1」の場合はタイマ割り込みは行われません。
また、前回のファームウェアではDIPスイッチとシーケンスの割当が逆順になっていました。本来は左から右へ再生されるべきが、右から左の順になっていました。意外とわからないものですw
Arduinoのスケッチ <Gate_Sequencer_02.ino>
// // Gate Sequencer // Sync-in -> Gate sequence // Split Sync-in // // 2021.07.25 // #include <MsTimer2.h> #define PIN_SYNC_IN (2) #define PIN_GATE_OUT (12) #define PIN_GATE_LED (11) #define PIN_DIVISION (A0) #define CNT_N (8) #define PULSE_WIDTH (15) byte sequence[CNT_N] = {0}; int cnt = 0; int division = 1; int divisionCnt = 0; int interval = 0; void gateOff() { digitalWrite(PIN_GATE_OUT, LOW); digitalWrite(PIN_GATE_LED, LOW); if (divisionCnt > 0) { divisionCnt--; MsTimer2::set(interval - PULSE_WIDTH, stepOne); MsTimer2::start(); } } void stepOne() { digitalWrite(PIN_GATE_OUT, sequence[cnt]); digitalWrite(PIN_GATE_LED, sequence[cnt]); cnt++; if (cnt >= CNT_N) { cnt = 0; } MsTimer2::set(PULSE_WIDTH, gateOff); MsTimer2::start(); } void step() { static uint32_t prevTime = 0; uint32_t now = millis(); interval = (now - prevTime) / division; prevTime = now; divisionCnt = division; stepOne(); divisionCnt--; } void setup() { pinMode(PIN_SYNC_IN, INPUT); pinMode(PIN_GATE_OUT, OUTPUT); pinMode(PIN_GATE_LED, OUTPUT); // DIP switch pinMode(3, INPUT_PULLUP); pinMode(4, INPUT_PULLUP); pinMode(5, INPUT_PULLUP); pinMode(6, INPUT_PULLUP); pinMode(7, INPUT_PULLUP); pinMode(8, INPUT_PULLUP); pinMode(9, INPUT_PULLUP); pinMode(10, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(PIN_SYNC_IN), step, RISING); } void loop() { // Read DIP switch sequence[0] = !digitalRead(10); sequence[1] = !digitalRead(9); sequence[2] = !digitalRead(8); sequence[3] = !digitalRead(7); sequence[4] = !digitalRead(6); sequence[5] = !digitalRead(5); sequence[6] = !digitalRead(4); sequence[7] = !digitalRead(3); // Read division division = analogRead(PIN_DIVISION) / 256 + 1; // 1 ~ 4 }
入出力波形
ch1:Sync-in ch2:Gate-out
SQ-1のSpeedを最速にし、GateExのDivisionを1/4に設定。
メモ
オシロで出力波形を観測すると、ジッターというか波形の間隔が揺れることがあります。millis()ではなくmicros()関数、MsTimer2ではなくTimer1を使うようにして(us単位で制御できる)分解能を上げると改善するかもしれません。
ハードウェアを改修するなら、押すとシーケンスの頭から再生し直す(シーケンス・リセット)ボタンがあると良さそうです。SQ-1のシーケンスとは1音単位では同期していますが、フレーズとしてはズレてしまいます。SQ-1側のスタート/ストップで一応は対応できます。
0 件のコメント:
コメントを投稿