這個(gè)項(xiàng)目使用 3D 打印外殼測(cè)量放射性,帶有 OLED 顯示屏和鋰離子電池。
項(xiàng)目是在我買了一個(gè)現(xiàn)成的 Geiger 計(jì)數(shù)器套件之后開始的。
我的整個(gè)想法是把這個(gè)套件放在一個(gè) 3D 打印的外殼中,這樣完整的蓋革計(jì)數(shù)器套件就可以手持了。最終結(jié)果如下圖所示:
第 1 步:系統(tǒng)設(shè)計(jì)
手持式蓋革計(jì)數(shù)器的設(shè)計(jì)如下圖所示:
蓋革計(jì)數(shù)器配備 0.96 英寸彩色 OLED 顯示屏,可通過(guò)一個(gè)簡(jiǎn)單的因子告知用戶測(cè)量的 CPM(測(cè)量每分鐘電離事件的檢測(cè)率)以及劑量當(dāng)量(以 μSv/hr 為單位) 151 可以在文獻(xiàn)中找到所使用的蓋革-米勒 (GM) 管的類型。
事實(shí)上,顯示的 CPM 是計(jì)算一分鐘計(jì)數(shù)的結(jié)果,通過(guò)測(cè)量每秒計(jì)數(shù) (CPS) 并將這些測(cè)量值存儲(chǔ)在涵蓋過(guò)去十秒周期的數(shù)組中。過(guò)去 10 秒期間的總計(jì)數(shù)乘以 6 即可獲得 CPM 值。
過(guò)去一秒的計(jì)數(shù)用于通過(guò) OLED 顯示屏上的條形圖顯示瞬時(shí)測(cè)量次數(shù)。這在高計(jì)數(shù)率的情況下很有用,或者當(dāng)手持式計(jì)數(shù)器在輻射源上移動(dòng)時(shí)發(fā)生計(jì)數(shù)率的快速變化時(shí)。
蓋革計(jì)數(shù)器由 18650 型鋰離子電池供電,可通過(guò)微型 USB 插頭充電。Arduino Nano USB 端口也可用于軟件更改。一個(gè)額外的蜂鳴器連接到 Geiger 計(jì)數(shù)器板上,以增強(qiáng) GM 管中的電離聲音。
蓋革計(jì)數(shù)器的所有電子設(shè)備都內(nèi)置在 3D 打印外殼中:
OLED 顯示屏放在蓋革計(jì)數(shù)器頂部的單獨(dú)盒子中:
完全組裝的版本:
第 2 步:制作蓋革計(jì)數(shù)器組件
使用以下材料:
Arduino NANO 1
蓋革計(jì)數(shù)器套件 1
0.96“ OLED 彩色顯示屏 96 * 64 1
Micro USB 充電器板 18650 電池 1
3.7v 4000mAh 受保護(hù)的可充電 18650 鋰離子電池 1
晶體管 BC547 1
蜂鳴器-12MM 1
電阻 1k Ohm 1
電子設(shè)計(jì)
蓋革計(jì)數(shù)器套件的電子設(shè)計(jì)如下電路圖所示:
完整的蓋革計(jì)數(shù)器設(shè)置的電路圖如下:
5V 電源由放置在 Micro USB 充電器板上的可充電鋰離子電池提供。用于 OLED 顯示器的 3、3 V 取自該板。
用于使用 ARDUINO IDE 測(cè)試和構(gòu)建軟件的面包板設(shè)置如下圖所示:
組裝
所有機(jī)械和電子零件的組裝如下圖所示:
請(qǐng)注意,手持式蓋革計(jì)數(shù)器沒(méi)有任何電纜連接。
為了給 3、7V 鋰離子電池充電,外殼上有一個(gè)單獨(dú)的開口,用于(臨時(shí))連接微型 USB 插頭。
額外的迷你 USB 連接可用于 Arduino Nano 的軟件更新。
第 3 步:軟件設(shè)計(jì)
以下流程圖顯示了蓋革計(jì)數(shù)器的一般軟件設(shè)計(jì):
0, 96” OLED 顯示屏的視圖如下:
完整的 Arduino 代碼如下所示:
#include
#include
#include
//Connections for the OLED display
#define sclk 13 //SCL (blue wire)
#define mosi 11 //SDA (white wire)
#define cs 10 //CS (grey wire)
#define rst 9 //RES (green wire)
#define dc 8 //DC (yellow wire)
#define LOGtime 1000 //Logging time in milliseconds (1 second)
#define Minute 60000 //the period of 1 minute for calculating the CPM values
#define show endWrite
#define clear() fillScreen(0)
// Color definitions
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, rst);
int Counts = 0; //variable containing the number of GM Tube events withinthe LOGtime
unsigned long previousMillis= 0; //variablefor storing the previous time
int AVGCPM = 0; //variable containing the floating average number ofcounts over a fixed moving windo period
int TenSecCPM = 0;
int units = 0;
int tens = 0;
int hundreds = 0;
int thousands = 0;
float Sievert = 0;
int COUNTS[10]; // array for storing the measured amounts of impulses in10 consecutive 1 second periods
int t = 0;
////////////////////the setup code that follows,will run once after "Power On" or after a RESET///////////////////
void setup() {
Serial.begin(115200);
display.begin();
display.fillScreen(BLACK);
floatBattery = analogRead(A3); //(orange wire)
floatBattPerc = 100 * (Battery/770);
//Serial.print("battery value = "); Serial.println (Battery); Serial.print("battery percentage = "); Serial.println (BattPerc);
display.setCursor(4,4);
display.setTextSize(2);
display.setTextColor(MAGENTA);
display.println("Battery");
display.setCursor(4,24);
display.print (int (BattPerc)); display.print("."); display.print (int((10*BattPerc)-(10*int(BattPerc))));display.print(" %");
delay(3000);
display.fillScreen(BLACK);
for(int x = 0; x < 10 ; x++) { //put all data in the Array COUNTS to 0 (Array positionsrun from 0 to 10;?
COUNTS[x] = 0; //10 positions covering a period of 10 seconds
}
attachInterrupt(0, IMPULSE, FALLING); //define external interrupton pin D2/INT0 to start the interupt routine IMPULSE (green wire)
display.drawRect(0,0,96,64,WHITE);
display.setCursor(4,4);
display.setTextColor(RED);
display.setTextSize(2);
display.print("CPM");
display.setCursor(50,4);
display.setTextSize(1);
display.print("10 sec");
display.setCursor(50,12);
display.print("window");
display.setCursor(4,38);
display.setTextSize(1);
display.setTextColor(GREEN);
display.print("uSv/hr");
display.drawRect(0,48, 96, 16, YELLOW);
}
////////////////////////the loop code that follows,will run repeatedly until "Power Off" or a RESET/////////
void loop()
{
unsignedlong currentMillis= millis();
if(currentMillis - previousMillis >LOGtime)
{
previousMillis = currentMillis;
COUNTS[t] = Counts;
for (int y = 0; y < 10 ; y++) { //add all data in the Array COUNTS together?
TenSecCPM = TenSecCPM + COUNTS[y]; //and calculate the rolling average CPM over a 10 secondperiod
}
AVGCPM = 6* TenSecCPM;
TenSecCPM = 0;
t++ ;
if (t > 9) { t = 0 ;}
//Serial.print ("COUNTS "); Serial.print(t);Serial.print (" = ");Serial.println (COUNTS[t]);
display.fillRect(4,20,90,17,BLACK); // clear the CPM value field on the display
display.setCursor(4,20);
display.setTextColor(RED);
display.setTextSize(2);
display.println(AVGCPM);
//Serial.print ("AVGCPM = "); Serial.print(AVGCPM); //Serial.print (" CPM = "); Serial.println(CPM);
display.fillRect(45,38,50,10,BLACK); //clear the uSv/Hr value field on the display
display.setCursor(45,38);
display.setTextColor(GREEN);
display.setTextSize(1);
Sievert = (AVGCPM /151.0) ; //Serial.print (" Sievert = ");Serial.println (Sievert);
units = int (Sievert); //Serial.print ("units = "); Serial.println(units);
tens = int ((10*Sievert) - (10*units)); //Serial.print ("tens = "); Serial.println(tens);
hundreds = int ((100*Sievert) - (100*units) - (10* tens)); //Serial.print ("hundreds = "); Serial.println(hundreds);
thousands = int ((1000*Sievert) - (1000*units) - (100*tens) - (10*hundreds)); //Serial.print ("thousands ="); Serial.println (thousands);
display.print (units); display.print("."); display.print (tens); display.print (hundreds);display.println (thousands);
display.fillRect(1,49,94,14,BLACK); // clear the CPM indicator field on the display
display.fillRect(1,49,Counts,14,RED); //fill the CPM indicator field on the display
Counts = 0;
}
}
//////////////////END ofLOOP////////////////////////////////////
/////////////////////////////////Hereafter follows the Function for counting the number of impulses from Geiger Counter kit
void IMPULSE()
{
Counts++;
}
代碼中最重要的部分是中斷函數(shù),當(dāng)測(cè)量到 Geiger Counter 的 GM 管上的脈沖會(huì)觸發(fā) Geigercounter 的 INT 輸出(通過(guò)使其在短時(shí)間內(nèi)變?yōu)榈碗娖剑r(shí)調(diào)用。INT信號(hào)連接到引腳D2(Arduino Nano的外部中斷引腳INT0):
attachInterrupt(0, IMPULSE, FALLING);
INT 信號(hào)將啟動(dòng)中斷程序 IMPULSE () 以將 Counts 增加 1:
void IMPULSE() {Counts++ ; }
經(jīng)過(guò) 1000 ms后:
整數(shù) Counts 被放回 0
數(shù)組 COUNTS [ ] 填充了過(guò)去 1000 毫秒內(nèi)測(cè)量的計(jì)數(shù)數(shù)
過(guò)去 10 秒的總計(jì)數(shù)是通過(guò)將數(shù)組 COUNTS [ ] 中的所有數(shù)字相加并乘以 6 以在顯示屏上顯示 CPM 值來(lái)計(jì)算的。
以 μSv/hr 表示的劑量當(dāng)量是通過(guò) CPM 值除以 151 計(jì)算得出的(該值可在文獻(xiàn)中找到)。
在彩色 OLED 顯示屏上,根據(jù)過(guò)去一秒的計(jì)數(shù)值顯示一個(gè)紅色條,因此實(shí)際上呈現(xiàn)的是 CPS 值(每秒計(jì)數(shù))
-
計(jì)數(shù)器
+關(guān)注
關(guān)注
32文章
2256瀏覽量
94478 -
手持式儀器
+關(guān)注
關(guān)注
0文章
5瀏覽量
5744 -
OLED顯示屏
+關(guān)注
關(guān)注
6文章
217瀏覽量
30675 -
3D打印
+關(guān)注
關(guān)注
26文章
3547瀏覽量
109028
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論