RaspberryPi
PM2.5 花粉観測のためのセンサ 作成
 空気清浄機や煙式火災報知器につかわれているレーザ光がホコリで散乱する原理のホコリセンサーを用いPM2.5 花粉観測のためのセンサを作ります。米国ではアマチュアがホコリセンサーによる計測器を開発し、空気の質(Air quality)を計測し公開するフォーラムが立ち上がっており、スマホで閲覧できる都市が増えているようです。これらを参考にしながらトライすることとしました。

 使われているセンサーは、日本製で、メーカに問い合わせたところ、単体で1万円以上、評価キットが10万円以上とのことでした。同じものが中国のサイト(中国シンセン)で$15.9で売られており、さらにその日本サイトでは2000円弱で入手可能でした。

 ほこりセンサは特殊なインターフェースですので、このままではPCにつながりません。シングルボードコンピュータRaspberryPiでi一次処理を行い標準的なファイルにしてPCに渡すこととします。 入手したセンサーは下記の通りです。

型番 :SEN12291P
販売サイト:Seeed Technology Inc. 日本サイト:FabxFab
メーカ: 神栄テクノロジー株式会社
メーカ型番: PPD 42NJ
規格表:こちら

 このセンサーを分解し内部を解析した方がおられます(いわゆるリバースエンジニアリング)。その資料が公開されていましたので、一部使わせていただきます。
下の白い抵抗はヒータ ここで空気が暖められ、上昇する
左側は発光ダイオード、この光が空気中のホコリで反射し、右の受信ダイオードで検出される
発光ダイオードの光は、実際は見えないが、赤色ダイオードに取り替えて実験したところ。レンズで集光され、ここを通過する空気を観測する

検出された微粒子の大きさに応じた、パルスが出力されます。PWM(パルス幅変調)という方式で、これを30秒間以上LOレベルのしめる時間比(デューティサイクル)を求めます。それを下のグラフに従って、単位体積あたりの微粒子の個数に変換します。 (規格表による)



ここで、このグラフを数式に表した方がおられ、それによると、次の通りです。


 この式で x はデューティサイクルを%であらわしたもの、 y は0.01立方フィートあたりの粒子の個数ですので、分かりやすい単位に換算が必要です。

 このセンサーの入出力コネクタは5端子でその配置は次の通りです。すなわち出力はP1(端子4)とP2(端子2)の2系統あり、小さな微粒子と大きな微粒子の2種類を計測できます。その際P1は1ミクロン以上で固定ですが、P2はT1(端子5)に抵抗をつなぐことにより、計測の粒子サイズを変更することが出来ます。デフォルトは「2.5ミクロン以上」です。
1 : COMMON(GND)
2 : OUTPUT(P2)
3 : INPUT(5VDC 90mA)
4 : OUTPUT(P1)
5 : INPUT(T1)・・・FOR THRESHOLD FOR [P2]

端子の物理規格:JST EHシリーズ EHR-5
ハードの作成
必要な部品(RaspberryPi本体をのぞく)
ホコリセンサー 上述
12V40mm角 DCファン 秋月電子 150円 これを5Vでゆっくり回す
5V 2A 電源 旧パソコンから取り外したもの
ケース 旧モデムのケース再利用
LANケーブル USBケーブル 手持ち
抵抗 2.4K 3.9K それぞれ2個
ユニバーサル基板 サンハヤト
26Pピンソケット 秋月電子 50円
接続用JSTコネクタ マルツパーツ館


 GPIOにホコリセンサーをつなぎ込みます。GPIO 番号の呼び方はいろいろな経緯で複数あるようです。ここではBCM Rev2の規格で記述していきます。

 http://wiringpi.com/wp-content/uploads/2013/03/gpio1.png

 ホコリセンサの必要な電源は5Vプラスマイナス10%で、この範囲の電源を用意しなければ精度は保証されません。Raspberry PiのGPIO HEADERには5Vの電源が取り出せるピンがありますが、実測するとこの範囲に収まりません。またRaspberry Piはあたらしいデバイスを使っているため、基本入出力電圧が3.3Vで、上記ホコリセンサーのPWMパルスを直接接続はできず、電圧を3/5に変換する必要があります。そのため抵抗で分圧します。下のような簡単な接続基板を作成しました。これをRaspberryPiのGPIO HEADERに直接マウントし、ほかの基板、FANなどとコネクタ接続します。、

部品面から見ているので、上の回路図とは反転 PaspberryPiのGPIO HEADERにマウントしたところ


適当なケースに格納 右下は電源
空気の流れを考慮し小さいファンを使用
ファンの下の小さな四角い窓はホコリセンサーの
空気取り入れ口
軒下に設置 ルータを経由してWindowsマシンに接続
隣は1Wire温度センサ




Raspberry Piのほこりセンサソフトの作成

 Raspberry Piで動くセンサ用のソフトを作ります。Raspberry Piはもともと教育用のため、Pythonという、あたらしい汎用のスクリプト言語が基本となっています。ホコリセンサーは、幅が10msから90msのパルスの幅を精度良く読み取らなければなりません。そのためにGPIOをHIかLOかをくりかえし読みに行く必要があります。このような仕事はリアルタイムのマイコンが得意で、本来UNIXのような多重プログラミングの機械は不得意です。それをあえてやろうというわけですから、コンパイルした実行形式のプログラムで、すこしでも高速に読み取りたいのです。そのためC言語で記述します。RaspberryPiはLinuxマシンですから、当然C言語がつかえます。GPIOを読みに行くプログラムをPythonとCで記述し速度を比較すると、70倍の差がありました。
 裏側で動くソフトは極力減らし、余計なことはWindowsの親機にまかせ、簡潔なソフトにします。読み取り頻度は0.1m秒としました。

GPIOのwiringPiライブラリをインストール
GPIOをC言語から使えるようにするライブラリWieringPiインストールする

バージョン管理システムGitのインストール
$ sudo apt-get install git-core

WiringPiのソースファイルをダウンロード
$ git clone git://git.drogon.net/wiringPi

プログラムのコンパイル
$ cd wiringPi
$ ./build


インストールされたバージョンを確認します。
$ gpio -v

Raspberry Piで動かす、ホコリセンサーのよみとりプログラム
(1)  GPIOのwiringPiライブラリをinclude
(2)  よくつかうGPIO番号をdefineしておく
(3) wiringPiをBCM規格でイニシャライズ(重要) GPIOヘッダのPin11とPin15がBCM規格の番号で読めるようになる
(4) GPIO17とGPIO22を読み取りモードにセット
(5) 無限ループ
(6) GPIO17とGPIO22を読む
(7) パルスがLOレベルの場合カウンタを1あげる
(8) これを0.1msごとに繰り返し約1分続ける
(9) 1分ごとに、ファイルにデューティー比を出力する。dustsensorディレクトリの中にdustsensor.txtというCSV形式のファイルができる。
時刻,小さい粒子,大きい粒子
たとえば
2014/05/18 11:18:03,0.005348,0.000245

 ホコリセンサー  dustsensor.c
/* ホコリセンサー
* 2014/05/08 (C) H.Ishikawa
*/
#include <wiringPi.h> //(1)
#include <time.h>
#include <stdio.h>

#define GPIO17 17 //1micro small_particle //(2)
#define GPIO22 22 //2.5micro large_particle //(2)

int main (void)
{
    time_t timer;
    struct tm *date;
    char date_time[256];
	FILE *fp;
	char *fname = "dustsensor/dustsensor.txt";
	   	
	if (wiringPiSetupGpio() == -1) return 1 ;//BCM GPIO pin numbers  //(3)
	pinMode(GPIO17, INPUT) ; //(4)
	pinMode(GPIO22, INPUT) ; //(4)
	
	long count_small_particle,count_large_particle,total;
	int small_particle,large_particle;
	float lowpulse_small_particle = 0.0;
	float lowpulse_large_particle = 0.0;
	timer = time(NULL);          
	strftime(date_time, 255, "%Y/%m/%d %H:%M:%S", localtime(&timer));   
	
	printf("measurement start %s\n",date_time);
	while (1){//(5)
		count_small_particle = 0;
		count_large_particle = 0;
		total = 0;
		fp = fopen( fname, "a" ); //追記形
		while (total < 331000) {  //(8)
			total = total + 1;
			small_particle = digitalRead (GPIO17); //(6)
			if (small_particle == 0){   //(7)
				count_small_particle = count_small_particle + 1;
			}
			large_particle = digitalRead (GPIO22); //(6)
			if (large_particle == 0){   //(7)
				count_large_particle = count_large_particle + 1;
			}
			delayMicroseconds(100);//(8) 0.1ms
		}
		

		timer = time(NULL);          
		strftime(date_time, 255, "%Y/%m/%d %H:%M:%S", localtime(&timer)); 
		lowpulse_small_particle = (float)count_small_particle / (float)total;
		lowpulse_large_particle = (float)count_large_particle / (float)total;
		fprintf( fp, "%s,%f,%f \n", date_time,lowpulse_small_particle,lowpulse_large_particle); //(9)
		printf("%s,%f,%f \n",date_time,lowpulse_small_particle,lowpulse_large_particle);
		fclose( fp );
	}
	return 0;
}

このプログラムを、Raspberry Pi上にdustsensor.cというなまえで保存し、コンパイルします。たとえば
$ gcc dustsensor.c -o dustsensor.exe -lwiringPi

実行は
$ sudo ./dustsensor.exe

dustsensorディレクトリの中にdustsensor.txtというCSV形式のファイルができる。
[時刻,小さい粒子,大きい粒子]の形式
たとえば
2014/05/18 11:18:03,0.005348,0.000245
1分ごとに書き込まれる。

Windows本体側のほこりセンサ用プログラム

Windows本体側では、次のような処理をおこなっています。
(1) 1時間に一度、Raspberry PiのCSV形式ファイルを読み、上に述べた変換式により、単位体積あたりの粒子数に変換する
(2) 10分間の移動平均を求める
(3) GNUPLOTでグラフを描画する
(4) FTPでホームページにグラフをアップロードする
ここらは一般的な方法ですので、ここでは省略します。