ゲインがプログラムで調整できるADコンバータがあるなんて!
というわけで、そんな夢のようなデバイスADS1115を試してみました。
差分を測定する用途に向いているもので、ひずみゲージとかのデータを取り込むのに良いと思います。
データシートの詳細はこちら
今回は急ぎだったのでAmazonから購入。
似たようなモジュールがたくさん出てきますが、偽物?も多いので選ぶのが難しい。
Arduinoのライブラリがあるので、それを使いました。
使用したライブラリ
ArduinoとADS1115の配線は下記のようにしました。
AIN0とAIN1に信号線をつなげて差分を取ります。
ADDRピンは繋ぐところによって4つのアドレスを選択できるのですが、今回はGNDに接続しました(0x48)。
今回の配線で躓いたポイントは、サンプルプログラム「continuous」を使用した場合、ADS1115のALERT/RDYとArduinoのD3を接続しないと安定してデータが取れなかったことです。(スケッチのコメントにはちゃんと書いてる…)
他のサンプルプログラムだと繋がなくても問題ありません。
実物の写真はこちら。
データの取得はサンプルプログラム「continuous」を使用しました。
一部書き換えたところがあるので、メモしておきます。
デバイスの指定と、ゲインの設定をコメントアウトしました。
あとはディレイを1000から100に変更しました。
#include <Adafruit_ADS1X15.h>
Adafruit_ADS1115 ads; /* Use this for the 16-bit version */
//Adafruit_ADS1015 ads; /* Use this for the 12-bit version */
// Pin connected to the ALERT/RDY signal for new sample notification.
constexpr int READY_PIN = 3;
// This is required on ESP32 to put the ISR in IRAM. Define as
// empty for other platforms. Be careful - other platforms may have
// other requirements.
#ifndef IRAM_ATTR
#define IRAM_ATTR
#endif
volatile bool new_data = false;
void IRAM_ATTR NewDataReadyISR() {
new_data = true;
}
void setup(void)
{
Serial.begin(9600);
Serial.println("Hello!");
Serial.println("Getting differential reading from AIN0 (P) and AIN1 (N)");
Serial.println("ADC Range: +/- 6.144V (1 bit = 3mV/ADS1015, 0.1875mV/ADS1115)");
// The ADC input range (or gain) can be changed via the following
// functions, but be careful never to exceed VDD +0.3V max, or to
// exceed the upper and lower limits if you adjust the input range!
// Setting these values incorrectly may destroy your ADC!
// ADS1015 ADS1115
// ------- -------
// ads.setGain(GAIN_TWOTHIRDS); // 2/3x gain +/- 6.144V 1 bit = 3mV 0.1875mV (default)
// ads.setGain(GAIN_ONE); // 1x gain +/- 4.096V 1 bit = 2mV 0.125mV
// ads.setGain(GAIN_TWO); // 2x gain +/- 2.048V 1 bit = 1mV 0.0625mV
// ads.setGain(GAIN_FOUR); // 4x gain +/- 1.024V 1 bit = 0.5mV 0.03125mV
ads.setGain(GAIN_EIGHT); // 8x gain +/- 0.512V 1 bit = 0.25mV 0.015625mV
// ads.setGain(GAIN_SIXTEEN); // 16x gain +/- 0.256V 1 bit = 0.125mV 0.0078125mV
if (!ads.begin()) {
Serial.println("Failed to initialize ADS.");
while (1);
}
pinMode(READY_PIN, INPUT);
// We get a falling edge every time a new sample is ready.
attachInterrupt(digitalPinToInterrupt(READY_PIN), NewDataReadyISR, FALLING);
// Start continuous conversions.
ads.startADCReading(ADS1X15_REG_CONFIG_MUX_DIFF_0_1, /*continuous=*/true);
}
void loop(void)
{
// If we don't have new data, skip this iteration.
if (!new_data) {
return;
}
int16_t results = ads.getLastConversionResults();
Serial.print("Differential: "); Serial.print(results); Serial.print("("); Serial.print(ads.computeVolts(results)); Serial.println("V)");
new_data = false;
// In a real application we probably don't want to do a delay here if we are doing interrupt-based sampling, but we have a delay
// in this example to avoid writing too much data to the serial port.
delay(100);
}
シリアルモニターで確認した様子がこちら。
あとはこれを実用的な内容に少し書き換えれば、自由にデータが取得できます。
一応簡単な動作確認はできたので、このあと本格的な実験を行う予定です。