HAGIWO MOD1用にプログラミングしたウィンドウ・コンパレータ×シフトレジスタです。
ウィンドウ・コンパレータは、ある一定の電圧の間にある電気信号をゲート信号に変換するモジュールです。
例えば、5VのLFOを入力し、3V以上でウィンドウを設定した場合、出力からは3−5Vの範囲内に電気信号がある時のみゲート信号が出力されます。
用途としては、CVシーケンスで1オクターブ以上でエフェクトをかけたい、などのシーンで役立ちます。
また、本モジュールにはシフトレジスト機能も追加しています。通常のウィンドウコンパレータでは、入力電圧によってテンポシンクが難しいですが、F2にトリガーを入力することで、トリガーのタイミングでゲートが出力されます。ゲートはPOT3ノブによって最大8ビット遅延可能です。
注意事項:chatGPTで作成したプロンプトです。プログラミング知識は一切ないため、動作の安定性は保証はできません。趣味用途でお使いください
[機能紹介]
※0V-5Vの範囲で入力電圧を測定し、5Vのゲート信号を出力する。
※トリガーを入力した場合、出力がシフトレジスタを通過して、トリガータイミングに揃ったゲート信号が出力される。
POT1:SHIFT(ウィンドウの中心を決定)
POT2:SIZE(ウィンドウの幅を制御)
POT3:F2にトリガーを入力したとき、F3、F4はシフトレジストして出力される。出力タイミングはノブで1ビット-8ビットまで選択可能
F1:CV IN
F2:トリガーIN(入力がない場合は通常のコンパレータとして使える)
F3:コンパレート出力
F4:F3のNOT出力
LED:F3に連動する
[プログラム](ArduinoでMOD1にプログラミングしてください)
// Pin definitions
const int shiftKnob = A0; // SHIFT control knob
const int sizeKnob = A1; // SIZE control knob
const int shiftRegKnob = A2; // Shift register control knob
const int inputVoltage = A3; // Voltage input pin (D17 on Nano)
const int triggerInput = 9; // Trigger input pin
const int gateOutput = 10; // Gate output pin
const int notOutput = 11; // NOT gate output pin
const int ledIndicator = 3; // LED indicator output pin (same PWM as D10)
// Variables
float shiftValue = 0;
float sizeValue = 0;
int shiftRegValue = 0;
bool shiftRegisterEnabled = false;
byte shiftRegisterState = 0;
bool lastTriggerState = LOW;
unsigned long lastTriggerTime = 0;
const unsigned long triggerTimeout = 500; // Timeout in ms to return to normal mode
float smoothShift = 0;
float smoothSize = 0;
const float alpha = 0.05; // Smoothing factor (0: no smoothing, 1: instant)
void setup() {
pinMode(triggerInput, INPUT);
pinMode(gateOutput, OUTPUT);
pinMode(notOutput, OUTPUT);
pinMode(ledIndicator, OUTPUT);
}
void loop() {
// Read and smooth control knobs
int rawShift = analogRead(shiftKnob);
int rawSize = analogRead(sizeKnob);
// Apply exponential smoothing
smoothShift = alpha * rawShift + (1 – alpha) * smoothShift;
smoothSize = alpha * rawSize + (1 – alpha) * smoothSize;
// Map smoothed values from 0–1023 to 0–5000 mV for 0–5V input range
shiftValue = map(smoothShift, 0, 1023, 0, 5000);
sizeValue = map(smoothSize, 0, 1023, 0, 5000); // Max window width 5V
shiftRegValue = constrain(analogRead(shiftRegKnob) / 128, 1, 8); // 1-8 bit range
// Read input voltage assuming 0V to 5V mapped to 0–1023
int inputVal = analogRead(inputVoltage); // 0-1023
int voltage = map(inputVal, 0, 1023, 0, 5000); // 0 to 5000 mV (0V to 5V)
// Calculate window in mV
int lowerBound = shiftValue – (sizeValue / 2);
int upperBound = shiftValue + (sizeValue / 2);
// Determine comparator result
bool gateState = (voltage >= lowerBound && voltage <= upperBound);
// Read trigger
bool triggerState = digitalRead(triggerInput);
// On rising edge, sample gate state and shift
if (triggerState == HIGH && lastTriggerState == LOW) {
shiftRegisterEnabled = true;
lastTriggerTime = millis();
bool sampledGateState = gateState;
shiftRegisterState = (shiftRegisterState << 1) | sampledGateState;
shiftRegisterState &= (1 << shiftRegValue) – 1;
}
lastTriggerState = triggerState;
// Disable shift register mode after timeout
if (millis() – lastTriggerTime > triggerTimeout) {
shiftRegisterEnabled = false;
}
// Output gate or shifted gate
bool finalGateState;
if (shiftRegisterEnabled) {
finalGateState = (shiftRegisterState >> (shiftRegValue – 1)) & 1;
} else {
finalGateState = gateState;
}
digitalWrite(gateOutput, finalGateState);
digitalWrite(notOutput, !finalGateState);
// LED indicator follows gate output (PWM)
analogWrite(ledIndicator, finalGateState ? 255 : 0);
}