2018年7月10日火曜日

Arduino EGの構想

Arduinoとアナログ処理部の組み合わせでエンベロープ・ジェネレーターを製作することにしました。

シミュレーション回路図

前回のシミュレーションでは「InvAttack」のスイッチング動作をAVRの3-State Bufferで行いましたが、一応MOS-FETでスイッチングしておくことにしました。

「Attack」信号がHになる時間は、AVRのADCで出力レベルを監視して制御しますが、シミュレーションでは固定しています。

過渡解析

Gate信号V(gate)からADSRエンベロープV(out)を作り出しています。

ブレッドボード配線図


ArduinoはAruduino Pro Mini(5V/16MHz版)を使用しました。

MOS-FET M1はシミュレーション回路図では2N7002になっていますが、2N7000を使いました。パッケージが違うだけで特性はほとんど同じです。

出力バッファ用のOPAMPは単電源OPAMPのNJM13404を使用しました。

A、R、Dとラベルを貼ってあるところの抵抗は10kΩ程度のPOTを使いますが、手持ちがないので固定抵抗で代用しました。Rsustainは10kΩ/Aです。

「GateIn」信号はSQR FG から出力しました。

Rattack=4.7kΩ
Rdecay=2.2kΩ
Rrelease=2.2kΩ


ch1:GateIn(D2) ch2:OUT

細かいパラメータは少々異なりますが、だいたいシミュレーションと同じような波形が出力されました。

Rattack=10kΩ
Rdecay=10kΩ
Rrelease=2.2kΩ


ch1:GateIn(D2) ch2:OUT

Rattack=1kΩ
Rdecay=1kΩ
Rrelease=1kΩ


ch1:GateIn(D2) ch2:OUT

Arduinoのスケッチ <Arduino_EG.ino>

/*
 * Arduino EG
 *
 * 2018.07.10
 *
 */

#define UART_TRACE  (0)
#define PIN_CHECK   (0)

#define TITLE_STR1  ("Arduino EG")
#define TITLE_STR2  ("20180710")

const int ThresholdPin = 0;

const int GateInPin = 2;

const int AttackPin = 4;
const int InvAttackPin = 5;
const int GateOutPin = 6;

const int LedPin = 13;

#if (PIN_CHECK)
const int CheckPin = 10;
#endif

enum EG_STATE {
  ST_ATTACK,
  ST_DECAY,
  ST_RELEASE
};

volatile enum EG_STATE state = ST_RELEASE;

void GateIn()
{
  bool isGateOn = digitalRead(GateInPin);
  
#if (UART_TRACE)
  Serial.println(isGateOn);
#endif

  if (isGateOn) {
    state = ST_ATTACK;
    digitalWrite(LedPin, HIGH);
  }
  else {
    state = ST_RELEASE;
    digitalWrite(LedPin, LOW);
  }
}

void setup()
{
  pinMode(AttackPin, OUTPUT);
  pinMode(InvAttackPin, OUTPUT);
  pinMode(GateOutPin, OUTPUT);
  pinMode(LedPin, OUTPUT);

  pinMode(GateInPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(GateInPin), GateIn, CHANGE);

#if (PIN_CHECK)
  pinMode(CheckPin, OUTPUT);
#endif

#if (UART_TRACE)
  Serial.begin(115200);
  Serial.println(TITLE_STR1);
  Serial.println(TITLE_STR2);
  delay(1000);
#endif
}

void loop()
{
  int th = analogRead(ThresholdPin);

  if (state == ST_ATTACK && th > 683) {
    state = ST_DECAY;
  }
  
#if (UART_TRACE)
  Serial.print(th);
  Serial.print("\t");
  Serial.println(state);
#endif

  switch (state) {
  case ST_ATTACK:
    digitalWrite(GateOutPin, HIGH);
    digitalWrite(InvAttackPin, LOW);
    digitalWrite(AttackPin, HIGH);
    break;
  case ST_DECAY:
    digitalWrite(AttackPin, LOW);
    digitalWrite(InvAttackPin, HIGH);
    break;
  case ST_RELEASE:
    digitalWrite(AttackPin, LOW);
    digitalWrite(GateOutPin, LOW);
    break;
  }
}


Github:
https://github.com/ryood/Arduino_EG

メモ:


Arduinoの処理能力と配線次第ですが、2系統エンベロープを出力できるかも?