2018年2月9日金曜日

Arduino LFO Main Boardの設計と機能追加

回路図

テスト用ブレッドボード配線図
<追記:2018.02.10>

LEDの配線が間違っていました。→「Arduino LFO Main Boardの設計 その2

</追記>


機能追加

ファームウェア:
https://github.com/ryood/ArduinoLFO/tree/f536b1cc2bfd08b9c33ed6bf65a2ae5e4665be1d/Arduino/MCP4922_LFO

Sqr、SawUp、SawDownは波形テーブルを参照せずに位相値(phaccu)を直接使用するように変更しました。

波形テーブルを12bit 4096要素に変更しました。(Sin、Triにのみ使用)

SQRのパルス幅を設定できるようにしました。

SyncIn信号で波形の位相値を強制的にリセットするようにしました。

SyncInを設けたので選択波形表示用LEDを5個→4個に変更しました。表示はNord Lead2のように行います(^q^;


出力波形(MCP4922のOUTA)


WaveSpectraでFFTしました。

Arduinoの電源: 電池電源(単3✕6)、7.55V
5V: 5.02V
3.3V: 3.27V
Audio I/F: TASCAM US-144MKII (Mic/Line入力)
窓関数: FlatTop
Avg:100

サイン波

三角波

矩形波

ノコギリ波上昇

ノコギリ波下降

波形の直線の部分が丸くなっているのは、オーディオ・インターフェイスの入力のACカップリングによるものだと思います。オシロで測定すると直線的です。

サイン波以外の波形のスペクトラムを見るとサンプリング周波数のエイリアスがよりわかりやすくなっています(^q^/

SyncIn


ch:MCP4922のOUTA ch2:SyncIn

ch2:SyncInの立ち上がりでch1の出力のサイン波の位相がリセットされています。

タイミングの計測


A4の出力でサンプリング周期での割り込み処理時間を計測しました。

ISR(TIMER2_OVF_vect)
{
#if (PIN_CHECK)
  digitalWrite(CheckPin1, HIGH);
#endif

  // synthesize
  phaccu = phaccu + tword_m;
  int idx = phaccu >> 20;  // use upper 12 bits

  switch (waveshape_sel) {
    case WS_SIN:
      MCP4922Write(0, pgm_read_word_near(sin_12bit_4k + idx));
      break;
    case WS_TRI:
      MCP4922Write(0, pgm_read_word_near(tri_12bit_4k + idx));
      break;
    case WS_SQR:
      if (idx < pulse_width) {
        MCP4922Write(0, 4095);
      } else {
        MCP4922Write(0, 0);
      }
      break;
    case WS_SAWUP:
      MCP4922Write(0, idx);  // 12bit value for MCP4922
      break;
    case WS_SAWDOWN:
      MCP4922Write(0, 4095 - idx);  // 12bit value for MCP4922
      break;
  }

  // debounce
  if (waveshape_pushed_wait > 0) {
    waveshape_pushed_wait--;
    if (waveshape_pushed_wait == 0 && digitalRead(ButtonWaveShape) == LOW) {
      waveshape_sel++;
      if (waveshape_sel >= WS_MAX) {
        waveshape_sel = 0;
      }
    }
  }
#if (PIN_CHECK)
  digitalWrite(CheckPin1, LOW);
#endif
}

Tri: 44.4us
Sqr: 44.4us
SawUp: 43.2us
SawDown: 44.0us
Sin: 44.8us

phaccuを直接見ているSawUpが一番速いですが、テーブル参照しているSin、Triもそれほど遅くなっていないようです。DDSはメモリが必要になりますがさすがに速いと言えます。

ランダム波形


ランダム波形をrandom()関数で処理できないかと思って処理時間を計測しました。

Arduinoのスケッチ <random_function_TimeTest.ino>

https://github.com/ryood/ArduinoLFO/blob/f536b1cc2bfd08b9c33ed6bf65a2ae5e4665be1d/Arduino/random_function_TimeTest/random_function_TimeTest.ino

実行すると1000回のループで52180usかかっていて、1回の呼び出しで52.18usかかる事になります。かんたんに追加できなさそうなのでしばらく保留。

消費電流


消費電流を計測すると112mAも流れていました。LEDを2個点灯させると(サイン波を選択している時)208mAになり、LEDをブレッドボードから抜くと電流が15mA程度まで下がります。

LEDの電流制限に1kΩのRを入れているので多くても1本あたり5mA(@5V)のはずですが(@@?

<追記:2018.02.10>

LEDの配線が間違っていました。→「Arduino LFO Main Boardの設計 その2

</追記>