視訊加載中...
介紹
目前輻射監測與我們息息相關,它不僅關系到我們的健康與安全,還隐藏着許多神秘和迷人的科學現象。核輻射是指來自放射性物質的粒子或電磁波的釋放。它分為三種類型:阿爾法輻射、貝塔輻射和伽馬射線。
這些輻射與我們日常生活息息相關,比如在醫學診斷、能源生産和食品輻照中的應用。然而,它們也帶來了一定的危險。了解這些輻射的特點和安全門檻值,能幫助我們更好地應對潛在的風險。
随手拿起身邊的行空闆,手搓了一個桌面版的蓋革計數器。簡單說這是一種專門探測電離輻射強度的記數儀器。
通常蓋革計數器由一個充氣密封管和一個資訊顯示屏構成,可以測得機關時間内的射線數。我将在下面詳細分享自制蓋革計數器的各個環節,以幫助我們日常監測輻射值和增加自定義功能。
硬體選型
現在我們一起來看看制作一個輻射監測器所需的硬體!
材料清單
- 行空闆 X1
- 蓋革計數器子產品 X1
- 溫濕度傳感器 X1
- U型公對母TypeC延長線 X1
接線圖
蓋革計數器子產品連接配接至行空闆pin23
DHT20溫濕度傳感器連接配接至行空闆IIC接口
3D列印外殼
3D列印外殼下載下傳連結: https://www.thingiverse.com/thing:6224720/files
蓋格計數器原理
如何測量輻射值呢?
這裡科普一下蓋革計數器的原理。
蓋革計數器是一種氣體放電探測器,内部充有易電離氣體,當輻射進入管中,會引起氣體電離,進而産生脈沖電流。這些脈沖信号被放大後就成為計數脈沖。我們隻需要統計機關時間内的脈沖個數,就可以直接計算出環境輻射量。相比其他探測器,蓋革計數管最大的優點是它輸出數字電信号,不需要複雜的模拟電路就可以實作輻射的精确計數。是以我們統計好每分鐘有多少個輻射粒子經過了氣體管,就可以得出目前環境的受輻射程度了。
如何計算輻射量?
這裡有三個關鍵的機關CPM、毫希弗(mSv/h),微希弗(uSv/h)。
CPM (Counts Per.Minute是種測量輻射水準的機關,為次/分鐘。它表示在一分内輻射值所接收到的輻射粒子擊中的次數。
而輻射水準可以用每小時受到輻射量水準的水準衡量:(Sv/h)、毫希弗(mSv/h)、微希弗(uSv/h)表示。
換算公式為 151CPM = 1uSv/h
1Sv/h = 1000mSv/h = 1000000uSh/h
如何評價和計量輻射程度?
《放射衛生防護基本标準》中提到,公衆中個人受到照射的年劑量當量限值是:全身均勻照射不超過5mSv;任何單個組織和或器官不超過50mSv;一生中每年的全身劑量當量限值應不高于1mSv。
室内環境中的核輻射劑量标準值為0.5uSV/h,根據公衆年輻射劑量限制5mSv/h進行計算,按照365*24小時的計算方法,劑量率不超過0.5uSv/h,在這個範圍内屬于正常範圍,一般室内環境的正常輻射劑量率在0.20uSv/h以下,大部分在0.13左右,但通常衛生間與廚房中存在的輻射劑量率較高。
程式編輯
用python程式設計計算微希弗(uSv/h)
計算機關時間間隔内(count)觸發多少次引腳中斷,判斷經過了多少個輻射粒子。這裡先設定為五秒計算一次(time_gap)。然後用60秒/5秒*經過的粒子數,計算出一分鐘經過的粒子數(cpm)。由于 151CPM = 1uSv/h,最終得出uSv/h的數值。
加載pinpong庫,用以python控制蓋格計數器
加載GUI庫,用以在顯示屏上顯示數字。
傳感器連接配接引腳p23,作為信号輸入。
import time
from pinpong.board import Board,Pin
Board("unihiker").begin() #初始化,選擇闆型(uno、leonardo、xugu)和端口号,不輸入端口号則進行自動識别
from unihiker import GUI #導入包
gui=GUI() #執行個體化GUI類
btn = Pin(Pin.P23, Pin.IN)
設定變量和函數:
time_gap:輸入兩次計算微希弗(uSv/h)值的時間間隔
start_time:開始計數的時間
count:經過的粒子數
time_gap:兩次計算的時間間隔
uSvh:最終得出的輻射值
定義函數zero,确定開始計算時間并計數清零。
定義中斷函數,下降中斷時粒子計數+1。
定義get_cpm函數,計算出usvh的值。
time_gap = 0
start_time = 0
count = 0
time_gap = 5
uSvh = 0
def zero():
global start_time,count
start_time = time.time()
count = 0
def btn_falling_handler(pin):#中斷事件回調函數
global count
count += 1
zero()
btn.irq(trigger=Pin.IRQ_FALLING, handler=btn_falling_handler) #設定中斷模式為下降沿觸發
def get_cpm():
global uSvh
if time.time() - start_time >= time_gap:
uSvh = round((count/151)*(60/time_gap),2)
print("uSvh=",uSvh)
zero()
顯示屏顯示
在150*90像素、黑色20号字顯示目前輻射值。
允許get_cpm函數,并更新顯示中的text。
dig = gui.draw_digit(x=150, y=90, text=uSvh, origin = "center",color="black",font_size=20,angle=90)#數位管字型顯示
while True:
#start()
time.sleep(1) #保持程式持續運作
get_cpm()
dig.config(text=uSvh)
全部代碼
import time
from pinpong.board import Board,Pin
Board("unihiker").begin() #初始化,選擇闆型(uno、leonardo、xugu)和端口号,不輸入端口号則進行自動識别
from unihiker import GUI #導入包
gui=GUI() #執行個體化GUI類
btn = Pin(Pin.P23, Pin.IN)
time_gap = 0
start_time = 0
count = 0
time_gap = 5
uSvh = 0
def zero():
global start_time,count
start_time = time.time()
count = 0
def btn_falling_handler(pin):#中斷事件回調函數
global count
count += 1
zero()
btn.irq(trigger=Pin.IRQ_FALLING, handler=btn_falling_handler) #設定中斷模式為下降沿觸發
def get_cpm():
global uSvh
if time.time() - start_time >= time_gap:
uSvh = round((count/151)*(60/time_gap),2)
print("uSvh=",uSvh)
zero()
dig = gui.draw_digit(x=150, y=90, text=uSvh, origin = "center",color="black",font_size=20,angle=90)#數位管字型顯示
while True:
#start()
time.sleep(1) #保持程式持續運作
get_cpm()
dig.config(text=uSvh)
顯示優化
現在輻射值顯示出來了,但畫面略顯單調。此時我們可以嘗試增加溫濕度傳感器,同時顯示溫濕度、實時的年月日資訊、和輻射值變化的折線圖。當輻射值超過0.5uSvh的時候,行空闆發出蜂鳴聲并且數值顯示紅色。
- 溫濕度傳感器:DHT20
- 加載溫濕度傳感器的庫:from pinpong.libs.dfrobot_dht20 import DHT20
- 數字橫向顯示,在這段代碼後面加上‘angle=90’。tem1 = gui.draw_text(x=55, y=263, text="Temperature :", origin = "center",color="white",font_size=8,angle=90)
- 繪制線段的函數:line1=gui.draw_line(x0=(numberMap((uSvh_list[0]), 0, 1.1, 239, 200)),y0=320,x1=(numberMap((uSvh_list[1]), 0, 1.1, 239, 200)),y1=288,width=2,color="#acacac")
- 年月日和時間的顯示: DigitalTime.config(text=time.strftime("%Y/%m/%d %H:%M"))
- 折線圖始終顯示最新的10個資料的變化:def numberMap(x, in_min, in_max, out_min, out_max): return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
import time
from pinpong.board import Board,Pin
from pinpong.libs.dfrobot_dht20 import DHT20
from pinpong.extension.unihiker import *
Board("unihiker").begin() #初始化,選擇闆型(uno、leonardo、xugu)和端口号,不輸入端口号則進行自動識别
from unihiker import GUI #導入包
gui=GUI() #執行個體化GUI類
btn = Pin(Pin.P23, Pin.IN)
p_dht20 = DHT20()
#global num_pulse1
time_gap = 0
start_time = 0
count = 0
time_gap = 5
uSvh = 0
def zero():
global start_time,count
start_time = time.time()
count = 0
# print('start',start_time)
def btn_falling_handler(pin):#中斷事件回調函數
global count
count += 1
# print("pulse = ", count)
zero()
btn.irq(trigger=Pin.IRQ_FALLING, handler=btn_falling_handler) #設定中斷模式為下降沿觸發
def get_cpm():
# print("time:",time.time())
global uSvh
global dht1
global p_dht20
if time.time() - start_time >= time_gap:
print("-------------------")
print("count=",count)
uSvh = round((count/151)*(60/time_gap),2)
print("uSvh=",uSvh)
zero()
def numberMap(x, in_min, in_max, out_min, out_max):
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
uSvh_list = [0,0,0,0,0,0,0,0,0,0,0]
bg = gui.fill_rect(x=0, y=0, w=240, h=320, width=3, color=(0, 0, 0),onclick=lambda: print("rect clicked"))
tem1 = gui.draw_text(x=55, y=263, text="Temperature :", origin = "center",color="white",font_size=8,angle=90)#數位管字型顯示
tem2 = gui.draw_digit(x=95,y=240,text=(int(float(p_dht20.temp_c()))),origin = "center",color="white",font_size=33,angle=90)
tem3 = gui.draw_digit(x=105, y=190, text="°C", origin = "center",color="white",font_size=10,angle=90)#數位管字型顯示
humi1 = gui.draw_text(x=57, y=140, text="Humidity :", origin = "center",color="white",font_size=8,angle=90)#數位管字型顯示
humi2 = gui.draw_digit(x=95,y=100,text=(int(float(p_dht20.humidity()))),origin = "center",color="white",font_size=33,angle=90)
humi3 = gui.draw_digit(x=105, y=45, text="%rh", origin = "center",color="white",font_size=10,angle=90)#數位管字型顯示
u1 = gui.draw_text(x=143, y=270, text="Radiation :", origin = "center",color="white",font_size=8,angle=90)#數位管字型顯示
u2 = gui.draw_digit(x=175, y=150, text=uSvh, origin = "center",color="white",font_size=45,angle=90)#數位管字型顯示
u3 = gui.draw_digit(x=190, y=45, text="uSvh", origin = "center",color="white",font_size=12,angle=90)#數位管字型顯示
DigitalTime=gui.draw_digit(text=time.strftime("%Y/%m/%d %H:%M"),x=10,y=310,font_size=15, color="white",angle=90)
if (len(uSvh_list) >= 12):
uSvh_list.pop((len(uSvh_list) - 1))
print(uSvh_list)
line1=gui.draw_line(x0=(numberMap((uSvh_list[0]), 0, 1.1, 239, 200)),y0=320,x1=(numberMap((uSvh_list[1]), 0, 1.1, 239, 200)),y1=288,width=2,color="#acacac")
line2=gui.draw_line(x0=(numberMap((uSvh_list[1]), 0, 1.1, 239, 200)),y0=288,x1=(numberMap((uSvh_list[2]), 0, 1.1, 239, 200)),y1=256,width=2,color="#acacac")
line3=gui.draw_line(x0=(numberMap((uSvh_list[2]), 0, 1.1, 239, 200)),y0=256,x1=(numberMap((uSvh_list[3]), 0, 1.1, 239, 200)),y1=224,width=2,color="#acacac")
line4=gui.draw_line(x0=(numberMap((uSvh_list[3]), 0, 1.1, 239, 200)),y0=224,x1=(numberMap((uSvh_list[4]), 0, 1.1, 239, 200)),y1=192,width=2,color="#acacac")
line5=gui.draw_line(x0=(numberMap((uSvh_list[4]), 0, 1.1, 239, 200)),y0=192,x1=(numberMap((uSvh_list[5]), 0, 1.1, 239, 200)),y1=160,width=2,color="#acacac")
line6=gui.draw_line(x0=(numberMap((uSvh_list[5]), 0, 1.1, 239, 200)),y0=160,x1=(numberMap((uSvh_list[6]), 0, 1.1, 239, 200)),y1=128,width=2,color="#acacac")
line7=gui.draw_line(x0=(numberMap((uSvh_list[6]), 0, 1.1, 239, 200)),y0=128,x1=(numberMap((uSvh_list[7]), 0, 1.1, 239, 200)),y1=96,width=2,color="#acacac")
line8=gui.draw_line(x0=(numberMap((uSvh_list[7]), 0, 1.1, 239, 200)),y0=96,x1=(numberMap((uSvh_list[8]), 0, 1.1, 239, 200)),y1=64,width=2,color="#acacac")
line9=gui.draw_line(x0=(numberMap((uSvh_list[8]), 0, 1.1, 239, 200)),y0=64,x1=(numberMap((uSvh_list[9]), 0, 1.1, 239, 200)),y1=32,width=2,color="#acacac")
line10=gui.draw_line(x0=(numberMap((uSvh_list[9]), 0, 1.1, 239, 200)),y0=32,x1=(numberMap((uSvh_list[10]), 0, 1.1, 239, 200)),y1=0,width=2,color="#acacac")
while True:
#start()
time.sleep(1) #保持程式持續運作
get_cpm()
# tem1.config(text="溫度:")
tem2.config(text=(int(float(p_dht20.temp_c()))))
# humi1.config(text="濕度:")
humi2.config(text=(int(float(p_dht20.humidity()))))
# u1.config(text="輻射量:")
u2.config(text=uSvh,color="white")
DigitalTime.config(text=time.strftime("%Y/%m/%d %H:%M"))
print(uSvh_list)
uSvh_list.insert(0,uSvh)
line1.config(x0=(numberMap((uSvh_list[0]), 0, 1.1, 239, 200)),y0=320,x1=(numberMap((uSvh_list[1]), 0, 1.1, 239, 200)),y1=288)
line2.config(x0=(numberMap((uSvh_list[1]), 0, 1.1, 239, 200)),y0=288,x1=(numberMap((uSvh_list[2]), 0, 1.1, 239, 200)),y1=256)
line3.config(x0=(numberMap((uSvh_list[2]), 0, 1.1, 239, 200)),y0=256,x1=(numberMap((uSvh_list[3]), 0, 1.1, 239, 200)),y1=224)
line4.config(x0=(numberMap((uSvh_list[3]), 0, 1.1, 239, 200)),y0=224,x1=(numberMap((uSvh_list[4]), 0, 1.1, 239, 200)),y1=192)
line5.config(x0=(numberMap((uSvh_list[4]), 0, 1.1, 239, 200)),y0=192,x1=(numberMap((uSvh_list[5]), 0, 1.1, 239, 200)),y1=160)
line6.config(x0=(numberMap((uSvh_list[5]), 0, 1.1, 239, 200)),y0=160,x1=(numberMap((uSvh_list[6]), 0, 1.1, 239, 200)),y1=128)
line7.config(x0=(numberMap((uSvh_list[6]), 0, 1.1, 239, 200)),y0=128,x1=(numberMap((uSvh_list[7]), 0, 1.1, 239, 200)),y1=96)
line8.config(x0=(numberMap((uSvh_list[7]), 0, 1.1, 239, 200)),y0=96,x1=(numberMap((uSvh_list[8]), 0, 1.1, 239, 200)),y1=64)
line9.config(x0=(numberMap((uSvh_list[8]), 0, 1.1, 239, 200)),y0=64,x1=(numberMap((uSvh_list[9]), 0, 1.1, 239, 200)),y1=32)
line10.config(x0=(numberMap((uSvh_list[9]), 0, 1.1, 239, 200)),y0=32,x1=(numberMap((uSvh_list[10]), 0, 1.1, 239, 200)),y1=0)
i = uSvh
if (i > 0.5):
u2.config(text=uSvh,color="red")
buzzer.pitch(466,8)
i = 0
time.sleep(1)
使用行空闆DIY自制的桌面蓋革計數器,可以非常便捷地實時監測環境中的輻射水準。它具有制作簡單、使用友善、成本低廉等優點,通過簡單的脈沖統計就可以計算出輻射劑量率,幫助我們實時了解周圍的輻射情況。同時,項目中使用的行空闆不僅具備了可以觸摸的螢幕,還可以與其他硬體傳感器連接配接。直接使用python程式設計也極大的增加了創造的靈活度。與一般商業檢測裝置相比,這種自制裝置更加靈活和可定制化,我們可以添加報警功能、資料記錄功能等,讓輻射檢測更智能化。總之,在核污染日漸被熟知的當下,制作一台桌面版蓋革計數器,讓輻射監測觸手可及,既可提高輻射安全意識,也是一件有意義的創造。
蓋革在手,輻射逃走!
原文首發于:https://makelog.dfrobot.com.cn/article-313483.html
轉載請注明來源資訊