Arduinoでステレオ電子ボリューム(FM62429)

はじめに

電子ボリューム(デジタルポテンショメータ)を使ってみたくて、どんなのがあるのかなーと調べてみました!

Aliで手に入れやすい電子ボリューム
型番
構造
チャンネル
プロトコル
分解能
パッケージ
お値段
X9C102/103/503/104
(1k,10k,50k,100k)
抵抗アレイ
モノラル
独自(Up/Down)
100TAP
dip8, sop8
10個で350円
(X9C104)[dip]
MCP41010/050/100
(10k,50k,100k)
抵抗アレイ
モノラル
SPI
256TAP
ほぼsop8,
僅かにdip8
5個で360円
(MCP41100)[sop]
MCP42010/050/100
(10k,50k,100k)
抵抗アレイ
ステレオ
SPI
256TAP
ほぼsop14,
僅かにdip14
5個で830円
(MCP42100)[sop]
FM62429
(0~-83dB,-∞)
減衰器
(アッテネータ)
ステレオ
独自
(2-Wire,絶対値)
84+1TAP
dip8,sop8
5個で100円
[dip]
PT2257
(0~-79dB)
減衰器
(アッテネータ)
ステレオ
I2C
80TAP
dip8,sop8
10個で450円
[dip]
抵抗アレイ型は、既存の3本足のポテンショメータをそのまま置き換えられるタイプで、減衰器型のものは、入力電圧が減衰されて出力されるタイプのようでした。今回は、1個当たり20円と飛びぬけてお安いFM62429を使ってみました(*´▽`*)

配線

 オリジナルの三菱M62429のデータシートを見て、アプリケーション例のとおりに接続しました。DATAとCLOCKは、Arduino(pro micro)の8番ピンと14番ピンにそれぞれ繋ぎましたが、スケッチのピン番号は変更できるので、どこに繋いでもよいと思います。
 なお、忘れずにVINに2.2μFを挟みましょう!最初これを入れてなくて、音ががびがびになってしまいました(/ω\)イヤン










スケッチ

 スケッチは、M62429 digital volume control with working code exampleを参考にさせていただきました。VolumePinDATとVolumePinCLKに代入するDATAとCLOCKのピン番号を、忘れずに変更しておきます。上記のサンプルはボリュームを自動的に上下するものですが、ArduinoIDEのシリアルモニタからボリューム値(0~100)を入力したかったので、私はこんな感じにスケッチを改造しました(*´▽`*)

/*
  Serial controlled volume based on this sketch: http://forum.arduino.cc/index.php?topic=244152.0
  The above sketch is also based on this lib: https://github.com/krupski/M62429/blob/master/M62429.cpp
*/

int VolumePinDAT = 8; // connect to DATA
int VolumePinCLK = 14; // connect to CLOCK
int vol = 0;

void setup (void) {
  pinMode(VolumePinDAT, OUTPUT);
  pinMode(VolumePinCLK, OUTPUT);

  Serial.begin(115200);
  while (!Serial);
  Serial.println("Ready.");
}

void loop (void) {
  if (Serial.available() > 0) {
    int ch = Serial.read();

    // Store received digit.
    if (ch >= '0' && ch <= '9') {
      vol = vol * 10 + (ch - '0');
    } else if (ch == 0x0a) {
      // When receive LF, check range of vol.
      if (vol >= 0 && vol <= 100) {
        // If vol is in valid range, set sent it to M62429.
        Serial.print("Set volume:");
        setVolume(vol);
      } else {
        Serial.print("Out of range:");
      }
      Serial.println(vol, DEC);
      vol = 0;
    }
  }
}

// this function does the job
void setVolume (uint8_t volume) {
  uint8_t bits;
  uint16_t data = 0; // control word is built by OR-ing in the bits

  // convert attenuation to volume
  volume = (volume > 100) ? 0 : (((volume * 83) / -100) + 83); // remember 0 is full volume!
  // generate 10 bits of data
  data |= (0 << 0); // D0 (channel select: 0=ch1, 1=ch2)
  data |= (0 << 1); // D1 (individual/both select: 0=both, 1=individual)
  data |= ((21 - (volume / 4)) << 2); // D2...D6 (ATT1: coarse attenuator: 0,-4dB,-8dB, etc.. steps of 4dB)
  data |= ((3 - (volume % 4)) << 7); // D7...D8 (ATT2: fine attenuator: 0...-1dB... steps of 1dB)
  data |= (0b11 << 9); // D9...D10 // D9 & D10 must both be 1

  for (bits = 0; bits < 11; bits++) { // send out 11 control bits
    delayMicroseconds (2); // pg.4 - M62429P/FP datasheet
    digitalWrite (VolumePinDAT, 0);
    delayMicroseconds (2);
    digitalWrite (VolumePinCLK, 0);
    delayMicroseconds (2);
    digitalWrite (VolumePinDAT, (data >> bits) & 0x01);
    delayMicroseconds (2);
    digitalWrite (VolumePinCLK, 1);
  }
  delayMicroseconds (2);
  digitalWrite (VolumePinDAT, 1); // final clock latches data in
  delayMicroseconds (2);
  digitalWrite (VolumePinCLK, 0);
  //return data; // return bit pattern in case you want it :)
}

おわりに

 電子ボリュームを初めて使ってみましたが、ソフトウェアで外部装置の信号電圧を制御できるのはなかなか楽しいです!ESP32を2つ使って、片方に物理ポテンショメータかロータリーエンコーダを繋ぎ、もう片方に電子ボリュームを繋げば、BTかWiFiででボリューム値を送信して、いろんなボリュームをワイヤレス化できそうですね~(*´▽`*)

コメント

このブログの人気の投稿

ESP32: Visual Studio CodeでESP-IDFを使う(Windows編)

PSoC5LP Prototyping Kitで作るUSBオーディオI/F(I2S出力対応)