

NOTE: the geiger tube J305β is UV light and alfa ray sensitive, to avoid false readings you need to completely cover it with some black electrical tape,
eventually put a thin layer of copper sheet to protect it from EMI.
This device is compatible with many tubes working from 350V to 1000V
tube chosen: J305β Geiger Tube
Specifications:
Manufacturer: North Optic
Radiation Detection: β, γ
Length: 111mm
Diameter: 11mm
Recommended Voltage: 350V
Plateau Voltage: 360-440V
Sensitivy γ ( 60 Co): 65cps/(µR/s)
Sensitivy γ (equivalent Sievert): 108cpm / (µSv/h)
Max cpm: 30000
cps/mR/h: 18
cpm/m/h: 1080
cpm/µSv/h: 123.147092360319
Factor: 0.00812037037037
suggested H.T. tube supply circuit from manifacturer:
[img ]http://49v.com/asterisk/software/raspberry/J305HT.jpg[/img]
Tutorial and product page:
https://www.cooking-hacks.com/documenta ... i-tutorial
This device does not use serial communication to read measurement data!
----------------------------------------------------------------------------------------------------------------------
My Arduino code to measure uSv/h, send it to stdout and to activate LCD display and bargraph
Prerequisites: arduPi library for Raspberry
measure.c
- Codice: Seleziona tutto
/*
* ------Geiger Tube board (Arduino Code) Example--------
*
* Explanation: This example shows how to get the signal from the Geiger Tube
* in Arduino, we use one of the Arduino interrupt pins (PIN2).
* We count the time (ms) between two pulses of the Geiger tube.
*
* Copyright (C) 2011 Libelium Comunicaciones Distribuidas S.L.
* http://www.libelium.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Version: 0.3
* Design: Marcos Yarza, David Gascon
* Implementation: Marcos Yarza
*
* Version 0.4
* 20140420 by circulosmeos for RPi compatibility
* circulosmeos.wordpress.com
*
* modified by P.M. Lovisolo Italy - http://forum.49v.com
*/
// include the arduPi library code:
#include "arduPi.h"
// include the LCD library code:
#include "LiquidCrystal.h"
// Threshold values for the led bar
#define TH1 75
#define TH2 150
#define TH3 250
#define TH4 400
#define TH5 600
// define geiger tube Conversion factor (cpm * conversion factor = μSv/h)
// for J305By geiger tube
//#define CONV_FACTOR 0.00812
// for SBM-20 geiger tube (1/361)
#define CONV_FACTOR 0.00277
// Variables
int ledArray [] = {10,11,12,13,9};
int geiger_input = 2;
long count = 0;
long countPerMinute = 0;
long timePrevious = 0;
long timePreviousMeassure = 0;
long countPrevious = 0;
float radiationValue = 0.0;
void ledVar(int value);
void countPulse();
void setup(LiquidCrystal *lcd){
pinMode(geiger_input, INPUT);
digitalWrite(geiger_input,HIGH);
for (int i=0;i<5;i++){
pinMode(ledArray[i],OUTPUT);
}
// test led array ON
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);
pinMode(11, OUTPUT);
digitalWrite(11, HIGH);
pinMode(12, OUTPUT);
digitalWrite(12, HIGH);
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
pinMode(14, OUTPUT);
digitalWrite(14, HIGH);
pinMode(15, OUTPUT);
digitalWrite(15, HIGH);
pinMode(9, OUTPUT);
digitalWrite(9, HIGH);
//set up the LCD\'s number of columns and rows:
lcd->begin(16, 2);
lcd->clear();
lcd->setCursor(0, 0);
lcd->print("Radiation Sensor");
lcd->setCursor(0,1);
lcd->print("Board - 2019 -");
delay(3000);
lcd->clear();
lcd->setCursor(0, 0);
lcd->print("Counts*minute");
lcd->setCursor(0,1);
lcd->print("microSv*hour");
delay(3000);
//for (int i=0;i<5;i++){
// delay(200);
// lcd->scrollDisplayLeft();
//}
//delay(500);
lcd->clear();
lcd->setCursor(0, 0);
lcd->print("- www.49v.com -");
lcd->setCursor(0,1);
lcd->print(" P.M. Lovisolo ");
delay(3000);
//led array off
pinMode(10, OUTPUT);
digitalWrite(10, LOW);
pinMode(11, OUTPUT);
digitalWrite(11, LOW);
pinMode(12, OUTPUT);
digitalWrite(12, LOW);
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
pinMode(14, OUTPUT);
digitalWrite(14, LOW);
pinMode(15, OUTPUT);
digitalWrite(15, LOW);
pinMode(9, OUTPUT);
digitalWrite(9, LOW);
lcd->clear();
lcd->setCursor(0, 0);
lcd->print("CPM=");
lcd->setCursor(4,0);
lcd->print(6*count);
lcd->setCursor(8,0);
lcd->print("counts");
lcd->setCursor(0,1);
lcd->print(radiationValue);
lcd->setCursor(7,1);
lcd->print(" uSv/h");
attachInterrupt(2,countPulse,FALLING);
}
void loop(LiquidCrystal *lcd){
if (millis()-timePreviousMeassure > 60000){
detachInterrupt(2);
countPerMinute = 1*count;
//countPerMinute = count/10;
radiationValue = countPerMinute * CONV_FACTOR;
timePreviousMeassure = millis();
//Serial.print("cpm = ");
//Serial.print(countPerMinute,DEC);
//Serial.print(" - ");
//Serial.print("uSv/h = ");
//Serial.println(radiationValue,4);
lcd->clear();
lcd->setCursor(0, 0);
lcd->print("CPM=");
lcd->setCursor(4,0);
lcd->print(countPerMinute);
lcd->setCursor(8,0);
lcd->print("counts");
lcd->setCursor(0,1);
lcd->print(radiationValue,4);
lcd->print((int)radiationValue);
lcd->setCursor(7,1);
lcd->print(" uSv/h");
//fprintf(stderr,"CPM ");
//fprintf(stderr,"%d\n",countPerMinute);
fprintf(stderr,"%f",radiationValue);
fprintf(stderr," uSv/h\n");
//led var setting
if(countPerMinute <= TH1) ledVar(0);
if((countPerMinute <= TH2)&&(countPerMinute>TH1)) ledVar(1);
if((countPerMinute <= TH3)&&(countPerMinute>TH2)) ledVar(2);
if((countPerMinute <= TH4)&&(countPerMinute>TH3)) ledVar(3);
if((countPerMinute <= TH5)&&(countPerMinute>TH4)) ledVar(4);
if(countPerMinute>TH5) ledVar(5);
count = 0;
attachInterrupt(2,countPulse,FALLING);
delay (60000);
}
}
void countPulse(){
//detachInterrupt(2);
count++;
//while(digitalRead(2)==0){
//}
//attachInterrupt(2,countPulse,FALLING);
}
void ledVar(int value){
if (value > 0){
for(int i=0;i<=value;i++){
digitalWrite(ledArray[i],HIGH);
}
for(int i=5;i>value;i--){
digitalWrite(ledArray[i],LOW);
}
}
else {
for(int i=5;i>=0;i--){
digitalWrite(ledArray[i],LOW);
}
}
}
int main (){
// initialize the library with the numbers of the interface pins
// AFTER WirePi has been initialized (!)
LiquidCrystal lcd(3,4,5,6,7,8);
setup(&lcd);
while(1){
loop(&lcd);
}
return (0);
}
Note:
modified for the SBM-20 tube, if you want to use the J305B tube, you need to comment-out the SBM-20 CONV_FACTOR section and remove comment in the J305 section this way:
- Codice: Seleziona tutto
// for J305By geiger tube
#define CONV_FACTOR 0.00812
// for SBM-20 geiger tube (1/361)
//#define CONV_FACTOR 0.00277
compile the code for Raspberry:
- Codice: Seleziona tutto
g++ -lrt -lpthread measure.c LiquidCrystal.cpp Print.cpp arduPi.cpp -o measure
setting permission to file:
- Codice: Seleziona tutto
chmod 755 measure
to launch file from Raspberry console (test):
- Codice: Seleziona tutto
sudo ./measure
My Raspberry scripts (all Bash):
prerequisites:
- Codice: Seleziona tutto
sudo apt-get install bc
This is the main script I programmed to start measuring uSv/h, to display data on the LCD and to save measurements in a csv temporary file.
The csv file is regenerated (empty) at each reboot since I don't want a huge file and also because I use MySQL to store all data.
If you are to much worried about writing data too frequently to the internal SD card, you can use a ramdisk or an external USB drive.
print_rad2csv.sh
- Codice: Seleziona tutto
#!/bin/bash
measure 2>&1 | awk '{ print strftime("%s %Y-%m-%d %H:%M:%S"), $0; fflush(); }' | sed -e 's/\s\+/,/g;w /var/www/rad/readings.csv'
note: the awk part add unixtime, date and time, the sed part substitutes "spaces" with "commas" and writes the csv file,
unixtime (optional) will be used as a primary key in Mysql to avoid importing duplicates.
add print_rad2csv.sh to "/etc/rc.local" file:
- Codice: Seleziona tutto
#!/bin/sh -e
#
# rc.local
#
/bin/sh /root/print_rad2csv.sh
#
exit 0
results:
/var/www/rad/readings.csv
- Codice: Seleziona tutto
1548232110,2019-01-23,09:28:30,0.056840,uSv/h
1548232170,2019-01-23,09:29:30,0.073080,uSv/h
1548232290,2019-01-23,09:31:30,0.048720,uSv/h
radmon.sh
- Codice: Seleziona tutto
#!/bin/bash
# L305By tube conversion factor from uSv/h to CPM (CPM = uSv/h * conv)
conv=123.14709
# read last value from csv file generated by my instrument
line="$(/usr/bin/tail -n 1 /var/www/rad/readings.csv | cut --complement -c 1-31 | cut --complement -c 9-14 | sed -e 's/,/ /g')"
# calculations to get CPM from uSv/h
#echo $line
line2="$(echo "$line*$conv" | bc)"
#echo $line2
line3="$(echo $line2 | awk '{print int($1+0.5)}')"
#echo $line3
# send data to radmon.org
user="pilovis"
password="mypwd"
exec=`wget -O /dev/null "http://radmon.org/radmon.php?function=submit&user=$user&password=$password&value=$line3&unit=CPM"
send to radmon.org the last CPM reading every minute:
crontab -e
- Codice: Seleziona tutto
*/1 * * * * /bin/sh /root/radmon.sh
Extra:
Import data into MySQL database:
import_csv2sql.sh
- Codice: Seleziona tutto
#!/bin/bash
/usr/bin/mysql -upilovis -pmypwd --local_infile=1 data -e "LOAD DATA LOCAL INFILE '/var/www/rad/readings.csv' INTO TABLE letture_radiazioni FIELDS TERMINATED BY ',' enclosed by '\
MySQL db structure
- Codice: Seleziona tutto
CREATE TABLE `letture_radiazioni` (
`unix_time` bigint(20) NOT NULL,
`date` date DEFAULT NULL,
`time` time DEFAULT NULL,
`value` decimal(10,6) DEFAULT NULL,
`unit` text,
PRIMARY KEY (`unix_time`),
UNIQUE KEY `unix_time` (`unix_time`)
I'm planning to move from one reading for 6000 ms (one minute) to one reading for 30000 ms (30 minutes), to get more consistent data.