2016年1月11日月曜日

Arduinoで水温計DS18B20を使う


備忘録としてメモを残します。

使ったもの


回路

温度プローブを下記のように接続しました。
青には信号読み取りのためのD6と、プルアップのための抵抗を接続しています。

  • 赤 <--> 5V
  • 青 <--> Arduino D6
  • 青 <--> 5kの抵抗 <-> 5V
  • 黒 <--> GND


ソフトウェア

OneWireというライブラリが必要です。 Dallas Semiconductor's 1-Wire Protocol
上記のアドレスから最新版をダウンロードして、zipを解凍して出来る「OneWire」というフォルダをArduinoのlibrariesフォルダに置きます。 読み込みがうまくいくと、Arduinoのエディタ再起動後にOneWireが認識されます。
このプログラムは接続された一つの温度計の温度を返すようにしています。 温度計にはアドレスが付与されているので、プログラムを頑張れば、一つの海鮮で複数の温度計を管理することもできるみたいです。
temperature_test
#include <OneWire.h>

// DS18S20 Temperature chip i/o
OneWire ds(6);  // on pin 6

void setup(void) {
  // initialize inputs/outputs
  // start serial port
  Serial.begin(9600);
}

void loop(void) {
  float temperature = getTemperature();

  Serial.print(temperature);
  Serial.println();
}

void updateData(byte* data) {
  byte i;
  byte present = 0;
  byte addr[8];

  ds.reset_search();
  if ( !ds.search(addr)) {
      ds.reset_search();
      return;
  }

  if ( OneWire::crc8( addr, 7) != addr[7]) {
    // CRC is not valid!
    return;
  }

  if ( addr[0] != 0x10 && addr[0] != 0x28) {
    // Device family is not recognized: 0x
    return;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1);         // start conversion, with parasite power on at the end

  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.

  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
  }

}

float getTemperature() {
  byte data[12];
  updateData(data);

  int HighByte, LowByte, TReading, SignBit, Tc_100;
  LowByte = data[0];
  HighByte = data[1];
  TReading = (HighByte << 8) + LowByte;
  SignBit = TReading & 0x8000;  // test most sig bit

  if (SignBit) // negative
  {
    TReading = (TReading ^ 0xffff) + 1; // 2's comp
  }
  Tc_100 = (6 * TReading) + TReading / 4;    // multiply by (100 * 0.0625) or 6.25

  if (SignBit) {
    Tc_100 = - Tc_100;
  }

  return Tc_100 / 100.0;
}

動作確認

シリアルモニタで確認します。 息を吹きかけたりすると、数値が上がると思います。
以上です。

参考

Dallas Semiconductor's 1-Wire Protocol Arduino+DS18B20で温度測定してみた

更新履歴

2016.01.01
信号線への接続説明が抜けていたので追加しました。

0 件のコメント :