ADS1015をArduinoで使う - ③差動入力チャネル数の謎を解く

差動入力時の入力チャネル数の謎

以前の記事で、ADS1015はシングルエンドであれば4ch、差動入力であれば2chの入力が可能と書きました。
ty-note.hatenablog.com

実際、ADS1015のデータシートには

4つのシングルエンド入力または2つの差動入力(ADS1015)

との記載があります。

ところが、データシートにはまた

The ADS1015 contains an input multiplexer (MUX), as shown in Figure 10. Either four single-ended or two differential signals can be measured. Additionally, AIN0 and AIN1 may be measured differentially to AIN3.

とも書いてあり、後半の一文「加えて、AIN0 と AIN1 は、 AIN3 と差動で測定できます」の意味がよく分かりません。

Configuration registerで指定する入力マルチプレクサの設定を見ると、差動入力の入力ピン設定(片側がGNDではない)は

  • AIN_0AIN_1
  • AIN_0AIN_3
  • AIN_1AIN_3
  • AIN_2AIN_3

の4つとなっています。普通に考えれば、AIN_0AIN_1で1ch、AIN_2AIN_3で1chの計2chが無難に感じますが、ではこの真ん中二つは一体・・?


あえて図に上記4通りの組み合わせをすべて記入すると以下になります。(ここで[CT]とはカレントトランス、つまり電圧発生源としてください)

これでは、たとえばAIN_0AIN_3の電位差を測定しようとしたとき、0~1と1~3間に接続されている別のCTと並列接続になるため正しい値は得られません。


ですが、一か所あきらめて以下とすると、少なくとも電位差を測定するときに他のCTが悪影響を及ぼすようには見えません。

それぞれ電気的に独立した回路として測定を行う場合は2chなものの、AIN_3をCommonとして使ってよいのなら3chの差動測定が可能なのではないでしょうか?

実験してみる

上記回路の通り、AIN_3をCommonとして3つのCTを接続します。
Configuration registerのMUXフィールドを

  • 001
  • 010
  • 011

で変化させ、それぞれのチャネルの電力を計測します。
具体的なデータ収集方法と計算方法は、以下の記事のままです。


結果とまとめ

結論から書きますと、正しく測定できました。計測の都合上3つのCTは同一の回路にクランプしているため、それぞれ個別につけ外しすることで値の変化を確認しましたが、お互いに測定値に影響を及ぼすことなく個々の測定が行えている様子です。

ADS1015はアドレスピンの接続先を変えることでI2Cアドレスを4種類に変更することができるので、この結果より1デバイスあたり3ch×4=12chの差動測定が一つのI2Cバスでできることになります。「いやそんなにいらないでしょ」と思う方もいらっしゃるかと思いますが、CTを分電盤の系統それぞれに付けて部屋や機器ごとの電力をモニタするHEMS製作を考えているため、チャネル数は稼げたほうが良いのです。

データシートの日本語抄訳はありがたいですが、きちんと使いこなしたかったら真面目に原文を読む必要がありますね。

CTを使って電力を測る - ②試作と精度の確認

試作

前回の記事
ty-note.hatenablog.com
で大まかに仕様を決めたので、実際に回路を作って実験をしてみます。

ハードウェアは、以前の記事
ty-note.hatenablog.com
と同じ以下とします。

回路構成は以下とします。とりあえずの機能実証と精度確認が目的なので、表示機能は設けず、プログラム書き込みに使うUSB-シリアル変換基板を介してシリアルモニタでデータを受け取ります。Arduino IDEはよく出来ていて便利ですね。

Arduino IDEのサンプルコードは以下の通りです。
setup()でADS1015の初期設定と読み取りレジスタの指定を行った後、loop()で16.66msの間に取れるだけデータを読み取り、二乗平均の平方根を取って値を換算しシリアル通信で出力します。
コメントアウトしているFor文を実行すると、計算に使った全サンプルデータをCSVで吐き出します。

#include <Wire.h>
#define ADS1015_ADRS 0x48 // Device I2C ID

int data_L, data_H; // For receiving data from ADS1015
int i; // Number of samples
long data, buffer;
int measurement[200];
unsigned long t1,t2;
float Vrms, Watt; // For output

void setup() {

  Serial.begin(9600); // Start serial communication, 9600bps
  Wire.begin(); // Start I2C communication
  Wire.setClock(400000); // Set I2C data rate to 400kHz

  Wire.beginTransmission(ADS1015_ADRS);
  Wire.write(0x01); //Set target register, Config register
  Wire.write(B00000110); //Upper byte
  Wire.write(B11100011); //Lower byte
  Wire.endTransmission();

  Wire.beginTransmission(ADS1015_ADRS);
  Wire.write(0x00); // Set target register, Data register
  Wire.endTransmission();

  Serial.println("Init done");

}

void loop() {

  delay(500);
  i = 0;
  data = 0;
  Vrms = 0;
  buffer = 0;
  t1 = micros();

  do {

    Wire.requestFrom(ADS1015_ADRS,2);
    while(Wire.available()){
      data_H = Wire.read();
      data_L = Wire.read();
    }

    data_H = data_H << 8;
    measurement[i] = (data_H + data_L) >> 4;
    buffer = measurement[i];
    data = data + (buffer * buffer);

    i = i+1;
    t2 = micros();

  } while ((t2-t1)<16666);

  Vrms = data;
  Vrms = sqrt(Vrms / i) * 0.5;
  Watt = Vrms * 3;

  Serial.print("i=");
  Serial.print(i);
  Serial.print(",data=");
  Serial.print(data);
  Serial.print(",Vrms=");
  Serial.print(Vrms);
  Serial.print(",Watt=");
  Serial.print(Watt);
  Serial.print(",");

  // for (int j=0; j<i; j++){
  //   Serial.print(measurement[j]);
  //   Serial.print(",");
  // }  

  Serial.println("EndOfData");
}


実行すればシリアルモニタに以下が表示されます。

サンプル数は約140個取れており、ADS1015のサンプルレートを大幅に超えている(無駄に同じ値を読んでいる)ため問題ないと思います。

取得した波形

内部バッファmeasurement[i]に溜めたデータをシリアルモニタで出力し、Excelで波形にした結果が以下です。

スイッチングACアダプタを接続したとき。力率の悪そうな波形になっています。

gootのセラミックヒータ式はんだごてを追加で接続した場合。

一応きっちり1周期分取れているようです。所詮3300サンプル/秒なので、特にスイッチング電源などのピーク電流を取りこぼしている可能性もあり、数回はサンプルを取って平均するような動作がいいでしょう。

精度の確認

都合のいい測定器は持ち合わせていないので、比較対象としてサンワサプライワットチェッカーを使います。
www.sanwa.co.jp
かなり前に購入したものですが、これは皮相電力・有効電力を分けて表示できる(=力率の概念がある)優れものです。

いくつか手元の家電でチェックした結果が以下です。
当たり前ですが力率が高い機器ほど測定値とワットチェッカーの値が近く、力率の悪いスイッチング電源ではかなりの差(50W⇔80W)が出ています。

想定外だったのがエアコンです。インバータ式の2.2kW機で、Panasonicの最廉価グレードです。Panasonicはカタログで力率を書いていない(ダイキンは書いてある)ので仕様はわかりませんが、ワットチェッカーでは力率0.81となっています。ある程度運転が安定した状態で測定しているので、立ち上げ時などフルパワー近くで運転しているときはもう少しましなのかもしれませんが・・。エアコンによる冷暖房費、および同じ仕組みを使っているエコキュートの電気代は季節によっては大きなウエイトを占めるので、これが2割近い誤差を生むのはちょっと困りものです。

測定対象 自作メータ(W & VA) ワットチェッカー(W) ワットチェッカー(VA) 力率
セラミックヒータ・弱 615 643 647 0.99
セラミックヒータ・強 1067 1094 1085 0.99
ドライヤー・弱 600 580 828 0.69
ドライヤー・強 1110 1132 1136 0.99
スイッチングACアダプタ 80 50 91 0.55
エアコン(暖房) 710 578 711 0.81

以下は、それぞれの電流波形です。

セラミックヒータ 弱

セラミックヒータ 強

ドライヤー 弱
半波整流して50%出力にしているんですね・・

ドライヤー 強

ACアダプタ

インバータエアコン 暖房運転 立ち上げ時
思いのほか力率が悪いのは安物だからでしょうか。

まとめ

皮相電力での比較であればワットチェッカーとかなり近い(5%以内)の値が出ており、CTの電圧波形のRMSを測定しての電流換算は計算通り動作しているようです。
電子工作で商用100Vを直接触るのにちょっと抵抗があるので、力率をたとえば0.9で固定するなどして換算するしか手がないように思います。

CTでの電力計測は目途がついたので、次は電力量計算および多チャンネル測定に進みます。

ADS1015をArduinoで使う - ②負の電圧を計測する

ADS1015で負の電圧を計測する方法

前回の記事
ty-note.hatenablog.com
で説明した通り、今回ADS1015を使う目的はCTの出力を計測するためです。
CTは”トランス”の名の通り交流電流を計測し交流の出力となるため、A/Dコンバータで読み取るには負電圧の入力を処理する必要があります。

巷にある制作例だと、電源電圧(主に5V)を抵抗で分圧して2.5Vを作りだし、CTの電圧をオフセットさせる例が多いようです。これは方法としては単純でいいのですが、以下の問題があります。

  • 分圧する電圧の精度が計測値に直接影響する(基準電圧ICを使ったり、ソフトでキャリブレーションするなど手はあると思いますが)
  • オフセットしてしまっているので、せっかく内蔵されているPGAのゲインを上げられない。変位量が微小なのでこれは辛い
  • 12bit ADCなのに、実質11bitしか使えない*1

日本語版データシートの概要欄に以下記載があるため、まるでそのまま交流信号を入れていいように記載している解説を何例か見たのですが、シングルエンドモードでは無理です。

PGAは入力電圧範囲が± 256mV~±6.144Vで、振幅の小さな信号から大きな信号まで高精度に測定できます。

ダメなことは、データシートの 9.1.2 Single-ended Inputs にもはっきり記載があります。

The single-ended signal ranges from 0V up to positive supply or +FS, whichever slower. Negative voltages cannot be applied to these devices because the ADS101x can only accept positive voltages with respect to ground.
シングルエンド入力の信号レンジは0Vから電源電圧または+FSのどちらか低いほうまでです。ADS101xはGNDに対して正の電圧しか許容しないため、負の電圧を入力することはできません。

詳しくはデータシートのFigure.10を見るとわかります。各入力のすぐ後ろにダイオードでVDDとGNDにクランプされているので、負電圧を入れてもほぼGND電位になってしまいます。

最大絶対定格もAnalog input voltage (MIN.) が GND-0.3V と表記されています。

ではなぜ最大で±6.144Vの入力範囲だとデータシートに記載されているのか?それは差動入力モードを使うからです。

シングルエンドモードと差動入力モード

シングルエンドは通常のマイコン内蔵ADCでお使いの方も多いと思いますが、GNDという基準に対する電位差を計測するものです。入力する線が1本で済みますが(もう片側はGNDで共通のため)、外部からのノイズに弱く、今回のケースでは負の電圧も測れません。(シングルエンド入力で負電圧測れるADCってあるのでしょうか?)
シングルエンド入力に設定されると、ADC前段にあるマルチプレクサの回路が閉じ、 AIN_{N} はGNDに接続されます。

差動入力モードはその名の通り2つの入力間の差を読み取る方法です。外部からノイズが入っても、(信号P+ノイズ)ー(信号N+ノイズ)で計算されノイズが打ち消されることから、ノイズに強い計測方法だと言われます*2。このデバイスの場合、差動入力時のAD変換値 V_{IN}は、 AIN_{P} - AIN_{N}で計算されます。
難点としては2つの入力を使って差分を取るため、実質的に入力チャネルが半減してしまうことですね。

余談

なぜ差動入力だと負の電圧が計測できるのか、私もうまく電気的に説明が出来ない(理解していない)のですが、マイナスの電位というのはあくまでGND基準であるというところがキモなのだと思います。差動入力に接続されている電圧源はGNDに対して浮いているので、GNDに対する電位差は不定(何らかの内部回路や特性によってバランスが取れるところ)というのが真実なのではないでしょうか?

試しに以下回路の波形をオシロスコープで観測してみた結果は以下です。

Ch.1、Ch.2ともに、CTからの入力信号(60Hz)に同期した動きはしているものの、電圧もデタラメで波形も不思議な形をしています。
しかし、Ch.1と2の差分を取ると、CT単体の入力をオシロで観測したときの波形そのままが現れました。安物のスイッチング電源を接続しているため力率の悪い波形をしていますが・・・。

差動入力信号について解説している様々な資料を当たってみましたが、まだここについてしっくりくる解説に出会えていません。

*1:12bit ADCですが、最上位1bitは符号です。シングルエンドモードで使うと0V~VCCまでの計測になるため、分解能が落ちます

*2:差動信号で有名?なCAN信号も、CAN-HとCAN-Lの波形をそれぞれ独立で見るとノイズまみれですが、差動電圧波形はきれいです

CTを使って電力を測る - ①仕様の検討

真の実効値(TrueRMS)の計算

前回の記事でCTからの交流信号をADS1015で変換できることは確認したため、いよいよCTの入力を電圧(電流)値として取り込む方法を考えます。

今回計測対象とするのは交流信号のため、実効値・最大値・平均値といった概念が必要になります*1
予備試験として手近な機器の電流波形をCTを使って観測したところ、特に省電力の機器ほど波形のゆがみが大きく、中でも安物のスイッチング電源はもはやサイン波とも言えない代物が多いことが分かりました。これらの測定で、波形が正弦波であると仮定する平均値方式ではまともな計測結果が期待できません。

よって、真の実効値(TrueRMS)と呼ばれる方式にチャレンジしようと思います。

テクトロニクスの資料によれば

電流の実効値は、電流の二乗平均平方根で求められます。

だそうです。RMS: Root Means Square たるゆえんですね。
https://download.tek.com/document/55Z_29828_0_3.pdf

以下の数式で表される通り、真の実効値は瞬時値の二乗の総和をサンプル数で割り(=平均値)、平方根を取ればいいわけです。

 I=\sqrt{\frac{I_{1}^{2}+I_{2}^{2}+...I_{n}^{2}}{n}}

試しに \sin(\theta)を0~360°観測したと仮定してRMSExcelで計算してみたところ、0.707が得られました。完全なsin波であれば振幅の最大値は実効値の \sqrt{2}倍なので、振幅±1の時の実効値は \frac{1}{\sqrt{2}}=0.7071..となることから、正しい値になっていそうです。


サンプリング速度

商用電源の周波数は地域によって50または60Hzですので、1周期 Tは以下です。

 T=\frac{1}{50}=20\,\mathrm{(ms)@50Hz}
 T=\frac{1}{60}=16.66..\,\mathrm{(ms)@60Hz}

ADS1016の最大サンプリング速度は3300サンプル/secなので、1周期あたりのサンプル数 Nは以下です。

 N=\frac{3300}{50}=66 または
 N=\frac{3300}{60}=55

なので、

  • 50Hz地域なら20.0ms以内に66回以上サンプリング
  • 60Hz地域なら16.6ms以内に55回以上サンプリング

できれば、少なくともADS1015の最大サンプリング能力を使い切ることができるはずです。これが電流波形のサンプリングとして十分かはわかりませんが。。

このことから、最初はタイマ割込みを使って303μS毎に読み込みをかける処理を考えたのですが、I2C通信にもタイマ割込みを使っている?らしく、割り込みをさせると正常に動作できなくなる問題が起きました。I2C通信の間は割り込みをかけない処理にしたり、関係しそうな変数をvolatileで宣言したりと少し試行錯誤してみましたが、単純に解決できそうになかったため、最終的には一定時間の間できるだけサンプルを取る方式に変えています。

CTの選定と特性

今回使う予定のCTは、台湾DER EE社製の分割型CT SCT-10です。80Armsまで計測可能で、秋月電子でも扱いがあります。
https://ja.deree.com.tw/sct-10-split-core-ct.html
電流センサー(CTセンサー・変流器) 80A Φ10mm 分割型 SCT-10: 計測器・センサ・ロガー 秋月電子通商-電子部品・ネット通販

数年前にこの制作をリサーチしたときはU_RD社製CTL-10-CLSが候補だったのですが、このDER EE製SCT-10は見た目からスペックまでそっくりです。実物を比較していないのですがOEMなのでしょうか・・・?
超小型クランプ式交流電流センサ(φ10/80Arms)[仕様] | 株式会社ユー・アール・ディー

CTの出力電圧 E_{o}は、以下の式で求められます。


 E_{o}=\frac{K \cdot I_{o} \cdot RL} {n}

ここで

 K:\,結合特性
 I_{o}:\,貫通電流
 RL:\,負荷抵抗
 n:\,巻き数

SCT-10は巻き数3000で、今回は負荷抵抗に100Ωを選定しました。結合特性は比較的特性の良好な小電流部分でしか使わないため1で計算します。
フルスケール20Armsを目標にすると、最大の出力電圧は約±0.95V程度となりそうです。したがって、ADS1015のPGAゲインは±1.024V(4倍)を選べばいいでしょう。


 \begin{align}
E_{o}&=\frac{K\cdot I_{o}\cdot RL\cdot \sqrt{2}}{n}\\
&=\frac{1\times 20\times 100\times\sqrt{2}}{3000}\\
&=0.9428..
\end{align}

(急に登場した \sqrt{2}ですが、貫通電流 I_{0}RMSなので、この公式だと E_{o}も実効値になります。なのでp-pを求めるには \sqrt{2}倍する必要があると思ってます。違いますかね?)

電圧(電流)の分解能

ADS1015の出力値は、0x7FF0(32752)~ 0x8000(-32752)になります。・・が、ADコンバータ分解能は12bitのため16bitのうち末尾4桁は常時0なので、実際には0x7FF(2047)~0x800(-2048)の4096ステップ( 2^{12})になります。

入力 測定値(16bit) 測定値(12bit)
+1.024V 0x7FF0 (32752) 0x7FF (2047)
0V 0x0000 (0) 0x000 (0)
-1.024V 0x8000 (-32752) 0x800 (-2048)

PGAゲインを4倍にしてフルスケール±1.024Vとすれば、最小分解能1bitあたり0.5mVになります。先ほどのCTの出力電圧の式を用いると、


 \begin{align}
\frac{0.5}{1000}&=\frac{1\times I_{o} \times 100}{3000}\\\\
I_{o}&=0.015 \rm{[A]}
\end{align}

となり、十分な分解能が取れそうです(あくまで分解能で、精度はまた別の話)。100V電源であれば×100で1.5W単位ですね。

まとめ

現在検討している電力計は以下で実現できそうです。

  1. ADS1015のPGAを4倍に設定し、CTセンサSCT-10を負荷抵抗100Ωで差動入力させる
  2. 1サイクルあたり55または66回以上サンプリングする
  3. サンプリングした値の二乗平均平方根を求める
  4. 求めた値に0.5mVを乗じて、実効電圧 Vrms (mV)を求める
  5.  E_{o}=\frac{K \cdot I_{o} \cdot RL} {n} より  I_{o}=\frac{E_{o} \cdot n}{K \cdot RL} を使って実効電流を求める
  6. 電圧100Vをかけて皮相電力(VA)にする。力率は考慮しない(できない)ので、これを有効電力(W)として扱う

次はこれを実装してみます。

*1:このあたりは計測器メーカなどが分かりやすい解説をしている記事が多数あるため本稿では割愛します

ADS1015をArduinoで使う - ①接続と設定

I2C接続、12bit 4ch、PGA付きと便利なTI製ADS1015を使用した制作例をよく見かけます。
ここでは自分の制作に使用するにあたり調べたことをメモします。

TI ADS1015について

CT(カレントトランス)を使った電力計の制作を考えていたのですが、CTの出力電圧はモノにもよりますが計測値0.1A(≒10W)で出力電圧33mVなどと小さく、また交流出力のため負電圧への対応が必要であり信号の扱いがやや面倒です。ADS1015は、そんな要件に適したデバイスです。

ADS1015の主な特徴は以下の通りです。

  • 12bit分解能のA/Dコンバータが4ch (差動入力で2ch
  • I2Cでマイコンとデジタル接続が可能
  • 設定ピンの接続先を変えることでI2CデバイスIDを4種類に変更できる→一つのI2Cインターフェースに対して最大4つ接続可能
  • PGAプログラマブル・ゲイン・アンプ)が内蔵されていて、微小信号を外付け部品なしに増幅して取り込める
  • 最大サンプリングレートは3300サンプル/sec

PGAがなくてもオペアンプで増幅回路を組めば済む話ですが、私の経験上素人が特に微小な信号を扱う回路を組むとノイズであったり誤差であったりと余計な壁に当たる可能性が高く、ワンチップで完結しているADS1015は魅力的です。

兄弟製品としてADS1115という16bit分解能の製品もありますが、こちらは最大サンプリングが860サンプル/secとなり、アプリケーションを選ぶ感じです。

国内では秋月電子がモジュール化した製品(adafruit製の互換製品?)を扱っていますね。
ADS1015使用 PGA機能搭載12bitADコンバーター: 半導体 秋月電子通商-電子部品・ネット通販

ハードウェア構成

今回は以下で試しました。いずれも秋月電子で手に入ります。

AE-ATMEGA328-MINIはArduino Pro Mini互換基板で、I2Cは基板シルクでA4, A5のピンです。ジャンパJ2, J3が接続された状態(プルアップされた状態)にします。
ADS1015基板側でもジャンパをショートさせればプルアップ抵抗を有効にできるようですが、マスター側でやるのがスジだと思います。

測定する電圧源は単三乾電池(エネループ)とし、A0、A1に接続します。将来的に交流で出力されるCTの信号を受け取りたいので差動入力を選択しています。

I2CでADS1015を設定し、結果を読み出す

Arduinoの場合、便利なライブラリを使うことで非常に簡単にデータを得られます。しかしデバイス専用ライブラリは便利な反面、細かな設定であったり機能の詳細を隠蔽してしまうため、ちょっと凝ったことをしようと思ったとたん融通が利かなくなるうえ、覚えた知識の応用も難しくなります。

今回はI2Cこそライブラリの力を借りますが、ADS1015との通信は直接プログラムすることにします。

サンプリングモードの設定

ADS1015は、動作設定をConfiguration registerに書き込むことで設定します。プログラムの手順としては以下です。

  1. 対象のデバイスIDに対してI2C通信を開始する
  2. 0x01を送信して、書き込み先をConfiguration registerに設定する
  3. Configuration registerの内容を、上位8bit、下位8bitの順番に送信する
  4. I2C通信を終了する

Configuration register (16bit)各bitの意味は以下の通りです。

幅広い設定が可能なので詳細はデータシートを見てください。以下は概要です。

Field 内容
OS ReadかWriteかで意味が異なってきます。シングルショットの時は1を書くとサンプリング開始です。連続変換ならどちらでもOK ("No effect"です)
MUX 入力チャネルの選択、および動作モード(シングルエンド又は差動入力)の切り替えを行います。デフォルト000でA0とA1ピンでの差動入力で動作します
PGA プログラマブル・ゲイン・アンプのゲインを設定します。デフォルトは010で±2.048Vです
MODE 連続変換かシングルショットかを選択します。0で連続変換です
DR サンプリング周期を設定します。デフォルトは100で1600サンプル/秒です
COMP_MODE 内部コンパレータの設定を行います。割愛。
COMP_POL 内部コンパレータの設定を行います。割愛。
COMP_LAT 内部コンパレータの設定を行います。割愛。
COMP_QUE 内部コンパレータの設定を行います。割愛。

今回の例では以下としました。

データの読み出し

Configuration registerに適切な設定を行えば、ADS1015は指定した周期でサンプリングを行い、データを逐次Conversion registerに書き込みます。これの読み出し手順は以下です。

  1. 対象のデバイスIDに対してI2C通信を開始する
  2. 0x00を送信して、I2C通信で読み取るレジスタのアドレスをConfiguration registerに設定する
  3. 送信を終了する
  4. 上位8bit、下位8bitの順にデータを読み取る
  5. 上位8bitのデータを8bit分ビットシフトさせて、下位8bit分のデータと足し合わせることで結果を得る

Conversion registerは以下の通りで、12bitのデータが上位詰めで格納されています。

12bitのデータを一度に読み出せないため、8bitずつ読み取ったデータを以下手順で処理します。

一度読み出し先のアドレス0x00を設定しさえすれば、チャネル設定を変更しない限りステップ4~5を繰り返すことで最新のデータを読み出すことができます。

ところで、ADS1015は4chのADコンバータではありますが、内部マルチプレクサで回路を切り替えているだけでADCコア自体は1個しか搭載されていません。Configレジスタでチャネルを指定して、変換したデータを読み取るというプロセスなので、3300サンプル/秒は1chあたりの最大サンプリングです。チャネル変更→読み出しには複数回のI2C通信を行う必要があるので、4chすべてを読み出す場合の最大サンプル数はかなり少なくなるでしょう。このあたりは安いオシロスコープと似たような作りですね。

サンプルプログラム

上記設定の動作確認を以下プログラムで行いました。A0~A1間の電位差を計測し、シリアル通信で電圧出力を行います。I2C通信および内部での変換処理を1サイクル実行する時間も併せて計測し出力します。

#include <Wire.h>
#define ADS1015_ADRS 0x48 // Device I2C ID

int data, data_L, data_H; // For receiving data from ADS1015
unsigned long t, t1; // For time measurement
float voltage; // For output

void setup() {

  Serial.begin(9600); // Start serial communication, 9600bps
  Wire.begin(); // Start I2C communication
  Wire.setClock(400000); // Set I2C data rate to 400kHz

  Wire.beginTransmission(ADS1015_ADRS);
  Wire.write(0x01); //Set target register, Config register
  Wire.write(B00000010); //Upper byte
  Wire.write(B11100011); //Lower byte
  Wire.endTransmission();

  Serial.println("Init done");

  Wire.beginTransmission(ADS1015_ADRS);
  Wire.write(0x00); // Set target register, Data register
  Wire.endTransmission();

}

void loop() {

  t1 = micros();

  Wire.requestFrom(ADS1015_ADRS,2);
  while(Wire.available()){
   data_H = Wire.read();
   data_L = Wire.read();
  }

  data_H = data_H << 8;
  data = data_H + data_L;
  voltage = data * (4.094/32767);

  t = micros() - t1; // Get acquisition time in micro sec

  Serial.print("V=");
  Serial.print(voltage);
  Serial.print(" Acquisition time(us)=");
  Serial.println(t);
  delay(500);

}

結果は以下の通りです。

1回の読み出し・データ処理で120μ秒程度かかっています。
実は、最初に試したときは1回の処理で600μSec程度かかっていました。ADS1015の最大サンプリングは3300サンプル/秒のため、1読み出しあたり約300μSecを超えてしまうと最大サンプリングでデータを読み取れなくなってしまいます。I2Cの通信速度を最高速の400kHzに変更(デフォルトは100kHz)したり、読み取るレジスタの指定を毎回行わない(一度指定すれば何度でも繰り返し読めることに後で気づきました)などの改善で120μ秒まで短縮しています。

最後の電圧変換するFloatの演算をある程度サンプリングした後に行うなど処理の工夫でまだ改善できるはずですが、とりあえずこれでADS1015の設定とデータ読み取りはできたので先に進むこととします。