sea side she side

写真と山、資格が好きなアラフォーエンジニアのブログ

簡易ガイガーカウンター(SBM-20) w/ RTC

   

時計のときもそうでしたが、内部クロック使って秒数カウントするとどうしてもずれが発生します。こんなときこそRTCモジュールの出番です。

使用するRTCは秋月のリアルタイムクロックモジュール(RTC-8564NB)。

ライブラリはarms22さんのRTC8564ライブラリとそれをRTCの割込用信号を利用できるよう拡張したen_daisukeさんのRtc8564AttachInterruptライブラリを利用させていただきます。

また1分間の計測値をそのままcpmとするとぶれが大きすぎるため、5分間の移動平均とすることにしました。

/* 簡易ガイガーカウンター
   Arduino SBM-20 RTC8564
   5分間の移動平均
 */

#include <Wire.h>
#include <Rtc8564AttachInterrupt.h>


// RTCタイマ開始日時設定
#define RTC_SEC  0x00  // 秒
#define RTC_MIN  0x43  // 分
#define RTC_HOUR 0x22  // 時
#define RTC_DAY  0x07  // 日
#define RTC_WEEK 0x03  // 曜日(00:日 〜 06:土)
#define RTC_MON  0x06  // 月
#define RTC_YEAR 0x11  // 西暦

byte date_time[7] = {
    RTC_SEC
    ,RTC_MIN
    ,RTC_HOUR
    ,RTC_DAY
    ,RTC_WEEK
    ,RTC_MON
    ,RTC_YEAR
};

// 電源リセット確認フラグ
boolean init_flg = false;
// 計測間隔(RTC割込間隔)
#define RTC_INTERRUPT_TERM 1
// 定周期タイマ間隔設定単位 0:秒 1:分
#define RTC_INTERRUPT_MODE 0

// 外部割込ピン
#define RTC_INTERRUPT_PIN 2
#define GMC_INTERRUPT_PIN 3

int time = 0;
int allcount = 0;
int cps_now = 0;        // cpsリアルタイム値
int cps[60] = {0};      // 各秒ごとのcps値
int cpm = 0;            // Counts per Minute
int cpmtmp[5] = {0};    // 5分移動平均
int cpmsum = 0;
float cpmav = 0;
int i = 0;


/*----------------------------------------------
 * 関数: setup
 * 概要: 事前処理
 * 引数:
 * 戻値:
 * ---------------------------------------------*/
void setup(void) {
    Serial.begin(9600);
    Serial.println("Geiger Counter Board - Arduino");
    Serial.println("sea side she side");
    Serial.println("https://www.a10i.jp/");
    Serial.println("");
    Serial.println(""); 
 
    Rtc.initDatetime(date_time);

    // 日付時刻初期化
    Rtc.beginWithoutIsValid();

    Rtc.begin();
    
    if (!Rtc.isInterrupt()) {
        Rtc.syncInterrupt(RTC_INTERRUPT_MODE, RTC_INTERRUPT_TERM);
    }
    
    pinMode(RTC_INTERRUPT_PIN, INPUT);
    digitalWrite(RTC_INTERRUPT_PIN, HIGH);
    attachInterrupt(0, secInterrupt, FALLING);
    
    pinMode(GMC_INTERRUPT_PIN, INPUT);
    //digitalWrite(GMC_INTERRUPT_PIN, HIGH);
    attachInterrupt(1, gmCount, FALLING);
 }

/*----------------------------------------------
 * 関数: loop
 * 概要: メイン処理
 * 引数:
 * 戻値:
 * ---------------------------------------------*/
void loop(void) {
}

/*----------------------------------------------
 * 関数: gmCount
 * 概要: ガイガーカウンターカウントアップ
 * 引数:
 * 戻値:
 * ---------------------------------------------*/
void gmCount(void) {
    allcount++;
    cps_now++;
}

/*----------------------------------------------
 * 関数: secInterrupt
 * 概要: 毎秒処理
 * 引数:
 * 戻値:
 * ---------------------------------------------*/
void secInterrupt(void) {
    culcCpm();
    time++;
    if(time > 59) {
        time = 0;
        culcAvCpm();
    }
}


/*----------------------------------------------
 * 関数: culcCpm
 * 概要: 毎秒処理
 * 引数:
 * 戻値:
 * ---------------------------------------------*/
void culcCpm(void) {
    // 60秒前のcpsの値を引いて、現在のcpsを足す
    cpm -= cps[time];
    cps[time] = cps_now;
    cpm += cps[time];
    cps_now = 0;
    
    Serial.print("----- ");
    Serial.print(time);
    Serial.println(" -----");
    Serial.print(allcount);
    Serial.println("times");
    Serial.print(cpm);
    Serial.println("cpm");
    for(int j=0; j<60; j++) {
        Serial.print(cps[j]);
        Serial.print(" ");
    }
    Serial.println("");
    for(int k=0; k<time; k++) {
        Serial.print("  ");
    }
    Serial.println("~");
}


/*----------------------------------------------
 * 関数: culcAvCpm
 * 概要: 5分移動平均
 * 引数:
 * 戻値:
 * ---------------------------------------------*/
void culcAvCpm(void) {
    cpmsum -= cpmtmp[i];
    cpmtmp[i] = cpm;
    cpmsum += cpmtmp[i];
    cpmav = cpmsum / 5;
    
    Serial.println("===== cpm av. =====");
    Serial.print(cpmtmp[0]);
    Serial.print(" ");
    Serial.print(cpmtmp[1]);
    Serial.print(" ");
    Serial.print(cpmtmp[2]);
    Serial.print(" ");
    Serial.print(cpmtmp[3]);
    Serial.print(" ");
    Serial.print(cpmtmp[4]);
    Serial.println("");
    Serial.print("cpm av. ");
    Serial.println(cpmav);
    Serial.println("");

    i++;
    if(i > 4) {
        i = 0;
    }
}

デバッグ部分も含めているため少し冗長気味なスケッチです。

----- 59 -----
114times
23cpm
1 0 2 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 2 0 0 1 0 0 0 0 0 0 0 0 1 1 2 1 0 1 1 0 0 0 1 1 1 0 3 0 0 0 0 0 0 1 0 0 0 0
~
===== cpm av. =====
15 30 24 22 23
cpm av. 22.00

----- 0 -----
114times
22cpm
0 0 2 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 2 0 0 1 0 0 0 0 0 0 0 0 1 1 2 1 0 1 1 0 0 0 1 1 1 0 3 0 0 0 0 0 0 1 0 0 0 0
~

こんな感じで表示されます。

 - Make , , , , ,