Created
August 12, 2016 14:31
-
-
Save izumogeiger/8c120c177ea1a56030c99c0c38d3fc0a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <TM1638.h> | |
// data,clk,stb | |
TM1638 tm1638(7, 8, 9); | |
/// デジタルIOのピンの設定 /// | |
int signPin = 2; //信号(黄) | |
int noisePin = 5; //ノイズ(白) | |
const double alpha=53.032; // cpm = uSv × alpha | |
unsigned int icount = 0; | |
int index=0; //ループを回った回数 | |
char msg[256]=""; //シリアルで出力する文字列用 | |
int signCount=0; //信号のカウント回数 | |
int noiseCount=0; //ノイズのカウント回数 | |
int sON=0;//信号検出時のロックフラグ | |
int nON=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]; | |
char uSvBuff[20]; | |
char uSvdBuff[20]; | |
void setup() | |
{ | |
Serial.begin(9600); | |
tm1638.setupDisplay(true, 7); | |
//信号検出ピンの設定 | |
pinMode(signPin,INPUT); | |
digitalWrite(signPin,HIGH); | |
//ノイズ検出ピンの設定 | |
pinMode(noisePin,INPUT); | |
digitalWrite(noisePin,HIGH); | |
//CSV形式でシリアルで出力するときの列の名前を列挙(_を,に読み替える) | |
//Serial.println("hour[h]_sec[s]_count_cpm_uSv/h_uSv/hError"); | |
//cpmの履歴を保存する配列の初期化 | |
for(int i=0; i<200;i++ ) | |
{ | |
cpmHistory[i]=0; | |
} | |
//ループ開始時間を取得 | |
prevTime = millis(); | |
} | |
void loop() | |
{ | |
unsigned long cpm2; | |
unsigned long cpm3; | |
// 信号のローデータ 通常:High 検出時:Low | |
int sign = digitalRead(signPin); | |
// ノイズのローデータ 通常:Low 検出時:High | |
int noise = digitalRead(noisePin); | |
//信号の検出(100us程度 Lowになる) | |
if(sign==0 && sON==0) | |
{//信号の検出開始、しばらく続くのでその間はカウントしないようにする | |
sON = 1; | |
signCount++; | |
} | |
else if(sign==1 && sON==1){ | |
//信号が終了したのでフラグを解除 | |
sON = 0; | |
} | |
//ノイズの検出(100us程度 Lowになる) | |
if(noise==1 && nON==0) | |
{//ノイズの検出開始、しばらく続くのでその間はカウントしないようにする | |
nON = 1; | |
noiseCount++; | |
} | |
else if(noise==0 && nON==1){ | |
//ノイズが終了したのでフラグを解除 | |
nON = 0; | |
} | |
//10000回ループを回ったら、計測値を計算して、シリアルで出力する | |
if(index==10000) //Arduino Nano(ATmega328)で160-170ms程度 | |
{ | |
//現在の時刻を取得 | |
currTime = millis(); | |
//ノイズが10000回のループの中でまったく検出されないとき | |
//ノイズが検出されたときは、処理をしない | |
if(noiseCount == 0) | |
{ | |
//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++; | |
} | |
} | |
//現在の計測時間(最大20分) | |
double min = cpmTimeSec / 60.0; | |
if(min!=0) | |
{ | |
//cpm、uSv/h、uSv/hの誤差をそれぞれ計算する | |
//sprintfに%lfがないので文字列変換 | |
dtostrf(cpm / min, -1, 3, cpmBuff); | |
dtostrf(cpm / min / alpha, -1, 3, uSvBuff); | |
dtostrf(sqrt(cpm) / min / alpha, -1, 3, uSvdBuff); | |
cpm2 = (unsigned long)(cpm/min * 100); | |
cpm3 = ((unsigned long)(cpm/min)) % 256; | |
} | |
else{ | |
//0割り算のときは、0にする | |
dtostrf(0, -1, 3, cpmBuff); | |
dtostrf(0, -1, 3, uSvBuff); | |
dtostrf(0, -1, 3, uSvdBuff); | |
cpm2 = 0; | |
cpm3 = 0; | |
} | |
//シリアルで送信する文字列の生成 | |
sprintf(msg, "%d,%d.%03d,%d,%s,%s,%s", | |
totalHour,totalSec, | |
cpmTimeMSec, | |
signCount, | |
cpmBuff, | |
uSvBuff, | |
uSvdBuff | |
); | |
//シリアルで送信 | |
Serial.println(msg); | |
if (icount % 10 == 9) { | |
tm1638.setDisplayToDecNumber(cpm2,1<<2); | |
tm1638.setLEDs(cpm3); | |
} | |
} | |
//次の10000回のループのための変数の初期化 | |
prevTime = currTime; | |
signCount=0; | |
noiseCount=0; | |
index=0; | |
icount++; | |
} | |
index++; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment