4年前たまたま書店で見つけた「よくわかる最新線量計の基本と作り方」という本に、ガイガーカウンターの自作方法が解説されていたので当時作ってみました。
ソビエト製のSBM-20というガイガーミュラー管を使っていて、カッコイイですよね。でも、歩数計を改造したカウンターでは使い勝手が悪かったので、どうにかできないかと思いつつ放置していたんです。
先日書いた「ESP8266とDHT11とBlynkでスマホとWebにリアルタイムで温度と湿度を表示する」で使ったBlynkがかなりいい感じだったので、4年越しでガイガーカウンターをBlynkに対応させて使い勝手を向上させることにしました。
スマホアプリのBlynkではこんな風に表示します。
単位のcpmはcounts per minuteのことで、ガイガーミュラー管が1分間に検出した放射線の回数を表します。上の図でもわかる通り、1分間ではかなり検出数にムラがでるので1時間平均も載せるようにしています。
ハードウェア
使ったもの
筆箱版で使用していた部品
(抵抗・コンデンサ・ヒューズクリップはブレッドボードへの転用ができない状態になっていたため、新しいものを使っています。)
- ガイガーミューラー管SBM-20
- 写ルンです改造高電圧発生ボード
- 抵抗 1/4W 5.1MΩ --- 千石電商(税込6円)
- フィルムコンデンサ 1000pF --- 千石電商(税込11円)
- 抵抗100kΩ --- 手持ち
- ヒューズクリップ標準サイズ 2個 --- 千石電商(税込22円)
乾電池置き換え用電源部品
- 電源用マイクロUSBコネクタDIP化キット --- 秋月電子(税込130円)
- LDOレギュレータ(出力1.5V)【BA15DD0T】 --- マルツ(税抜150円)
- 電解コンデンサ100µF --- 手持ち
- セラミックコンデンサ0.1µF --- 手持ち
改造歩数計カウンター置き換え用IoT化部品
- ESP-WROOM-02開発ボード --- 秋月電子(税込1,280円)
- トランジスタ2SC1815 --- 手持ち
- 抵抗10kΩ --- 手持ち
その他
- QIコネクタ用ピン オス 5本1組 --- 千石電商(税込63円)
- QIコネクタ(黒)1×1 2個 --- 千石電商(税込22円)
- 長いブレッドボード --- 手持ち
- ジャンパーワイヤー --- 手持ち
回路図
写ルンです改造高電圧発生ボードを表現できなかったため、実際とは少し違う回路図になっています。LDOレギュレータの出力1.5Vがボードへの入力となり、出力を400V電池として表現しました。
ブレッドボード版IoTガイガーカウンターでESP8266用とLDOレギュレーター用にそれぞれ電源を二つ取っているのには理由があります。
ESP8266のVCC(3.3V出力)をLDOレギュレーターの入力に使うためにVCCとグランドを繋ぐと、高電圧出力が得られなくなってしまうんです。テスターで計ったら1.5Vになっていました...。ガイガーミュラー管の検出信号をフォトカプラーを使ってESP8266に伝えることで、高電圧出力側とESP8266のグランドを分けて電源を1つにしようといろいろと頑張ったのですがうまく動作させることができませんでした。
グランドを分けるためにUSB電源を2つ取っているので、USB電源の取り先のグランドが繋がっていると高電圧を発生させることができません。同じPCのUSBから電源を取ってしまうとグランドが繋がってしまうので注意が必要です。
ソフトウェア
Blynk設定
少し改良して、1分間の検出数、1分間の検出数(1時間平均)、2つの検出数のグラフの他に、閾値を超えたときの通知を追加しました。
1分間の検出数と1分間の検出数(1時間平均)はValue Displayを使いました。
グラフはHistory Graphを、通知はNotificationを使いました。通知のタイミングや通知内容はArduinoのプログラムで制御します。
Arduinoプログラム
お待ちかね?のプログラムです。今回は結構シンプルになってます。
※2017/10/1更新 ヘッダーファイル名が全て小文字になっていました
/*
* Geiger Counter
* September 1, 2017
* By Hiroyuki ITO
* http://intellectualcuriosity.hatenablog.com/
* MIT Licensed.
*/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#define BLYNK_AUTH "YourAuthToken"
#define WIFI_SSID "YourWiFiSSID"
#define WIFI_PASSWORD "YourWiFiPassword"
#define SIGNAL_PIN 5
#define NOTIFY_LIMIT 100 // 100cpm
#define NOTIFY_TEXT "WARNINIG! The device detected more than 100cpm."
/*
* Global Variable
*/
volatile int min_count;
volatile int hour_count;
int before_hour_count;
int times;
BlynkTimer timer;
/*
* Interrupt Function
*/
void interrupted() {
min_count++;
hour_count++;
}
/*
* Send Data to Blynk
*/
void sendData() {
Blynk.virtualWrite(V5, min_count);
if (before_hour_count > 0) {
Blynk.virtualWrite(V6, before_hour_count / 60);
}
BLYNK_LOG("Minutes: %04d Hours: %04d", min_count, before_hour_count / 60);
// Push Notification
if (min_count > NOTIFY_LIMIT-1) {
Blynk.notify(NOTIFY_TEXT);
}
min_count = 0;
times++;
// 1 hour
if (times > 60) {
before_hour_count = hour_count;
hour_count = 0;
times = 1;
}
}
/*
* Setup
*/
void setup() {
Serial.begin(74880);
BLYNK_LOG2("Reset Reason: ", ESP.getResetReason());
pinMode(SIGNAL_PIN, INPUT);
attachInterrupt(SIGNAL_PIN, interrupted, FALLING);
Blynk.begin(BLYNK_AUTH, WIFI_SSID, WIFI_PASSWORD);
// Setup a function to be called every minute
timer.setInterval(60000L, sendData);
times = 1;
min_count = 0;
hour_count = 0;
before_hour_count = 0;
}
/*
* Loop
*/
void loop() {
Blynk.run();
timer.run();
}
今回の1番の目玉は、ガイガーミュラー管の検出パルスを割り込みを使ってカウントすることで、カウント漏れを防ぐようにしたところです。
attachInterrupt(SIGNAL_PIN, interrupted, FALLING);
が割り込み設定で、interrupted()
が割り込み処理関数です。割り込み処理関数で変更される変数にはvolite
を付けるようなので気を付けましょう。
サイドバーのGeiger counterのソース
Blynk HTTP RESTful APIを用いてサイドバーに機器のステータス、1分間の検出数、1時間平均の1分間の検出数を表示しています。
ガイガーカウンターのデータは1分毎に送るようにしているので、setInterval()の間隔も1分毎にしています。
しかし、そのままではページを表示してから1分経つまでの間データが表示されないため、ページ読み込み時にもデータを表示する関数を実行しています。
<div id="blynk_geiger_status">ステータス取得中...</div>
<div id="blynk_geiger_min">カウント取得中...</div>
<div id="blynk_geiger_hour">毎時平均カウント取得中...</div>
<script type="text/javascript">// <![CDATA[
// 読み込み時にデータを表示
window.onload = function() {
getDHT11byBlynk();
}
// 1分毎にデータを更新
setInterval(getDHT11byBlynk,60000);
function getDHT11byBlynk() {
var authToken = "YourAuthToken"; // Blynkの認証トークン
var minPin = "V5"; // カウント(分)仮想ピン
var hourPin = "V6"; // カウント(毎時平均)仮想ピン
// ステータス取得
var xhrStatus = new XMLHttpRequest();
xhrStatus.onreadystatechange = function() {
if (this.readyState == 4) {
var status = JSON.parse(this.responseText);
if (status) {
statusHTML = "<font color ='blue'>Online</font>";
} else {
statusHTML = "<font color ='red'>Offline</font>";
}
document.getElementById("blynk_geiger_status").innerHTML = statusHTML;
}
};
xhrStatus.open("GET", "http://blynk-cloud.com/" + authToken + "/isHardwareConnected", true);
xhrStatus.send();
// カウント(分)
var xhrTemp = new XMLHttpRequest();
xhrTemp.onreadystatechange = function() {
if (this.readyState == 4) {
var minCount = JSON.parse(this.responseText);
if (minCount > 99) {
var minColor = "<font color ='red'>";
} else {
var minColor = "<font color ='green'>";
}
document.getElementById("blynk_geiger_min").innerHTML = minColor + minCount + "cpm (minute)</font>";
}
};
xhrTemp.open("GET", "http://blynk-cloud.com/" + authToken + "/get/" + minPin, true);
xhrTemp.send();
// カウント(毎時平均)
var xhrHum = new XMLHttpRequest();
xhrHum.onreadystatechange = function() {
if (this.readyState == 4) {
var hourCount = JSON.parse(this.responseText);
if (hourCount > 29) {
var hourColor = "<font color ='red'>";
} else {
var hourColor = "<font color ='green'>";
}
document.getElementById("blynk_geiger_hour").innerHTML = hourColor + hourCount + "cpm (hour avg.)</font>";
}
};
xhrHum.open("GET", "http://blynk-cloud.com/" + authToken + "/get/" + hourPin, true);
xhrHum.send();
}
// ]]></script>
おわり