wiki:epics/weather_sensor

Version 2 (modified by michkawa, 7 years ago) (diff)

--

USB 温湿度/大気圧センサ

以前作った、USB接続 温湿度/大気圧センサ に関する情報をまとめておく。

何で作ったか

温湿度/大気圧を測定するのに おんどとり(T&D TR73U)を使っているが、値段が高いので、気軽に置いておくわけにはいかない。
最近は半導体温湿度センサーが安くなってきて、しかもデジタル出力(I2C,SPI等)なので、面倒な校正作業が必要ないはず。
I2Cを普通のPCでは接続できないけど、arduinoのようなマイコンならば普通につなげるのでお手軽ではないか。
ということで、作ってみました。

基本構成

  • センサーはI2C接続、3.3V
  • なるべく小さく、安く
  • 電源と信号線を考えると、結局USB接続が一番お手頃
    • 電池は、交換が必要なのでNG
    • シリアルでもいいけど、RS232Cは1対1だし、RS485は接続が意外と面倒なのでNG
  • USB接続とは言っても、FTDIのUSBシリアル変換チップなので、実質シリアル通信
  • 開発はarduinoでできるように

ということを総合して考えたのが、

の組み合わせ。

ATTiny85を使ったシステムはarduino unoのようにUSBからプログラムを変更できないけど、一回書き込めば変更することはないので問題なし。書き込みはarduino UNOをライターとして使用する。
ATTiny85を内部クロック8MHzで動かし、3.3V電源はFT232RLから供給する。センサとはI2Cで接続し、一定時間ごとに受信したデータはCPUで文字列に変換してFT232でホストに送信する。
ホストから設定値を送ることはしないので、センサからデータが常時垂れ流されているデバイスとして使用することになる。

回路図,基板

I2CはSDA(5pin),SCL(7pin)、serial(UART)がTX(3pin),RX(2pin)になるように設計。

基板のベタ面GNDを切り離していなかったせいか、温度が若干高く測定されるように思われるが、他のデバイスとの相関を取ったわけではないので、正確なところはわからない。
ただ、個人的な趣味で、温度のみを測定するI2Cデバイスとの温度差を見てみた時にはそれほどずれていなかったので、単純にオフセットしているだけなのかも。

制御用プログラム

制御プログラムはarduinoで作成。
HITU21Dのサンプルプログラムをベースに作成した。

ATTiny85にはHW UARTがないのでSoftwareSerialを使い、I2Cはarduino標準ライブラリが使用できないのでライブラリを追加した。

また、HTU21DとMPL115A2のarduino用ライブラリもWireライブラリを使うことを前提に書かれていたので、TinyWireMを使うように修正。
修正内容としては、ヘッダファイルをWire.h -> TinyWire.H}に変更したのと、Wire.TinyWireM.に書き直しただけ。


#include <SoftwareSerial.h>
#include <TinyWireM.h>
#include "HTU21D_TinyWire.h"
#include "MPL115A2_TinyWire.h"

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

//Create an instance of the object
HTU21D_TinyWire myHumidity;
SoftwareSerial SwSerial(3, 4); // RX, TX

void
printfloat(float val, int prec)
{
  int i;
  float precMag = 1;
  int num = (int)val;
  SwSerial.print(num, DEC);
  SwSerial.print(".");
  
  for(i=0 ; i<prec ; i++) {
    precMag *= 10;
  }
  float precVal = (val - (float)num);
  num = (int)(precVal * precMag);
  for(i=prec-1 ; i>=0 ; i--) {
    precMag /= 10;
    if(precMag > num) {
      SwSerial.print("0");
    } else {
      break;
    }
  }
  SwSerial.print(num, DEC);
}

void setup()
{
  SwSerial.begin(9600);
  MPL115A2.begin();
  myHumidity.begin();
  cbi(ADCSRA,ADEN);
}

void loop()
{
  float humd = myHumidity.readHumidity();
  float temp = myHumidity.readTemperature();
  float pres = MPL115A2.read();

  SwSerial.print("T:");
  printfloat(temp, 2);
  SwSerial.print(" H:");
  printfloat(humd, 2);
  SwSerial.print(" A:");
  printfloat(pres, 2);
  SwSerial.print("\r\n");
  delay(5000);
}

出力文字列は、

T:xx.xx H:xx.xx A:xx.xx\r\n

となる。

Attachments (2)

Download all attachments as: .zip