2015年3月7日土曜日

8pinoでインフルエンザ感染リスク検知器をつくる②

今回は,I2C通信がうまくいっているのか確認する事にします.前回のエントリで「8pinoはシリアル通信できない」と書きましたが,正確にはシリアル通信できるみたいです.8pinoはUSBシリアル通信できないのですが「ソフトウェアシリアル」には対応しているので,8pinoの2本のpinをRX・TX通信路として使い,USBシリアル変換モジュールを使えばいいみたいです.

そこで秋月でUSBシリアル変換モジュールを購入し,8pinoの#0・#4 pinをそれぞれRX・TXに設定してみましたが,どうにもモニタできませんでした.オシロスコープで確認したところ,信号はきちんと出てるようなので,おそらくシリアル変換モジュールとPCの問題だと思います.ちなみに使用しているのはMacbook Airで,OSはYosemiteです.ドライバのインストールなどは問題無いと思います,認識もされているんですが・・・。なぜでしょうか.

仕方が無いので,Unoに8pinoのスケッチを書き込んで,シリアルモニタできちんと動いているか確認しました.まあ,Unoで動く事が確認できても8pinoで動いてるかわかんないんですが・・・.ちゃんと動きました.
TinyWireM.hをWire.hに変更しています
きちんと感染リスク(容積絶対湿度)が計算できている事が確認できました.修正したスケッチをのせておきます.変更点としては,HDC1000のRDY pinの機能を使う代わりにdelay()を使いました.これで8pinoの貴重なpin1本が節約できました.この節約できたpinにスイッチをつけたいと思います.
また,loop()のなかで温度と湿度を逐次計測するように変更しました.これできちんと動いているか,外気温度を変えたりすれば確認できます.

#include <TinyWireM.h>

//温湿度センサモジュール
#define HDC1000_ADDRESS 0x40 //温度センサモジュールのアドレス(固定)
#define HDC1000_TEMPERATURE_POINTER     0x00
#define HDC1000_CONFIGURATION_POINTER   0x02
#define HDC1000_CONFIGURE_MSB 0x10 //0x10=00010000
#define HDC1000_CONFIGURE_LSB 0x00 //0x00=00000000

int ledR = 1; //LEDの赤Anode
int ledB = 4; //LEDの青Anode
float ab_hum; //容積絶対湿度[g/m3]

void setup() { 
pinMode(ledR, OUTPUT); 
pinMode(ledB, OUTPUT);
TinyWireM.begin(); //initialize I2C bus
delay(15); //HDC1000は電源on後15msec程度の待ち時間が必要
configure(); //HDC1000の初期設定
delay(10);

getTempAndHumid(&ab_hum);
}

void loop() {
  if(ab_hum < 7){
    analogWrite(ledR, 100);
    delay(2000);
  }else if(7 <= ab_hum && ab_hum < 11){
    analogWrite(ledR, 100);
    analogWrite(ledB, 150);
    delay(2000);
  }else{
    analogWrite(ledB, 100);
    delay(2000);
  }
  digitalWrite(ledR, LOW);
  digitalWrite(ledB, LOW);
  delay(1000);
  getTempAndHumid(&ab_hum);
}

void configure(){ //Setup the HDC1000
  TinyWireM.beginTransmission(HDC1000_ADDRESS);
  TinyWireM.send(HDC1000_CONFIGURATION_POINTER); //pointerを指定した後
  TinyWireM.send(HDC1000_CONFIGURE_MSB);         //2byte(つまり8bit 8bit)のデータを送信している
  TinyWireM.send(HDC1000_CONFIGURE_LSB);         //この場合 00010000 00000000 従って12bit目が1にセットされた。
  TinyWireM.endTransmission();                   //12bit目が1だと温度湿度の順に32bitデータを送信するモードになる
}                                                //詳細はHDC1000のデータシートを参照

void getTempAndHumid(float *ab_hum){ //気温と相対湿度から容積絶対湿度を求める
  float tem, hum; //temparature[deg], humidity(相対湿度)[%]
  float sp_hum, p, wp, roh;
  int tempData, humidData;
  
  TinyWireM.beginTransmission(HDC1000_ADDRESS);
  TinyWireM.send(HDC1000_TEMPERATURE_POINTER);
  TinyWireM.endTransmission();
  delay(500);
  TinyWireM.requestFrom(HDC1000_ADDRESS, 4);
  while(TinyWireM.available() < 4){            //温度湿度それぞれ2byteのデータが送られてくる;
    ;
  }
  tempData = TinyWireM.receive() << 8;
  tempData |= TinyWireM.receive();
  humidData = TinyWireM.receive() << 8;
  humidData |= TinyWireM.receive();
  
  tem = tempData / 65536.0 * 165.0 - 40.0; //温度と湿度に変換
  hum = abs(humidData / 65536.0 * 100.0); //なぜか湿度が負になることがある
  
  //容積絶対湿度[g/m3]の計算
  p = 6.1078 * pow(10, (7.5 * tem) / (237.3 + tem)); //飽和水蒸気圧[hPa] Tetens equation
  wp = p * hum / 100; //水蒸気圧[hPa]
  sp_hum = 622 * wp / (1013.25 - wp); //重量絶対湿度[g/kg] 大気圧を1013.25hPaとした
  roh = 1.293 * 1 / (1 + tem / 273.15) * (1 - 0.378 * wp / 1013.25); //空気の密度[kg/m3]
  *ab_hum = sp_hum * roh; //容積絶対湿度[g/m3]
}


(右)リスクが低い,つまり温度や湿度が高いと青色に光ります
(左)逆にリスクが高くなると赤色っぽくなります
次回はスイッチを組み込みたいと思います.

Parts Lists

USBシリアル変換モジュール: http://akizukidenshi.com/catalog/g/gM-08461/

Reference


Note
なぜかHDC1000から送られてくる湿度が負を示す事があります.どうやらある値より大きな湿度の時にそうなるようです.絶対値は正しいようなので,とりあえずabs()で対応しています.なぜ負になるのか理由はまだわかりません.

2015年3月2日月曜日

昆虫クッキー

バレンタインから結構日がたってしまいましたが,研究室の4年生が作ってきてくれた昆虫クッキーを紹介します.
いろんな種類の昆虫がよくできています.色とりどりで美しいです.
自分が所属している研究室のテーマに「昆虫脳の比較」というものがあるのですが,それを担当している学生が作ってきてくれました.昆虫愛にあふれてますね!!本人は「虫はそんなに好きじゃない」と言っていますがw

私はお菓子とかを作った経験がないのでいまいちピンとこないのですが,これは「アイシングクッキー」というものだそうです.クッキーを虫の形に切り出して焼いたあとに,色をつけた「アイシングクリーム」やチョコレートで絵を書くそうです.

Reference

アイシングクッキーについて : http://matome.naver.jp/odai/2138899879076093801

2015年3月1日日曜日

8pinoでインフルエンザ感染リスク検知器をつくる①

Arduino互換機で(多分)最小サイズの8pino.
発売前から気になっていたのですが,先日やっと購入しました.
届いてみると,その小ささと美しさにビックリ.
8pinoのパッケージ.美しいです.
今回は8pinoを使って「インフルエンザ感染リスク検知器」を作ろうと思います.イメージとしては「インフルエンザ予防目安温湿度計」の簡易バージョンですね.コンセプトも要求機能もサイズも8pinoにぴったりだと思います.
インフルエンザ感染予防目安温湿度計
この機能性に優れたカッコいい器械を8pinoで作ります
/////////////////////////////////////////////////////
Concept
① 温度・湿度を計測
② 感染リスクを計算
③ LEDの色でリスクを表示
//////////////////////////////////////////////////////

8pinoで開発しやすいように,pinをハンダ付けしました.8pino自体よりもpinの方が大きいくらいですw

ブレッドボードにさすとこんな感じです.USBを直接繋ぎます.

とりあえず,赤青2色LEDを光らせてみます.(本当はRGB LEDを使いたかったんですが,pinの数がたらないので2色にしました・・・)今回使用したLEDはカソードコモンでしたので,カソードをGNDに接続して,8pinoのpin #1をLEDの赤anodeに,pin #4を青anodeに繋ぎます.本当は電流制限抵抗とか入れるべきなのでしょうが,横着してそのまま繋ぎます.ジャンパ線の色がむちゃくちゃなのは気にしないでください(涙

赤・青・紫(赤+青)がつきました.Lチカ成功です!!w
さて,LEDはついたので次は温度と湿度の測定です.
8pinoはI2C通信に対応しているので,I2Cの温湿度計が使えそうです.
今回はHDC1000搭載のモジュールを使ってみます.

HDC1000温湿度モジュール.小さいしデザインも好みなのでよく使います.
8pinoは,pin #0がSDA,pin #2がSCLなのでそのように繋ぎます.そうそう,8pinoは3.3V駆動なので何も考えずにモジュールと繋いで大丈夫ですね.スケッチは例えばこんな感じです.setup()で温度と湿度を一度だけ計測して,インフルエンザの感染リスクを計算します.感染リスクは次のようにして計算しています.
容量絶対湿度[g/m^3]を求める→7 g/m^3以下なら危険(赤),7~11 g/m^3なら中程度(紫),11~ g/m^3なら低(青)となるようにLEDを光らせます.

#include <TinyWireM.h>

//温湿度センサモジュール
#define HDC1000_ADDRESS 0x40 //温度センサモジュールのアドレス(固定)
#define HDC1000_RDY 3        //温度センサモジュールのRDY pinを8pinoの3に繋ぐ
#define HDC1000_TEMPERATURE_POINTER     0x00
#define HDC1000_CONFIGURATION_POINTER   0x02
#define HDC1000_CONFIGURE_MSB 0x10 //0x10=00010000
#define HDC1000_CONFIGURE_LSB 0x00 //0x00=00000000

int ledR = 1; //LEDの赤Anode
int ledB = 4; //LEDの青Anode
float ab_hum; //容量絶対湿度[g/m3]

void setup() { 
pinMode(ledR, OUTPUT); 
pinMode(ledB, OUTPUT);
TinyWireM.begin(); //initialize I2C bus
delay(15); //HDC1000は電源on後15msec程度の待ち時間が必要
configure(); //HDC1000の初期設定
delay(10);

getTempAndHumid(&ab_hum);
}

void loop() {
  if(ab_hum < 7){
    analogWrite(ledR, 100);
    delay(2000);
  }else if(7 <= ab_hum && ab_hum < 11){
    analogWrite(ledR, 100);
    analogWrite(ledB, 150);
    delay(2000);
  }else{
    analogWrite(ledB, 100);
    delay(2000);
  }
  digitalWrite(ledR, LOW);
  digitalWrite(ledB, LOW);
  delay(1000);
}

void configure(){ //Setup the HDC1000
  TinyWireM.beginTransmission(HDC1000_ADDRESS);
  TinyWireM.send(HDC1000_CONFIGURATION_POINTER); //pointerを指定した後
  TinyWireM.send(HDC1000_CONFIGURE_MSB);         //2byte(つまり8bit 8bit)のデータを送信している
  TinyWireM.send(HDC1000_CONFIGURE_LSB);         //この場合 00010000 00000000 従って12bit目が1にセットされた。
  TinyWireM.endTransmission();                   //12bit目が1だと温度湿度の順に32bitデータを送信するモードになる
}                                                //詳細はHDC1000のデータシートを参照

void getTempAndHumid(float *ab_hum){ //気温と相対湿度から容積絶対湿度を求める
  float tem, hum; //temparature[deg], humidity(相対湿度)[%]
  float sp_hum, p, wp, roh;
  int tempData, humidData;
  
  TinyWireM.beginTransmission(HDC1000_ADDRESS);
  TinyWireM.send(HDC1000_TEMPERATURE_POINTER);
  TinyWireM.endTransmission();
  while(digitalRead(HDC1000_RDY) == HIGH){//HDC1000はデータ変換が終了するとRDY pinをHIGHにする
    ;
  }
  TinyWireM.requestFrom(HDC1000_ADDRESS, 4);
  while(TinyWireM.available() < 4){            //温度湿度それぞれ2byteのデータが送られてくる;
    ;
  }
  tempData = TinyWireM.receive() << 8;
  tempData |= TinyWireM.receive();
  humidData = TinyWireM.receive() << 8;
  humidData |= TinyWireM.receive();
  
  tem = tempData / 65536.0 * 165.0 - 40.0; //温度と湿度に変換
  hum = humidData / 65536.0 * 100.0;
  
  //容積絶対湿度[g/m3]の計算
  p = 6.1078 * pow(10, (7.5 * tem) / (237.3 + tem)); //飽和水蒸気圧[hPa] Tetens equation
  wp = p * hum / 100; //水蒸気圧[hPa]
  sp_hum = 622 * wp / (1013.25 - wp); //重量絶対湿度[g/kg] 大気圧を1013.25hPaとした
  roh = 1.293 * 1 / (1 + tem / 273.15) * (1 - 0.378 * wp / 1013.25); //空気の密度[kg/m3]
  *ab_hum = sp_hum * roh; //容積絶対湿度[g/m3]
}

8pinoはI2Cに対応しているのですが,Arduino標準のWireライブラリが使えないそうです.マニュアル通りTinyWireライブラリをダウンロードして使えました.使い方はWireライブラリの関数とほとんど同じです.

動かしてみました.この時期はほぼ赤ですね(汗
8pinoはシリアル通信でモニタできないので,温湿度モジュールときちんと通信できているか確認するのが難しいですね.多分動いていると思いますが,あやしいです.次回はI2Cの通信の確認とスイッチの組み込みをしたいと思います.

Parts Lists

2色LED(赤・青)OSRB3132A x1 : http://akizukidenshi.com/catalog/g/gI-04079/
HDC1000温湿度センサモジュール x1 : http://akizukidenshi.com/catalog/g/gM-08775/

Reference

TinyWireMライブラリ: https://github.com/adafruit/TinyWireM
HDC1000温湿度モジュールの使い方について: http://garretlab.web.fc2.com/arduino/lab/temperature_and_humidity_sensor/index.html

Note

8pinoはスケッチの書き込みに癖があるみたいです.このあたりが8pinoはArduino互換というよりTrinket互換機といわれるゆえんでしょうか.8pinoはUSBをPCと繋ぐことで書き込みモードに移項します.書き込みモードになると,pin #1につながっているLEDが点滅します.点滅しているときが書き込み可能時間だそうです.この間にIDEの書き込みボタンを押せば書き込めます.公式サイトのマニュアルでは,書き込みボタンを押す直前・直後にUSBをつなげと書いてありますが,私の環境ではそこまでシビアにやる必要は無いです.ただ,なぜか書き込みモードにならなくなった8pinoがありますが・・・(壊れた?).

2015年2月19日木曜日

はじめてみた

とりあえずブログというかたちで初めて見ました。
まずは自分の”工作ログ”のような形で使っていきたいと思います。