Changes between Version 1 and Version 2 of epics/weather_sensor


Ignore:
Timestamp:
08/18/17 13:34:52 (8 years ago)
Author:
Tetsuya Michikawa
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • epics/weather_sensor

    v1 v2  
    1 = 温度/湿度/大気圧センサ =
     1= USB 温湿度/大気圧センサ =
    22
    3 以前、[https://www.tandd.co.jp/product/tr7ui_series.html おんどとり]の代わりにするために、作成した温度/湿度/大気圧センサモジュールの情報をまとめておく。
     3以前作った、USB接続 温湿度/大気圧センサ に関する情報をまとめておく。
     4
     5== 何で作ったか ==
     6
     7温湿度/大気圧を測定するのに [https://www.tandd.co.jp/product/tr7ui_series.html おんどとり(T&D TR73U)]を使っているが、値段が高いので、気軽に置いておくわけにはいかない。[[br]]
     8最近は半導体温湿度センサーが安くなってきて、しかもデジタル出力(I2C,SPI等)なので、面倒な校正作業が必要ないはず。[[br]]
     9I2Cを普通のPCでは接続できないけど、arduinoのようなマイコンならば普通につなげるのでお手軽ではないか。[[br]]
     10ということで、作ってみました。[[br]]
     11
     12== 基本構成 ==
     13
     14 * センサーはI2C接続、3.3V
     15 * なるべく小さく、安く
     16 * 電源と信号線を考えると、結局USB接続が一番お手頃
     17   * 電池は、交換が必要なのでNG
     18   * シリアルでもいいけど、RS232Cは1対1だし、RS485は接続が意外と面倒なのでNG
     19 * USB接続とは言っても、FTDIのUSBシリアル変換チップなので、実質シリアル通信
     20 * 開発はarduinoでできるように
     21
     22ということを総合して考えたのが、
     23
     24 * [http://www.atmel.com/ja/jp/devices/attiny85.aspx atmel attiny85 (CPU)]
     25 * [http://www.ftdichip.com/Products/ICs/FT232R.htm FTDI FT232RL (USB/Serial変換)]
     26 * [http://www.te.com/commerce/DocumentDelivery/DDEController?Action=srchrtrv&DocNm=HPC199_6&DocType=Data+Sheet&DocLang=English TE(旧ハウネル) HTU21D (温湿度センサ)]
     27 * [http://www.nxp.com/docs/en/data-sheet/MPL115A2.pdf NXP(旧freescale) MPL115A2(大気圧センサ)]
     28
     29の組み合わせ。[[br]]
     30
     31ATTiny85を使ったシステムはarduino unoのようにUSBからプログラムを変更できないけど、一回書き込めば変更することはないので問題なし。書き込みはarduino UNOをライターとして使用する。[[br]]
     32ATTiny85を内部クロック8MHzで動かし、3.3V電源はFT232RLから供給する。センサとはI2Cで接続し、一定時間ごとに受信したデータはCPUで文字列に変換してFT232でホストに送信する。[[br]]
     33ホストから設定値を送ることはしないので、センサからデータが常時垂れ流されているデバイスとして使用することになる。[[br]]
     34
     35== 回路図,基板 ==
     36
     37[[Image(weather_sch.png,400)]]
     38
     39I2CはSDA(5pin),SCL(7pin)、serial(UART)がTX(3pin),RX(2pin)になるように設計。
     40
     41
     42[[Image(weather_gbr.png,400)]]
     43
     44基板のベタ面GNDを切り離していなかったせいか、温度が若干高く測定されるように思われるが、他のデバイスとの相関を取ったわけではないので、正確なところはわからない。[[br]]
     45ただ、個人的な趣味で、温度のみを測定するI2Cデバイスとの温度差を見てみた時にはそれほどずれていなかったので、単純にオフセットしているだけなのかも。
     46
     47
     48== 制御用プログラム ==
     49
     50制御プログラムはarduinoで作成。[[br]]
     51HITU21Dのサンプルプログラムをベースに作成した。[[br]]
     52
     53ATTiny85にはHW UARTがないのでSoftwareSerialを使い、I2Cはarduino標準ライブラリが使用できないのでライブラリを追加した。
     54
     55 * [https://github.com/adafruit/TinyWireM TinyWireM]
     56
     57また、HTU21DとMPL115A2のarduino用ライブラリもWireライブラリを使うことを前提に書かれていたので、TinyWireMを使うように修正。[[br]]
     58修正内容としては、ヘッダファイルを{{{Wire.h -> TinyWire.H}}}}に変更したのと、{{{Wire.}}}を{{{TinyWireM.}}}に書き直しただけ。[[br]]
     59
     60{{{
     61
     62
     63#include <SoftwareSerial.h>
     64#include <TinyWireM.h>
     65#include "HTU21D_TinyWire.h"
     66#include "MPL115A2_TinyWire.h"
     67
     68#ifndef cbi
     69#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
     70#endif
     71#ifndef sbi
     72#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
     73#endif
     74
     75//Create an instance of the object
     76HTU21D_TinyWire myHumidity;
     77SoftwareSerial SwSerial(3, 4); // RX, TX
     78
     79void
     80printfloat(float val, int prec)
     81{
     82  int i;
     83  float precMag = 1;
     84  int num = (int)val;
     85  SwSerial.print(num, DEC);
     86  SwSerial.print(".");
     87 
     88  for(i=0 ; i<prec ; i++) {
     89    precMag *= 10;
     90  }
     91  float precVal = (val - (float)num);
     92  num = (int)(precVal * precMag);
     93  for(i=prec-1 ; i>=0 ; i--) {
     94    precMag /= 10;
     95    if(precMag > num) {
     96      SwSerial.print("0");
     97    } else {
     98      break;
     99    }
     100  }
     101  SwSerial.print(num, DEC);
     102}
     103
     104void setup()
     105{
     106  SwSerial.begin(9600);
     107  MPL115A2.begin();
     108  myHumidity.begin();
     109  cbi(ADCSRA,ADEN);
     110}
     111
     112void loop()
     113{
     114  float humd = myHumidity.readHumidity();
     115  float temp = myHumidity.readTemperature();
     116  float pres = MPL115A2.read();
     117
     118  SwSerial.print("T:");
     119  printfloat(temp, 2);
     120  SwSerial.print(" H:");
     121  printfloat(humd, 2);
     122  SwSerial.print(" A:");
     123  printfloat(pres, 2);
     124  SwSerial.print("\r\n");
     125  delay(5000);
     126}
     127}}}
     128
     129出力文字列は、
     130
     131
     132{{{
     133T:xx.xx H:xx.xx A:xx.xx\r\n
     134}}}
     135
     136
     137となる。
     138