「光強度」をなるべく安価で高精度に測定したい(Arduino + ADS1115 + フォトICダイオード)
この記事は Arduino Advent Calendar 2021 12日目の記事です。
はじめに
この記事はデジタル信号で光強度測定を行う際に必要になる受光素子 -> PCまでのインターフェースをArduinoを使って安価に作成した(?)ものです。
前提
光学測定は基本的に
光源 -> 受光素子(フォトダイオードなど) -> I-Vアンプ -> データロガー -> PC
↑の流れで、受光素子によって得た光電流をI-Vアンプによって電圧に変換・増幅し、A/D変換をして数値をPCに出力します。
特にI-Vアンプ
とデータロガー
と接続するケーブルなどなど全部揃えようとすると簡単に数万~数十万
は飛んでいきます。
札束で殴ることができる方は良いのですが、僕のような貧乏な研究室に所属する学生にとっては正直辛く、他の代替手段を探すしかありません。。。。
代替案
先に結論を述べますが、I-Vアンプの部分は、フォトICダイオードと負荷抵抗、データロガーの部分にArduinoを使用しています。
[主に使用したもの]
- フォトICダイオード
-> 使用したものは光電流を1300倍に増幅してくれて、かつ負荷抵抗の接続で十分な出力電圧得られます
- Arduino UNO R3
- ADS1115
-> 電圧値のbit分解能を向上させるために使用します
接続
- ADS1115とArduinoそしてP.ICと抵抗を繋いだだけです。
分解能について
Arduinoのアナログ入力分解能は10bitなので、1024段階 -> ADS1115を接続することで16bit(2^16=65536段階)で電圧値を測定することができます。ちなみに1bit分は2の補数を表すのでプラスの電圧は15bitでの分解能になります。
わかりやすいサイト
サンプルコード
- Adafruit公式に単動、差動入力によってのサンプルコードが掲載されているのでこれを使うと簡単に動作が確認できます。
#include <Adafruit_ADS1X15.h>
// Adafruit_ADS1115 ads; /* Use this for the 16-bit version */
Adafruit_ADS1015 ads; /* Use this for the 12-bit version */
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);
}}
void loop(void)
{
int16_t results;
/* Be sure to update this value based on the IC and the gain settings! */
float multiplier = 3.0F; /* ADS1015 @ +/- 6.144V gain (12-bit results) */
//float multiplier = 0.1875F; /* ADS1115 @ +/- 6.144V gain (16-bit results) */
results = ads.readADC_Differential_0_1();
Serial.print("Differential: "); Serial.print(results); Serial.print("("); Serial.print(results * multiplier); Serial.println("mV)");
delay(1000);
}
結果
波長635nWレーザーを用いて、照度0.1lx以下-最光電流1uAの場合でデジタル値の値が変化していることを確認しています。(LSB 125uV)
個人的に作成して思ったメリット
- 差動入力でそこそこノイズを抑えられる
- 小型で簡易的な実験がやりやすそう
- Arduino側の処理がカスタマイズし放題
- 計測間隔の調整やProcessing等を用いたデータ出力,その他豊富なライブラリを簡単に使える
まとめ
-
amazonや秋月電子でサクッと買えるセンサー類で、100uVオーダーくらいの分解能を持つデジタル電圧計測計がつくれます
-
研究用途など精度や分解能が重要になる場合はメーカーの既存品を買うべきだと思います。
参考
Discussion