昨年末に秋月で16ビットのA/DコンバーターMCP3425を購入した。このコンバーターはI2C接続が使え、さらにDIPへの変換基板もついて250円とお得だった。Arduino UNOで使おうと思っていたが、仕事がごたごたしていて手付かずになっていました。ちょっとだけ時間があったので挑戦してみた。検索してもArduino UNO+MCP3425という組み合わせでの作例がなかったので、記録がてら掲載しておきます。
□ 回路図
とりあえず動作確認が取れればいいや位のやっつけ回路です。SCL,SDAのラインに入っているプルアップ用の抵抗ですが、データシートには5~10kオームと書いてあったけどたまたま1kオームのものがみつかったのでそれを入れておきました。可変抵抗VRはArduinoからの5Vを適当に抵抗分配してチェック用の電位を作るために入れてあります。
□ スケッチ
とりあえず動けばいいやというスケッチです。
#include
byte dh,dl;
long d;
void setup(){
Wire.begin();
Serial.begin(9600);
delay(1000);
}
void loop(){
Wire.beginTransmission(0b1101000);
Wire.write(0x88);
Wire.endTransmission();
delay(200);
Wire.requestFrom(0b1101000,2);
dh = Wire.read();
dl = Wire.read();
d = dh *256 + dl;
Serial.println(d,DEC);
delay(500);
}
注意点というほどでもありませんが試作していてハマったことなどを幾つか列記します。
まず、Wire.beginTransmissionやWire.requestFromで指定するデバイスアドレスですが、秋月で購入したデバイスアドレスは7ビットで指定する1101000です。0x68であって、0xd0でありません。
次に、Wire.readでMCP4325からデータを読み込む際の変数の型ですが、Arduinoのマニュアルはcharで受けていますが、これをやるとArduinoが補数表現を使っておかしな結果を見ることになります。ですから上の例のようにbyte型で受けるほうがいいともいます。
Wire.write(0x88);で送り込む0x88がconfiguration registerの内容です。
bit7: 1=変換開始 0=最後に変換したデータ
bit6-5: 特に意味ない
bit4: 1=連続的に変換 0=1回だけ変換
Bit3-2: 分解能 00=12ビット 01=14ビット 10=16ビット
bit 1-0: ゲイン 00=1V/V(ゲイン1倍) 01=2V/V 10=4V/V 11=8V/V(ゲイン8倍)
Wire.endTransmissionしてから200msほど待っていますが、上の16ビット分解能だと秒15回くらいしかサンプリングできないようですので、最低でも1回の変換に70ミリ秒くらいかかることになります。この辺りに余裕をみて200msとしています。
あとは、変換の基準は内部で作られる2.048Vです。Vin+-Vin-が0V以上2.048Vまでなら0~07FFに変換されます。Vin+-Vin-が-1LSBなら0xFFFF,-2.048Vなら8000と負側は補数表現で表されます。上のスケッチは正の側では正しく動きますが、入力が負の側へは何も配慮していないのでご注意ください。