2010年11月24日水曜日

定点観測データロガー -3 : 気温・湿度・温度・照度計測


フィールド設置型の定点観測ロガーを作成する。

< 定点観測器の仕様 >
  1. 計測内容は、計測時刻・気温・湿度・温度・照度とする。
  2. Arduino Pro 328 3.3V 8MHz をスタンドアロンで動作させる。
  3. 単三乾電池4個を電源とし、最低一週間は稼働する省電力設計とする。
  4. 設定した間隔で持続的にデータを記録できるものとする。
  5. 定期的に記録データ媒体と乾電池を交換できる設計とする。
  6. 計測データの保存はSDカードを使用する。
使用する各センサについて。


< 温度センサ >



温度センサをセットする時はまず測定温度範囲を決める。
温度センサは計測した温度によって出力する電圧が変化する素子で、
その電圧はAD変換されて0〜1023の値として取得できる。
今回はArduino Pro 328 3.3V を使用するので、0V〜3.3V = 0〜1023となる。
計算しやすいので、100℃までの計測範囲とする。
そうすると、オペアンプのゲインは

LM35DZ
1個100円(秋月電子)
精度 ±1.0℃(最大)
温度係数 +10mV/℃
オフセット電圧 0V
測定温度範囲0〜100℃
100℃の時、100 × 0.01V = 1V
AD値をフルレンジ(0〜1023)で使用する場合のゲイン : 3.3V / 1V = 3.3

LM60BIZ
1個100円(秋月電子)
精度 ±4.0℃
温度係数 +6.25mV/℃
オフセット電圧 424mV
測定温度範囲-40〜125℃
100℃の時、100 × 0.00625V + 0.424V = 1.049V
AD値をフルレンジ(0〜1023)で使用する場合のゲイン : 3.3V / 1.049V = 約3.1

LM61CIZ
4個200円(秋月電子)
精度 ±4.0℃
温度係数 +10mV/℃
オフセット電圧 600mV
測定温度範囲-30〜100℃
100℃の時、100 × 0.01V + 0.6V = 1.6V
AD値をフルレンジ(0〜1023)で使用する場合のゲイン : 3.3V / 1.6V = 約2

となる。
詳しくはこちら




/*
 * sketch name   : temp_measure
 * summary       : 三種類の温度センサを使用して温度計測する
 */

/* Arduino 基準電圧 */
#define ARDUINO_VCC 3.3

/* 温度センサ  type / 0:LM35DZ  1:LM60BIZ  2:LM61CIZ */
unsigned int temp_pins[]        = {0, 1, 2};      // アナログピン0,1,2
unsigned int temp_sensor_type[] = {0, 1, 2};      // 使用センサタイプ(temp_pins の値に対応)
float        temp_gain[]        = {3.3, 3.1, 2};  // Op-amp ゲイン(temp_pins の値に対応)

/* センサのカウント回数 */
#define CNT_TEMP_PINS sizeof(temp_pins) / sizeof(temp_pins[0])

float temp;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  Serial.println("**********************");
  
  for (int i = 0; i < CNT_TEMP_PINS; i++) {
    temp = tempCalc(ARDUINO_VCC, temp_sensor_type[i], analogRead(i), temp_gain[i]);
    
    Serial.print("sensor type");
    Serial.print(i);
    Serial.print(" : ");
    Serial.println(temp_sensor_type[i]);
    Serial.print("temperature : ");
    Serial.println(temp);
  }
  
  Serial.println("**********************");
  Serial.println();
  delay(5000);
}

/*
 * func name  : tempCalc
 * processing : 温度センサ処理
 * param      : arduino_vcc / Arduino 基準電圧
 *              sensor_type / 0 : LM35DZ
 *                            1 : LM60BIZ
 *                            2 : LM61CIZ
 *              analog_val  / Analog値(0-1023)
 *              gain        / Op-amp ゲイン
 * return     : temp        / 計測温度(℃)
 */
float tempCalc (float arduino_vcc, int sensor_type, int analog_val, float gain)
{
  float dc_offset;  // DCオフセット電圧(V)
  float factor;     // 温度係数(V/1℃)
  
  switch (sensor_type) {
    
    // LM35DZ
    // DCオフセット 0V
    // +10mV/℃
    case 0:
      dc_offset = 0;
      factor    = 0.01;
      break;
      
    // LM60BIZ
    // DCオフセット 424mV
    // +6.25mV/℃
    case 1:
      dc_offset = 0.424;
      factor    = 0.00625;
      break;
      
    // LM61CIZ
    // DCオフセット 600mV
    // +10mV/℃
    case 2:
      dc_offset = 0.6;
      factor    = 0.01;
      break;
      
    define:
      return 0;
      break;
  }
  
  return (((arduino_vcc * analog_val) / 1024) - (dc_offset * gain)) / (factor * gain);
}



なんだか計測温度が微妙にずれているけれど、これくらいの誤差はしょうがない。
精度はLM35DZが一番いいみたいだけど、氷点下まで計測したいので、LM60BIZを使用することにする。


< 照度センサ >


このフォトダイオードについてはセンサ活用の素 (1)の回路をそのまま使用することにした。
これによると3300ルクスまで計測できることになるが、0〜1023のAD変換値でしか取得できないので精度はかなり落ちる。
照度は暗闇から真夏の直射日光まで、0〜約10000と幅がありすぎる。
1024段階の値で測定しようとするのは仕様的に無理があるけど、
正確なルクスを得ようというよりは日照時間が知りたいだけなので、このくらいアバウトでいい。




/*
 * sketch name   : illmi_measure
 * summary       : フォトダイオード S9648-100 を使用して照度計測する
 */

/* Arduino 基準電圧 */
#define ARDUINO_VCC 3.3

/* 照度センサ  type / 0:S9648-100 */
unsigned int illumi_pin = 3;                  // アナログピン3
#define      ILLMI_MAX_LX ARDUINO_VCC * 1000  // S9648-100使用時の最大計測照度(lx)

float illmi;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  illmi = (analogRead(illumi_pin) * ILLMI_MAX_LX) / 1024;
  
  Serial.print("Illumination : ");
  Serial.println(illmi);
  Serial.println();
  
  delay(5000);
}






< SHTセンサ >

センサは以前と同じSHT-71を使用する。
Sensirionのライブラリをこちらからダウンロードして解凍後、/Arduino/library/ 以下に設置する。
スケッチはサンプルのものがそのまま使用できるが、CLOCKピンとDATAピンはそれぞれデジタルピン7と8に変えてある。
気温と湿度だけではなく、露点も計測できるようなのでついでに計測しておく。



/*
 * Query a SHT10 temperature and humidity sensor
 *
 * A simple example that queries the sensor every 3 seconds
 * and communicates the result over a serial connection.
 * Error handling is omitted in this example.
 */

#include "Sensirion.h"

#define DATAPIN  8
#define CLOCKPIN 7

float temperature;
float humidity;
float dewpoint;

Sensirion tempSensor = Sensirion(DATAPIN, CLOCKPIN);

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  tempSensor.measure(&temperature, &humidity, &dewpoint);

  Serial.print("Temperature: ");
  serialPrintFloat(temperature);
  Serial.print(" C, Humidity: ");
  serialPrintFloat(humidity);
  Serial.print(" %, Dewpoint: ");
  serialPrintFloat(dewpoint);
  Serial.println(" C");
  
  delay(3000);  
}

void serialPrintFloat(float f){
  Serial.print((int)f);
  Serial.print(".");
  int decplace = (f - (int)f) * 100;
  Serial.print(abs(decplace));
}

0 コメント:

コメントを投稿