2011年04月03日

超小型ガイガーカウンタ by PIC12F1822

ガイガーカウンタ by PIC 12F1822
(写真はイメージです。そのままでは動作しない場合もあります。)

ガイガー・ミュラー管が運良く入手できたので超小型ガイガーカウンタを試作してみました。

使用したガイガー・ミュラー管(GM管)は、秋月電子で保安在庫品販売で入手した浜松ホトニクス製の D3372 です。

浜松ホトニクス製の D3372

浜松ホトニクス製の D3372

【回路図】

回路は下記サイトを参考に設計してみました。

 ・ガイガーカウンタの部屋
 ・使い捨てカメラ「写ルンです」の分解
 ・秋月電子「γ/β検出・ポケットガイガーカウンタキット」取説

ガイガーカウンタ回路図 by 12F1822
写真ではコイン電池を使用していますが、電圧が十分でないかも知れません。
動作確認は 3.3Vのスイッチング電源を使用しました。


「写ルンです」から流用した部品
 ・トランス
 ・2次側ダイオード、コンデンサ(223)
 ・1次側スイッチングトランジスタ


【高圧発生回路】


高圧発生に使用したトランスは、参考サイトを元に、「写ルンです」の回路部品を流用しました。
データシートからGM管のプラトー電圧の目標値は650~700Vとしました。
小型化のため電源電圧は3Vのリチウムボタン電池を使用します。
「写ルンです」に使用されているトランスは、参考資料から約1:350 の巻き線比のため、1次側に電圧調整回路を入れて、2次側で700V程度 になるようにしました。

写ルンです

電解コンデンサ(一番大きい部品)には電気が溜まっています。
危険ですので分解には注意が必要です。


写ルンです・電気回路

分析の結果、「写ルンです」のトランスの配線は下記の通りです。

写ルンです・トランス

2次の高圧測定には下記が使えるかもしれません。 次回注文してみたいと思います。
 ・高圧オシロスコープ・プローブ 100:1(250MHz)

また、高圧発生回路は下記基板が使えるかも知れません。値段も350円と手頃です。
 ・aitendo DC-ACインバータ[INV-EF002]


【使用した制御用マイコン】


今回試作した回路では制御に PIC 12F1822マイコンを使用しました。
 ・マイクロチップ 12F1822の参考サイト

このPIC 12F1822は比較的新しく、A/Dコンバータ、USART、EEPROMなどを実装して、価格が80円(秋月電子にて)というコストパフォーマンスが高いマイコンです。

今回は、主にEEPROM機能しか使っていませんが、価格が安いことや、使用方法になれるという点で採用しました。

PIC 12F1822用のCコンパイラは、マイクロチップ社の下記サイトからダウンロード可能です。
Hi-Tech社製で無償版がリリースされています。(Liteモードでインストール)
 ・HI-TECH C for the PIC10/12/16 MCU Family

書き込みは、秋月電子製のライターは未対応のようですので、ICD3経由でデバッグ、書き込みできるボードを作りました。

超小型ガイガーカウンタ by PIC12F1822



【ソフトウエア概略仕様】


モード切換え
 ・未定(未使用)


通常動作
 ・更新時間 10秒
 ・放射線検出時 → LED Red点灯 / ブザー x 1回

 ・放射線検出が定常状態 → LED Green 5secおきに点灯
 ・放射線検出がやや多い → LED Green 3secおきに点灯
 ・放射線検出が多い   → LED Green 1secおきに点灯




【ソースコード】


【main.c】

//───────────────────────────────────
//  Includeの定義
//───────────────────────────────────
#include <pic.h>
#include "port.h"
#include "timer.h"
#include "trigger.h"
#include "led.h"

//───────────────────────────────────
//  Define User Memory
//───────────────────────────────────
static unsigned char Timer100ms;
static unsigned char Timer10ms;
static unsigned char Flag10ms;
static unsigned char Flag1ms;

static unsigned char FlagDet = 0;
static unsigned char TimerDet = 0;
static unsigned int CountDet = 0;
static unsigned char TimerBuzz = 0;

//───────────────────────────────────
// Here be interrupt function
// - the name is unimportant.
//───────────────────────────────────
static void interrupt isr(void) 
{
    if( RA1 == 0 )
    {
        FlagDet = 1;        // 放射能検出
    }
    INTF = 0;               // clear the interrupt

    if(T0IF)                // timer interrupt
    {
        Flag1ms = 1;
        if( Timer10ms != 0 )
        {
            Timer10ms --;
        }
        else
        {
            Flag10ms = 1;
            Timer10ms = 9;
        }
        T0IF = 0;           // clear the interrupt flag
    }
}


//───────────────────────────────────
// Main
//───────────────────────────────────
void main(void)
{
    init_port();
    init_trigger();
    init_led();
    init_timer0();
    GIE = 1;            // Enable interrupts
    
    TimerBuzz = 50;

    for(;;){
        // 1msec 処理
        if( Flag1ms )
        {
            Flag1ms = 0;
            trigger_main();
            led_timer_1ms();
            led_main();
        }

        // 10msec 処理
        if( Flag10ms )
        {
            Flag10ms = 0;
            Timer100ms ++;

            if( TimerBuzz == 0 )
            {
                PortBuzzOff;
                PortRedOff;
            }
            else
            {
                PortBuzzOn;
                PortRedOn;
                TimerBuzz --;
            }
            
            if( FlagDet == 1)   // 放射能検出
            {
                FlagDet = 0;
                if( TimerBuzz == 0 )
                {
                    TimerBuzz = 5;
                }
                if( CountDet < 50000 )
                {
                    CountDet ++;
                }
                else
                {
                    led_set_mode(LED_MODE_HIGH);
                }
            }
        }

        // 100msec 処理
        if( Timer100ms >= 10 )
        {
            Timer100ms = 0;
            
            // 10secおきに更新
            TimerDet ++;
            if( TimerDet > 10 )
            {
                if( CountDet > 10 )
                {
                    led_set_mode(LED_MODE_HIGH);
                }
                else
                {
                    if( CountDet > 1 )
                    {
                        led_set_mode(LED_MODE_MIDDLE);
                    }
                    else
                    {
                        led_set_mode(LED_MODE_NORMAL);
                    }   
                }
                CountDet = 0;
                TimerDet = 0;   
            }   
        }
    }
}



【port.c】

#include <pic.h>
#include "port.h"

void init_port(void)
{
    WPUA = 0b00001000;      // Pullup   
    TRISA = 0b00001010;     // 1:入力、0:出力設定
    ANSELA = 0b00000000;    // A/D 禁止
    PORTA = 0b00110001;

    OPTION_REG &= 0b01111111;// Pullup許可
    CLKOUT = 1;         // CLKOUT function is disabled
    
    INTE = 1;
    IOCAN1 = 1;         // INTERRUPT-ON-CHANGE PORTA NEGATIVE EDGE REGISTER
}


【trigger.c】

#include <pic.h>
#include "port.h"
#include "trigger.h"

static char TrgInterval = 0;

//───────────────────────────────────
// initialize trigger
//───────────────────────────────────
void init_trigger(void)
{
    PortTrigOff;
}

//───────────────────────────────────
// Trigger main (2msec)
//───────────────────────────────────
void trigger_main(void)
{
    TrgInterval ++;
    if( TrgInterval >= 40 ) // 40msec (25Hz)
    {
        PortTrigOn;
        TrgInterval = 0;
        PortTrigOff;
    }
}


【led.c】

#include <pic.h>
#include "led.h"
#include "port.h"

static LED_MODE mode = LED_MODE_NORMAL;
static long TimerGreen = 3000;
static char FlagGreen = 0;
 
//───────────────────────────────────
// initialize LED
//───────────────────────────────────
void init_led(void)
{
    PortGrnOff;
    PortRedOff;
}

//───────────────────────────────────
// Set mode
//───────────────────────────────────
void led_set_mode(LED_MODE value)
{
    mode = value;

    FlagGreen = 1;
    TimerGreen = 20;
    PortGrnOn;
}

//───────────────────────────────────
// LED 1msec Timer
//───────────────────────────────────
void led_timer_1ms(void)
{
    if( TimerGreen > 0 )
    {
        TimerGreen --;
    }   
}
    
//───────────────────────────────────
// LED main
//───────────────────────────────────
void led_main(void)
{
    if( TimerGreen == 0 )
    {
        if( FlagGreen == 0 )
        {
            FlagGreen = 1;
            TimerGreen = 20;
            PortGrnOn;
        }
        else
        {
            FlagGreen = 0;
            PortGrnOff;

            switch( mode )
            {
            case LED_MODE_NORMAL:
                TimerGreen = 5000;
                break;
                
            case LED_MODE_MIDDLE:
                TimerGreen = 3000;
                break;
                
            case LED_MODE_HIGH:
                TimerGreen = 1000;
            }
        }   
    }
}


【timer.c】

#include <pic.h>
#include "timer.h"

//───────────────────────────────────
// initialize timer 0 (1msec)
//───────────────────────────────────
void init_timer0(void)
{
    OSCCON = 0b01100010; // PLL Disable / 2MHz Internal clock
    PS2 = 0;            // Clk 1/2
    PS1 = 0;
    PS0 = 0;
    PSA = 0;
    
    TMR0CS = 0;         // select internal clock
    TMR0IE = 1;         // enable timer interrupt
}


【port.h】

#ifndef _PORT_H_
#define _PORT_H_

/**********************************************
    マクロ定義
**********************************************/
#define PortBuzzOn  RA0 = 0
#define PortBuzzOff RA0 = 1

#define PortTrigOn  RA2 = 1
#define PortTrigOff RA2 = 0

#define PortRedOn   RA5 = 0
#define PortRedOff  RA5 = 1

#define PortGrnOn   RA4 = 0
#define PortGrnOff  RA4 = 1

/**********************************************
    外部参照関数
**********************************************/
void init_port(void);

#endif


【led.h】

#ifndef _LED_H_
#define _LED_H_

/**********************************************
    定数/型定義
**********************************************/
typedef enum
{
    LED_MODE_NORMAL,        // 定常状態
    LED_MODE_MIDDLE,        // 中くらい
    LED_MODE_HIGH           // 高い
} LED_MODE;

/**********************************************
    外部参照関数
**********************************************/
void init_led(void);
void led_timer_1ms(void);
void led_main(void);
void led_set_mode(LED_MODE value);

#endif


【timer.h】

#ifndef _TIMER_H_
#define _TIMER_H_

/**********************************************
    外部参照関数
**********************************************/
void init_timer0(void);

#endif


【trigger.h】

#ifndef _TRIGGER_H_
#define _TRIGGER_H_

/**********************************************
    外部参照関数
**********************************************/
void init_trigger(void);
void trigger_main(void);

#endif







【ビルド時の注意点】


MPLABでビルドする際には、「Configuration bits」 ダイアログ(下記)で
CLKIN を I/O に設定しないと RA4 端子が I/O として使用できません。

超小型ガイガーカウンタ by PIC12F1822

また、MCLR端子を I/O として使用する場合は MLRE の設定と共に
下記のように LVP を禁止に設定しておく必要があります。

超小型ガイガーカウンタ by PIC12F1822

この説明は、ユーザーズマニュアル(50ページ)にも記載されています。

MCLRE: RA3/MCLR/VPP Pin Function Select bit
 If LVP bit = 1:
  This bit is ignored.
 If LVP bit = 0:
  1 = MCLR/VPP pin function is MCLR; Weak pull-up enabled.
  0 = MCLR/VPP pin function is digital input




【HEXコード】


下記URLよりダウンロード可能です。

http://hmmk.co.jp/sample/GM_Counter.hex



【動作検証】


1分間に1回程度検出しているようですが、正常に動作しているか不明です。
回路およびプログラム変更で、1分間に5回程度検出しています。

下記動画は放射能レンズを近づけた実験です。




【その他】


たまたま見かけた「Software Design (ソフトウェア デザイン) 2011年 07月号」にArduinoで作るガイガーカウンタの記事が載っていました。
5ページにわたってわかりやすく書かれていましたし、回路図も載っていました。




同じカテゴリー(マイコン開発)の記事
Fusion PCBでエレキー
Fusion PCBでエレキー(2020-04-01 19:00)


この記事へのコメント
ホント、いつも感心します。
こんなの作るなんて。
実機見てみたいです。

ところで、校正する標本とか試料は手に入るのですか?
Posted by お店番 at 2011年04月04日 14:46
校正はできませんが、動作確認できる「放射能レンズ」を借りることができそうです。

確認の様子をYouTubeにアップ予定です。
Posted by 宇都宮 at 2011年04月04日 15:09
>>回路およびプログラム変更で、1分間に5回程度検出しています。

私も同じ計数管を持っていますが、やはり1分間に1回程度しか検知しません
具体的にどのようにしたのか、教えていただけませんか?
Posted by 通りすがりのエンジニア at 2011年04月27日 20:03
引越しで回答する時間がなかなか取れませんでした。

検出頻度の問題ですが、下記の2つが考えられます。
 ・2次側の高圧が充分でない。
 ・カソードのパルス電流をうまく拾えていない。

2次側の高圧が充分でない原因としては、回路として問題なければスイッチングのパルス幅が短すぎが挙げられます。
回路定数にもよりますが、ある程度(10usec~)TrをOnしないと完全にスイッチングしません。
1次側の波形はオシロで観測できるので確認してみてはいかがでしょう。

また、試作当初の回路では、GM管のカソード側のTr出力パルスの幅がマイコンの割込とチャタリング処理に対して充分な幅でなかったのでCRの時定数を変更してパルス幅を広げました。
Posted by 宇都宮 at 2011年04月28日 14:25
的確なアドバイスありがとうございます。
オシロを持ってないので、ちょっと時間がかかりますがチェックしてみます。
ありがとうございました。
Posted by 通りすがりのエンジニア at 2011年04月28日 22:00
ソースコードの公開感謝します  ただミューラー管がお手軽ではなさそうで
工作は 機会を見て作りたいです。
一点 ソースコードの誤植についてご報告いたします。lec と led の記述が整合していないので 整合したら上手く変換完了しました。
Posted by たつみ at 2011年08月28日 09:44
たつみさん

ご指摘ありがとうございます。
修正しておきました。
Posted by 宇都宮宇都宮 at 2011年08月28日 09:57
宇都宮さん

ソースコードの公開感謝します
手元に同じGM管を入手したのはよいのですが、なかなか回路作成に着手できずにいました。以前はソース及びバイナリー(削除)も記載されていませんでしたが、バイナリーの記載はしないのでしょうか?
もしよかったら、HEXの登録をお願いします。
Posted by wolf at 2011年09月18日 17:46
wolfさん

ご意見ありがとうございます。
本文中にリンク先を追記しました。

また、実際作られる際、電源は乾電池x2などに
した方が良いかも知れません。
私は、3.3Vスイッチング電源で実験をしました。
Posted by 宇都宮 at 2011年09月18日 21:21
宇都宮さん

早速のアップロードありがとうございます
早速、明日、秋葉で材料探しです

現在、GM管の入手が可能になりつつありますが、まだ、効果なため
自作中です。また、できましたら本サイトに投稿します!

ありがとうございます
Posted by wolf at 2011年09月18日 22:58
宇都宮さん

お世話になります
確認ですが、記載の中の『写るんです』からの流動部品ですが、コンデンサー(223)とありますが、実装されていないように思います
私が購入した、『写るんです』が未実装なのかもしれませんが?・??
ちなみに、223は入手が困難為、103×2(並列)でも可能でしょうか
Posted by wolf at 2011年09月26日 11:14
wolfさん

「写ルンです」の基板に透明の部品がついていると思います。

ちなみに、コンデンサは1000pF程度で十分ですが
耐圧1kV程度のものを使用する必要があります。
Posted by 宇都宮 at 2011年09月26日 12:55
宇都宮さん

お忙しいところご回答ありがとうございます

1000pF/1KVであれば、秋葉で入手できませね!102の耐圧1KVで問題なさそうですね(80~120円/個)
所で、たびたび質問をして申し訳
あと2点ほど確認させてください!

① 『モード切換え ・未定(未使用)
  SW入力とする場合、プルアップ抵抗が必要です。』
 と記載がありますが、プルアップは幾つぐらい必要ですか?
 10~100Ωぐらいですか?


② 回路図には電解コンデンサーが2ヶ所必要になっていますが
  実写では、一つのみ実装と見受けられますが?
  また、実写の青いコンデンサー(○型:)が223と思ってました

お忙しい所恐縮ですが、よろしくお願いします

  
Posted by wolf at 2011年09月28日 08:27
wolfさん


> ① 『モード切換え ・未定(未使用)
>   SW入力とする場合、プルアップ抵抗が必要です。』
>  と記載がありますが、プルアップは幾つぐらい必要ですか?
>  10~100Ωぐらいですか?

ここは使用しないので付けなくてOKです。
(将来的に機能を追加する場合を考えると1k~10kΩ程度)


> ② 回路図には電解コンデンサーが2ヶ所必要になっていますが
>   実写では、一つのみ実装と見受けられますが?
>   また、実写の青いコンデンサー(○型:)が223と思ってました

マイコンの横についている青色の小さいのが該当するタンタルコンデンサ(極性あり)になります。
Posted by 宇都宮 at 2011年09月28日 19:42
宇都宮さん


お世話になります
先月から、作成に着手しはや1ヶ月が過ぎます
試作品を何度か作成してみたのですが、うまく動きません
どうも、高電圧が発生していないように感じます
PICからは、クロックが発生しているが、5765を通すと何も
波形が出てきません。
何かよいアドバイスはありますか
また、作成ポイントがあれば教えてください
Posted by wolf at 2011年10月08日 23:47
wolfさん

PICからパルスが出ているようですので
そのあとを順番に追っていく必要があります。

トランジスタの入力、出力、トランスの出力、ダイオードの出力・・・・ と信号をチェックしていきます。

良くあるミスとしては、GNDがつながっていないとかです。
Posted by 宇都宮 at 2011年10月09日 23:39
宇都宮さん
お世話になります
その後、時間がなく確認とご返事が出来てませんでした。GNDは取れています。
しかし、正弦波らしき波形は出てきません。トランス、トランジスタわを交換してみましたが、やはり変化なしです。
Posted by wolf at 2011年10月22日 11:06
wolfさん

マイコンからはパルスが出ますので、正弦波はどこにも出ません。
まずはトランジスタがOnしているかの確認ですね。
Onしていなければ配線を確認しましょう。
Posted by 宇都宮 at 2011年10月22日 11:51
宇都宮さん


早々の回答ありがとうございます
正弦波でなく、パルス波形の間違いでした。申し訳ございません

トランジスター(2SC5765)のことでしょうか?ONとは、コレクターに発生する信号こ事ですか?
ベースにはパルス信号は入りますが、コレクターからは何も信号が出ていないように見えます。
Posted by wolf at 2011年10月22日 15:49
wolfさん

> トランジスター(2SC5765)のことでしょうか?

そうです。

パルスが出ていない時は、上記トランジスタのコレクタはHighになっていて
パルスが出ている時は、Lowにならないといけません。

Highになっていないようでしたら、その前の電源につながっているトランジスタや可変抵抗の電圧をチェックしてみましょう。
Posted by 宇都宮 at 2011年10月22日 16:29
宇都宮さん

お世話になります。
度々お忙しいところ恐縮です
何点か確認したいことがあります
お手数を桶しますが、よろしくお願いします

1、高圧が出てい
波形を送ります
1、jpg→スイッチングトランジスタ C
https://box.yahoo.co.jp/guest/viewer?sid=box-l-2vrwcgjaebmjxv2cda4vr3hiia-1001&uniqid=f8ac2dee-b3d7-4b5a-9448-c629be8f3eb2&viewtype=detail
2、jpg→トランス 信号
https://box.yahoo.co.jp/guest/viewer?sid=box-l-2vrwcgjaebmjxv2cda4vr3hiia-1001&uniqid=3cdb5373-ce32-4584-8c59-db9788851781&viewtype=detail

3、jpg→ダイオード信号
https://box.yahoo.co.jp/guest/viewer?sid=box-l-2vrwcgjaebmjxv2cda4vr3hiia-1001&uniqid=49561bd7-ddd1-4d01-b0bd-151456e87a2c&viewtype=detail

4、jpg→gm管端子 間信号
https://box.yahoo.co.jp/guest/viewer?sid=box-l-2vrwcgjaebmjxv2cda4vr3hiia-1001&uniqid=84cae7b0-bdef-4c62-805e-c0f4b0bbef33&viewtype=detail

また、検出信号 赤、緑のダイオードは何もはんのうしません
何か分かれば教えてください



ない事と、ダイオードが
出力波形を送ります
Posted by wolf at 2011年10月30日 21:09
wolfさん

波形確認しました。
だいたい大丈夫だと思います。

GM管にかかる電圧(画像4)は、電流は僅かしか取れないのでオシロスコープのプローブを当てると電圧はかなり低い値となりますので、画像のような感じで良いかと思います。
(リンク先の秋月電子のマニュアルを参照ください。)

GM管を手で触った際に検出信号(マイコンの6Pin)に信号が出るか確認してみてください。

出ないようでしたら、トランスの入力電圧が低い可能性があります。
電源電圧を5Vにして、トランジスタベースに付けてあるボリュームを調整して検出信号(マイコンの6Pin)にパルスが出る電圧位置がないか確認してみてください。
Posted by 宇都宮 at 2011年10月30日 21:36
宇都宮さん

お世話になります
色々とお手数をおかけして申し訳ございません
早速、5Vで稼働確認をいたしました。結果↓

単3×2:GM管にかかる電圧は15~16V(デジタルテスター値)
5V時:31~32V((デジタルテスター値)
出いていました。電流が低いためこのような数値になっていると考えます

6pinの信号ですが、3V・5V時共に2~3Vぐらいの電圧は掛かっていますが、GM管に刺激を与えると、電圧が下が一瞬下がります。
また、定期的に(約5S間隔)1V程度下降します
電圧ブザーも同時にビー・ビーとうなり音がしているようです
この状態て正常ですか?やはり、まだ回路的に間違いがあるのか
大変恐縮ですが、驚くほど回路は複雑でないと思います。m(__)m
動作的に、発光ダイオードも何も発光しない状況です。

色々書いてすみません。何か良いアドバイスがあればお願いします
追伸:手持ちのGM管は別な回路で動作確認しました(正常でした)
Posted by wolf at 2011年11月04日 12:59
GM管にかかる電圧をテスターでは正確認は測れませんが
入力電圧を上げると出力も上がっているので問題はないのではないでしょか。

GM管を触った時に6pinの電圧が下がるようですので
GM管→マイコン6pinへの配線は問題ないと思われます。

6pin電圧が定期的(約5sec)に低下するのは問題です。
5secは緑LEDの点滅周期ですので、緑LEDの配線が間違っている可能性があります。

電圧ブザーはマイコン側の端子を直接GNDに落として(もう一方は電源のまま)
正常に鳴るか確認する必要があります。
Posted by 宇都宮 at 2011年11月05日 08:54
上の画像に書かれている文字を入力して下さい
 
<ご注意>
書き込まれた内容は公開され、ブログの持ち主だけが削除できます。

削除
超小型ガイガーカウンタ by PIC12F1822
    コメント(24)