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ででボリューム値を送信して、いろんなボリュームをワイヤレス化できそうですね~(*´▽`*)
初めまして
返信削除電子ボリュームを作りたくてFM62429を買って こちらのサイトを参考(まるパクリ)でトライしたのですが 全く動きません
そもそも INとOUTにつなげば音そのものは出るはずですが無音のままです(ICを経由せず IN・OUTを直結すれば 当然のように音はでます)
ICを何個か入れ替えてみても同じで 全く音がでません
何かヒントはありませんでしょうか?