SpresenseでLチカから始める (3) Wireライブラリ A-DコンバータMCP3421

 Wireライブラリを利用するために、マイクロチップ製MCPシリーズの18ビットA-DコンバータMCP3421を利用します。DIP化されたボードをebayから入手しました。

MCP3421のおもなスペック

  • 分解能;18ビット
  • パッケージ;6ピンSOT-23
  • 基準電圧;2.048V内蔵
  • 電源電圧; 2.7~5.5V
  • 入力;差動1チャネル
  • 増幅器;ゲイン・プラグラマブル前置アンプ内蔵(PGA)。1倍、2倍、4倍、8倍から選択
  • 変換方式;ΔΣ(デルタ・シグマ)方式
  • 変換速度;3.75SPS(18ビット)、15 SPS (16ビット)、60 SPS (14ビット)、240 SPS (12ビット)から選択
  • インターフェース;I2C
  • I2Cデータ転送速度;standard (100 kHz)、fast (400kHz)、high-speed (3.4 MHz)モードのいずれか
  • I2Cのスレーブ・アドレス;1101000 0x68固定

設定用レジスタ

bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
Readyビット チャネル・セレクトだが使わない 1;連続、0;ワンショット 00;12ビット、01;14ビット、10;16ビット、11;18ビット PGA利得、00;×1、01;×2、10;×4、11;×8

 パワーオン・リセット後、このレジスタの内容は10010000です。12ビット、PGAは1倍の設定なので、16ビットに変更するときは、10011000にします。16ビットではサンプリング速度は15spsになります。

読み出したデータのフォーマット

 bit17~bit18が上位バイト、bit15~bit8が中位バイト、bit7~bit0が下位バイトです。bit17は符号ビットで、bit23からbit19はbi17がコピーされています。

接続

 SpresenseのI2Cインターフェースには1kΩのプルアップ抵抗が入っています(0番から13番ピンのすべて)。この低い抵抗値はMCP3421のデータ転送速度3.4MHzに対応していますが、ここではデフォルトの100kHzで実験します。Arduino UNOではA4とA5番ピンはI2Cと共通端子ですが、SpresenseのI2Cインターフェースは独立しています。

 

 データ転送速度は約100kHzです。

 400kHz以上に設定しても、336kHzより転送速度は上がりませんでした。

Wire.begin();
Wire.setClock(3400000L);

I2CスキャナでI2Cデバイスの存在をチェック

 i2c_scannerをコピペして、スケッチをコンパイルします。問題なければ、「→」で書き込みます。ボードへの書き込みが完了しましたが表示されたら、シリアル・モニタを開きます。通信速度は9600bpsです。0x68に見つけました。

A-D変換

 デバイスは、パワーオン・リセットで次のように設定されています。

  • コンバータのビット分解能 : 12 ビット (240 sps)
  • PGA ゲイン設定 : 1 倍
  • 連続変換

 こちらのスケッチ(MCP3425)をそのまま使います。16ビットにするためコンフィギュレーション・レジスタはb10011000です。元のスケッチも同じコンフィギュレーション値の設定なので、そのままコピペして動作させました。

#include <Wire.h>
#define MCP3425_address 0x68
#define configRegister 0b10011000 //16bit 15sps PGA x1
float Volts;
float Vref = 2.048 ;

void setup() {
Wire.begin();
Serial.begin(9600);
Wire.beginTransmission(MCP3425_address);
Wire.write(configRegister);
Wire.endTransmission();
}

void loop() {
Volts = (int)readADC() * Vref / 32767.0 ;
Serial.println(String(Volts,5));
delay(1000);
}

float readADC() {
Wire.requestFrom(MCP3425_address, 2);
return ( (Wire.read() << 8 ) + Wire.read() );
}

 Arduino UNOでは読み出してきたデータをintでキャストしたら、符号処理が行えました(16行目)。スケッチを動かしても、マイナスの値が正しく処理されていません。Spresenseのintは16ビットではないかもしれません。キャストにshortを使ってみましたが、符号処理は正しく行えませんでした。

 18ビットの読み出しに変更し、プラスの電圧だけを測るスケッチです。有効桁数以上の小数点を表示しています。

#include <Wire.h>
#define MCP3421_address 0x68
#define configRegister 0b10011100 //18bit 3.75sps PGA x1
float Volts;
float Vref = 2.048 ;

void setup() {
Wire.begin();
Serial.begin(9600);
Wire.beginTransmission(MCP3421_address);
Wire.write(configRegister);
Wire.endTransmission();
}

void loop() {
Volts = readADC() * Vref / 131071.0 ;
Serial.println(String(Volts,6));
delay(1000);
}

float readADC() {
Wire.requestFrom(MCP3421_address, 3);
return ( ( (Wire.read() & 0x03 ) << 16 ) + (Wire.read() << 8 ) + Wire.read() );
}

 エネループの電池の電圧を測っています。

前へ

SpresenseでLチカから始める (2) アナログ・ポート

次へ

SpresenseでLチカから始める (4) Wireライブラリ キャラクタLCD