Connecting Geiger Counter for Arduino and Raspberry Pi to radmon.org

More
5 years 9 months ago - 5 years 9 months ago #4258 by pilovis





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:


Tutorial and product page:

https://www.cooking-hacks.com/documentation/tutorials/geiger-counter-radiation-sensor-board-arduino-raspberry-pi-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
/*
 *  ------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:
// 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:
g++ -lrt -lpthread measure.c LiquidCrystal.cpp Print.cpp arduPi.cpp -o measure

setting permission to file:
chmod 755 measure

to launch file from Raspberry console (test):
sudo ./measure

My Raspberry scripts (all Bash):

prerequisites:
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 too 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
#!/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:
#!/bin/sh -e
#
# rc.local
#
/bin/sh /root/print_rad2csv.sh
#
exit 0

results:

/var/www/rad/readings.csv
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
#!/bin/bash

# J305By 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
*/1 * * * * /bin/sh /root/radmon.sh

Extra:
Import data into MySQL database:

import_csv2sql.sh
#!/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
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.
Last edit: 5 years 9 months ago by pilovis.
The following user(s) said Thank You: mw0uzo

Please Log in or Create an account to join the conversation.

More
5 years 9 months ago - 5 years 9 months ago #4259 by pilovis
Today here in North West Italy it is snowing and the CPM readings are much higher than usual
Last edit: 5 years 9 months ago by pilovis.

Please Log in or Create an account to join the conversation.

More
5 years 9 months ago - 5 years 9 months ago #4261 by pilovis
A very simple web page in HTML to show your data and graphs from radmon.org

mypage.html
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<title>
</title>
<head>
<meta http-equiv="refresh" content="30" >
</head>
<body>
<font size="2">
<div align="center">
<p>
<i>this page auto refreshes every 30 seconds</i>
<p>
</font>
<font size="4">
<hr>
<b>- Current readings:</b> 
<p>
<img src="http://www.radmon.org/radmon.php?function=cpmreading&user=pilovis"/> (Counts per minute)
<p>
<hr>
<p>
<center>
<form action="http://www.radmon.org/radmon.php?user=pilovis&function=graphtoday&refresh=true" method="post">
<input type="submit" value="Update graphs">
</form>
<br>
<img src="https://radmon.org/UserGraphs/pilovis/graphlasthour.png" alt="" />
<br>
<img src="https://radmon.org/UserGraphs/pilovis/graphtoday.png" />
<p>
<hr>
</center>
</font>
</body>
</html>

note: change "pilovis" with your username.
Last edit: 5 years 9 months ago by pilovis.

Please Log in or Create an account to join the conversation.

More
5 years 9 months ago - 5 years 9 months ago #4262 by pilovis
Next step will be to connect a GPS and a 3G USB dongles to this device, than put it in my car and start sending data/position 24 hours a day to a central database.
Last edit: 5 years 9 months ago by pilovis.

Please Log in or Create an account to join the conversation.

More
5 years 9 months ago #4263 by pilovis

Please Log in or Create an account to join the conversation.

More
5 years 9 months ago #4265 by mw0uzo
Ah a great thread! Thank you for posting the details and the BASH scripts and code. There will be several people interested in this information. Thank you pilovis!

Please Log in or Create an account to join the conversation.

Moderators: Gamma-Man
Time to create page: 0.206 seconds
Powered by Kunena Forum
Everything's free. Please support us by considering a donation. Log in first!
Solar powered Raspberry Pi 4 server stats: CPU 51% Memory 21% Swap 70% CPU temp=50.6'C Uptime 71 Days