Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
GeigerCounter Sensor gc10 + esp8266
#include <ESP8266WiFi.h>
#define USE_WIFI 1
const char* ssid = "wifi_ssid";
const char* password = "password";
const char* host = "192.168.1.xxx";
const int port = 8000;
/// デジタルIOのピンの設定 ///
int signPin = 16; //信号(黄)
const double alpha = 53.032; // cpm = uSv × alpha
int num = 0; //ループを回った回数
char msg[256] = ""; //シリアルで出力する文字列用
int signCount = 0; //信号のカウント回数
int sON = 0; //信号検出時のロックフラグ
double cpm = 0; //現在のカウント数
double cpmHistory[200]; //カウント回数の履歴
int cpmIndex = 0; //カウント回数の現在配列の格納位置
int cpmIndexPrev = 0; //二重カウントの防止用
//ループの時間間隔の計測用
int prevTime = 0;
int currTime = 0;
int totalSec = 0; //計測開始からのトータルの時間(秒)
int totalHour = 0; //計測開始からのトータルの時間(時間)
//cpm計算用の時間
int cpmTimeMSec = 0;
int cpmTimeSec = 0;
int cpmTimeMin = 0;
//シリアルで出力するときの浮動少数を文字列に変換用
char cpmBuff[20];
int reportSec = 0;
void setup()
{
int i;
Serial.begin(115200);
#ifdef USE_WIFI
delay(10);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
i = 0;
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
if (i > 10) {
Serial.println("wifi timeout");
break;
}
i++;
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
#endif
//信号検出ピンの設定
pinMode(signPin, INPUT);
digitalWrite(signPin, 1);
//cpmの履歴を保存する配列の初期化
for (int i = 0; i < 200; i++ )
{
cpmHistory[i] = 0;
}
//ループ開始時間を取得
prevTime = millis();
}
void report(char *cpm)
{
#ifdef USE_WIFI
WiFiClient client;
if (!client.connect(host, port)) {
return;
}
String path = "/gc10?cpm=";
path += cpm;
client.print(String("GET ") + path + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
unsigned int timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 1000) {
Serial.println("wifi error");
break;
}
}
client.stop();
#endif
}
void loop()
{
// 信号のローデータ 通常:High 検出時:Low
int sign = digitalRead(signPin);
//信号の検出(100us程度 Lowになる)
if (sign == 0 && sON == 0)
{ //信号の検出開始、しばらく続くのでその間はカウントしないようにする
sON = 1;
signCount++;
Serial.println("signal");
}
else if (sign == 1 && sON == 1) {
//信号が終了したのでフラグを解除
sON = 0;
}
//10000回ループを回ったら、計測値を計算して、シリアルで出力する
if (num >= 10000) //Arduino Nano(ATmega328)で160-170ms程度
{
//現在の時刻を取得
currTime = millis();
//6秒ごとにカウント回数の履歴を格納する配列をずらす
if ( totalSec % 6 == 0 && cpmIndexPrev != totalSec)
{
cpmIndexPrev = totalSec;
cpmIndex++;
//最後まできたら元に戻す
if (cpmIndex >= 200)
{
cpmIndex = 0;
}
//一周してきたときに次に格納する配列に値が詰まっていれば、
//現在の合計しているカウント(変数cpm)から引いて、無かったことにする
if (cpmHistory[cpmIndex] > 0)
{
cpm -= cpmHistory[cpmIndex];
}
cpmHistory[cpmIndex] = 0;
}
//カウント回数の履歴を保存
cpmHistory[cpmIndex] += signCount;
//カウント回数の蓄積
cpm += signCount;
//10000回、データを取得するのにかかった時間を取得
cpmTimeMSec += abs(currTime - prevTime);
//ms→secに変換する(オーバーフロー対策)
if (cpmTimeMSec >= 1000)
{
cpmTimeMSec -= 1000;
//cpmを求めるときに使用する計測時間(最大20分)を加算
if ( cpmTimeSec >= 20 * 60 )
{
cpmTimeSec = 20 * 60;
}
else {
cpmTimeSec++;
}
//トータルでの計測時間
totalSec++;
//sec→hourに変換する(オーバーフロー対策)
if (totalSec >= 3600)
{
totalSec -= 3600;
totalHour++;
}
// 65秒ごとにHTTP GETでサーバに投げる
reportSec++;
if (reportSec > 65) {
report(cpmBuff);
reportSec = 0;
}
//現在の計測時間(最大20分)
double min = cpmTimeSec / 60.0;
if (min != 0)
{
//cpm、uSv/h、uSv/hの誤差をそれぞれ計算する
//sprintfに%lfがないので文字列変換
dtostrf(cpm / min, -1, 3, cpmBuff);
}
else {
//0割り算のときは、0にする
dtostrf(0, -1, 3, cpmBuff);
}
//シリアルで送信する文字列の生成
sprintf(msg, "%d,%d.%03d,%d,%s",
totalHour, totalSec,
cpmTimeMSec,
signCount,
cpmBuff
);
//シリアルで送信
Serial.println(msg);
}
//次の10000回のループのための変数の初期化
prevTime = currTime;
signCount = 0;
num = 0;
}
num++;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment