DIY GM Environmental Radiation Monitor

Gamma spectacular, theremino adapters, non-sound card based, etc...
User avatar
Svilen
Posts: 184
Joined: 23 Sep 2016, 04:25
Location: Germany
Contact:

DIY GM Environmental Radiation Monitor

Post by Svilen » 25 Apr 2020, 21:24

I recently made a simple environmental radiation monitor with a GM tube, which logs the collected data with a time stamp on a SD card. One can also easily add Ethernet connectivity, but I didn’t need it in this case.

I guess the majority of the technically competent auditorium here will not find much new information in this post, but I still decided to show this quite easy design based on readily available building blocks that I already had, showing also the source code for the people who still haven’t programmed an Arduino microcontroller.

The design: A low dose GM tube is connected to an Arduino compatible detector kit, which sends its output to an Arduino microcontroller board with stacked SD-card shield for data logging.
Here is the place to also say that I do not have any relation to the producers and sellers listed bellow, but I name them since these exact components worked good for me and may save somebody the time to look for suitable parts.

Here is how it looks, but please note that the batteries are used only while experimenting with the device, it is otherwise powered with a 15 000 mAh powerbank (see the last picture):
1s.png
2s.png
I used a ZP1221 GM tube. This type of tubes were also used in the previous generation probes of the official measuring network of the Federal Office for Radiation Protection in Germany, which monitors the ambient dose rate in ~1800 measuring points allover the country.

This is how they look like from the outside:
3s.jpg
And from the inside:
4s.jpg
To extend the measuring range, there is also a high dose GM tube (ZP1301) in these detectors. Both GM tubes are energy compensated.
5s.jpg
5s.jpg (48.25 KiB) Viewed 28071 times
Assuming that after an accident which would saturate the low dose tube (> 3 mGy/h), I won't be that much interested in the readings of this particular logger (and to simplify the circuit and reduce costs), I did not use a high range GM tube. In case you really need one – there are kits that can drive two GM tubes simultaneously (originally for coincidence detection) from the same seller I mention below, and the Arduino Uno can handle interrupts on 2 pins (d2 and d3).

I bought the tube new on eBay, which is quite a rare case, but there are many other low dose sensitive GM tubes which will also do the job.
6s.jpeg
6s.jpeg (19.01 KiB) Viewed 28071 times
To keep it simple, I connected the GM tube to an already assembled detector kit available here (and in eBay too): https://rhelectronics.net/store/diy-gei ... r-kit.html
7s.jpg
There are different other good kits on the market too. There are also Arduino Geiger shields with SD-card logging, which can further simplify the device, but I already had this one.

A jumper on the board allows to disconnect the buzzer, as we prefer in this project, and another one switches the HV from 400V to 500V, which covers most of the GM tubes available on the market. Before using this product, read the manual provided from the producer, it is informative and there are some important precautions to follow.

For every impulse from the GM tube the detector kit produces HIGH-LOW-HIGH interrupt on the INT pin, which is connected to Pin2 of the Arduino microcontroller, where using the interrupt handler, they are counted and the mean value for a given interval of time is logged to the SD-card.

I used an Arduino Uno, here is how to connect it to the GM detector kit (the wires will actually be soldered to the prototyping area of the SD shield stacked above the Arduino board):
8s.jpg
The next component needed is an Arduino compatible data logging shield with real time clock (RTC). I used the one from the link below, but there are many others, including cheap “no name” ones.
https://www.velleman.eu/products/view/?id=435508
9s.jpg
9s.jpg (22.26 KiB) Viewed 28071 times
The shield has a back-up battery for the RTC and an onboard 3.3 V regulator. SD cards up to 2GB are supported.

Now when we have all the modules connected, we need to wire a power source too. While experimenting I just used 3xAA alkaline batteries, but to have enough power for a week of operation, it should be powered with at least 15 000 mAh battery. I used the respective terminal on the GM board, but the circuit can also be powered at the Arduino board. NOTE: Put the slide On/Off switch to OFF position if batteries are connected to the GM kit when you are using a 5V line from the USB of the computer!

To compile and upload the source code to the Arduino controller you will need to download and install the Arduino IDE. Tutorials are available in the Internet for the users who never used it before, just type it in your favorite search engine.
Here is where to download the Arduino IDE from: https://www.arduino.cc/en/main/software

The SD shield uses the SD and RTC libraries, which you can download here: https://www.velleman.eu/downloads/files ... ibrary.zip

After downloading, install them as described below:

To replace the SD library:
1. Close the Arduino IDE if opened
2. Go to C:\Program Files\Arduino, create a backup of the SD folder and remove the content of C:\Program Files\Arduino\libraries\SD
3. Extract the downloaded SD library content into the now empty SD folder.

To install the RTC library:
From the menu bar of the Arduino IDE open Sketch - > Include Library - > Add .ZIP Library and select the RTClib.zip file you downloaded.
10s.png
10s.png (50.28 KiB) Viewed 28071 times
The source code can be optimized, for example sleeping mode can be used for energy saving, but it works good enough for me and I leave it for you to improve it if you wish.
I left the definition of the conversion factor (counts to uSv/hr multiplier) for SBM-20 GM tube, since while you experiment with the kit, it is more comfortable to use the smaller SBM-20 tube, especially when proper terminals for it are already soldered to the board. You just need to specify SBM_20 or ZP_1221 is used in the respective line of the code below. This conversion is of course approximate!

Here is the source code:

Code: Select all

/*
  Enviroinmental Radiation Monitor

  HARDWARE CONNECTIONS:
    A) Connect Geiger PCB INT output to Arduino pin 2.
    B) Connect  Geiger PCB & Arduino grounds together.
    C) Ensure C-INT (103, 0.01 uF) is soldered on the Geiger PCB.

  Velleman (Adafruit) data logging shield; SD card attached to SPI bus as follows:
    MOSI - pin 11
    MISO - pin 12
    CLK  - pin 13
    CS   - pin 10

    Code from Brian K. Gauger is used
*/

#include <SPI.h>
#include <SD.h>

#include "RTClib.h"
RTC_DS1307 rtc;

#define ZP_1221 //Which GM tube is to be used

#ifdef SBM_20
#define CONV_FACTOR 0.0057   // Counts to uSv/hr multiplier for the SBM_20 tube
#endif

#ifdef ZP_1221
#define CONV_FACTOR 0.0012   // Counts to uSv/hr multiplier for the ZP_1221 tube
#endif

const int chipSelect = 10; // for the SD logger shield
unsigned long counts; // number of raw GM Tube events

// Interrupt handler that counts raw events from Geiger Kit
void tube_impulse() {
  counts++;
}

void setup()
{
    
  counts = 0;

  // Initialize Serial communication
  Serial.begin(9600);

  pinMode(2, INPUT);              // Set pin 2 up for GM tube event interrupts
  digitalWrite(2, HIGH);           // Use internal pullup resistor

  attachInterrupt(0, tube_impulse, FALLING);

  // Initialize SD card
  Serial.print("Initializing SD card...");

  // RTC setup
  if (! rtc.begin()) { 
    Serial.println("Couldn't find RTC");
    while (1);
  }

if (! rtc.isrunning()) {    // If the date and time must be adjusted when the rtc is running, the "!" should be removed
  // following line sets the RTC to the date & time this sketch was compiled
  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));   

  // For January 21, 2014 at 3am you would call:
  // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0)); 
  }
  
  // See if the SD card is present and can be initialized (max 2GB):
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");
  Serial.println();
  Serial.print("Please stand by for 10 min for first reading...");
  Serial.println();
}

void loop()
{
  // Real time
  DateTime now = rtc.now();

  // Elapsed time
  static unsigned long then;
  unsigned long currentMillis = millis();

  // Approximate radiation level in microsieverts
  double uSv;

  if (currentMillis - then > 600000) { // 10 min averaging period (600000 ms)
    then = currentMillis;
    if (counts) {                     // i.e., if (counts != 0)
      uSv = (counts / 10) * CONV_FACTOR;
    } else {
      uSv = 0;
    }
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(" ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print("  ");

    Serial.print("CPM: ");
    Serial.print(counts / 10);
    Serial.print(", uSv/hr: ");
    Serial.println(uSv, 2);           // Display 2 decimal places

    // Open the file for logging. Only one file can be open at a time,
    // so this one have to be closed before opening another.
    File dataFile = SD.open("datalog.txt", FILE_WRITE);

    // If the file is available, write to it:
    if (dataFile) {
      dataFile.print(now.year(), DEC);
      dataFile.print('/');
      dataFile.print(now.month(), DEC);
      dataFile.print('/');
      dataFile.print(now.day(), DEC);
      dataFile.print(" ");
      dataFile.print(now.hour(), DEC);
      dataFile.print(':');
      dataFile.print(now.minute(), DEC);
      dataFile.print("  ");

      dataFile.print("CPM: ");
      dataFile.print(counts / 10);
      dataFile.print(", uSv/hr: ");
      dataFile.println(uSv, 2);         // Log 2 decimal places
      dataFile.close();
    }
    // If the file isn't open, pop up an error:
    else {
      Serial.println("error opening datalog.txt");
    }
    counts = 0;
  }
  delay(100);
}
On the SD-card you will find a DATALOG.TXT file with content similar to this one:

2020/4/25 9:12 CPM: 84, uSv/hr: 0.10
2020/4/25 9:22 CPM: 88, uSv/hr: 0.11
2020/4/25 9:32 CPM: 86, uSv/hr: 0.10

To make a graph out of the collected data, you can easily paste it in Excel, defining comma and space as delimiter characters.

Please keep in mind, that if the supply voltage drop below 3.5V, the RTC will not function properly and you will get strange readings like this: 2165/165/165 165:165:165

At the end, we have to enclose all the electronics in a watertight container, since the detector will be installed outdoors:
11s.jpg
This is the final device with the powerbank, ready to be placed in the watertight housing:
12s.jpg
Svilen

User avatar
Sesselmann
Posts: 1374
Joined: 27 Apr 2015, 11:40
Location: Sydney
Contact:

Re: DIY GM Environmental Radiation Monitor

Post by Sesselmann » 26 Apr 2020, 10:13

Svilen,

Thanks for sharing and compliments on a very neat well documented project. I never tried using the Arduino with an SD card shield, looks simpler than using an Rpi.

Thumbs up!!

Steven

User avatar
Svilen
Posts: 184
Joined: 23 Sep 2016, 04:25
Location: Germany
Contact:

Re: DIY GM Environmental Radiation Monitor

Post by Svilen » 26 Apr 2020, 21:33

Thank you very much Steven!
I never used a Raspberry Pi, but using the Arduino SD shield was quite easy and works well. For easier and more frequent data access - WiFi or Ethernet is a must and can also be easily included (I may write about this too).

Greetings,
Svilen
Svilen

User avatar
sgt_bear
Posts: 117
Joined: 16 Jan 2017, 07:06
Contact:

Re: DIY GM Environmental Radiation Monitor

Post by sgt_bear » 28 Apr 2020, 15:33

Hi Svilen,

Very nicely done. I'm a fan of arduino too and have done alot with it and even migrated them to my own platforms.

Where do you place this detector? If its near wifi, you could look into the new Arduino Nano IOT33 which has build in wifi and you can upload the data to thingspeak or so...
- Jonathan from Switzerland

User avatar
Svilen
Posts: 184
Joined: 23 Sep 2016, 04:25
Location: Germany
Contact:

Re: DIY GM Environmental Radiation Monitor

Post by Svilen » 28 Apr 2020, 19:42

Thank you Jonathan,
For now I need it for a remote location that can not benefit from the WiFi, but I will include this functionality in the very near future. I have one Arduino Uno Wifi, so maybe I'll use this one, but the nano IOT33 is even a better option in this case. In case I need help with the code I may ask you :)
Svilen

gwgw
Posts: 57
Joined: 13 May 2019, 08:09
Contact:

Re: DIY GM Environmental Radiation Monitor

Post by gwgw » 01 May 2020, 02:52

Good job!
Regards,
Milen Rangelov

User avatar
Svilen
Posts: 184
Joined: 23 Sep 2016, 04:25
Location: Germany
Contact:

Re: DIY GM Environmental Radiation Monitor

Post by Svilen » 06 May 2020, 18:14

Thanks Milen, your opinion really counts here ;)
Svilen

User avatar
Svilen
Posts: 184
Joined: 23 Sep 2016, 04:25
Location: Germany
Contact:

DIY GM Environmental Radiation Monitor - UPDATE

Post by Svilen » 09 May 2020, 07:28

Since the old DS1307 real time clock (RTC) is inaccurate and significantly affected by ambient temperature changes, I replaced the SD card shield with a separate RTC DS3231 and SD card modules. The DS3231 is very accurate and features a temperature-compensated crystal oscillator. The SD card module supports now micro SD cards.

The first picture below shows how the RTC is connected to the Arduino UNO and the second shows the wiring of the SD card module:
rtc.png
rtc.png (25.26 KiB) Viewed 27798 times
sd.jpeg
sd.jpeg (54.56 KiB) Viewed 27798 times
The source code is rewritten using the DS3231 library available here: http://www.rinkydinkelectronics.com/library.php?id=73

I also attach it for direct download here:
DS3231.zip
(378.7 KiB) Downloaded 533 times

Code: Select all

/*
  Enviroinmental Radiation Monitor

  HARDWARE CONNECTIONS: 

    RH Electronics Geiger Counter Kit
    INT - pin 2.
    (Ensure C-INT (103, 0.01 uF) is soldered on the Geiger PCB) 

  DS3231 RTC module is connected as follows:     
    SDA - dedicated SDA pin or analogue pin 4
    SCL - dedicated SCL pin or analogue pin 5
 
  SD card module attached to SPI bus as follows:
    MOSI - pin 11
    MISO - pin 12
    SCK  - pin 13
    CS   - pin 10


  Connect all the GND and VCC(5V) to the respective arduino GND and 5V pins

  Contains code from Brian K. Gauger
*/

#include <SPI.h>
#include <SD.h>
#include <DS3231.h>		// http://www.rinkydinkelectronics.com/library.php

// Init the DS3231 using the hardware interface
DS3231  rtc(SDA, SCL); 

#define ZP_1221 //Which GM tube is to be used

#ifdef SBM_20
#define CONV_FACTOR 0.0057	// Counts to uSv/hr multiplier for the SBM_20 tube
#endif

#ifdef ZP_1221
#define CONV_FACTOR 0.0012   	// Counts to uSv/hr multiplier for the ZP_1221 tube
#endif

int pinCS = 10; // Pin 10 on Arduino Uno for the SD logger CS
unsigned long counts; 		// number of raw GM Tube events

// Interrupt handler that counts raw events from Geiger Kit
void tube_impulse() {
  counts++;
}

void setup()
{
    
  counts = 0;

  // Initialize Serial communication
  Serial.begin(9600);
  
  pinMode(pinCS, OUTPUT);		// Set pin 10 (as defined above) for the SD logger CS
  pinMode(2, INPUT);			// Set pin 2 up for GM tube event interrupts
  digitalWrite(2, HIGH);		// Use internal pullup resistor

  attachInterrupt(0, tube_impulse, FALLING);  //define external interrupts 

  // Initialize SD card
  Serial.print("Initializing SD card..."); 

  // Initialize the rtc object
  rtc.begin();
  
  // The following lines must be uncommented to set the day-of-week, date and/or time
  //rtc.setDOW(THURSDAY);		// Set Day-of-Week to Wednesday (NOTE: Setting only the date, will not automatically set the proper DOW!)
  //rtc.setTime(22, 0, 0);		// Set the time to 22:00:00 (24hr format)
  //rtc.setDate(7, 5, 2020);		// Set the date to 14th May , 2020 (DD-MM-YYYY)
  // After setting day-of-week, date and/or time, the program must be uploaded again with the setting lines commented (//)  
 
  
  // See if the SD card is present and can be initialized (max 2GB): 
  if (!SD.begin(pinCS)) { 
     Serial.println("Card failed, or not present");
     // don't do anything more: 
     while (1);
  }
  Serial.println("card initialized.");
  Serial.println();
  Serial.print("Please stand by for 10 min for first reading...");
  Serial.println();
}

void loop()
{
  // Real time
  //DateTime now = rtc.now();

  // Elapsed time
  static unsigned long then;
  unsigned long currentMillis = millis();

  // Approximate radiation level in microsieverts
  double uSv;

  if (currentMillis - then > 600000) { 	// 10 min averaging period (600000 ms)
    then = currentMillis;
    if (counts) {                  	// i.e., if (counts != 0)
      uSv = (counts / 10) * CONV_FACTOR;
    } else {
      uSv = 0;
    }
  
  // Send Day-of-Week
  //Serial.print(rtc.getDOWStr());
  //Serial.print(" ");
  
  // Send date
  Serial.print(rtc.getDateStr());
  Serial.print(" ");

  // Send time
  Serial.print(rtc.getTimeStr());
  Serial.print(" ");

  Serial.print("CPM: ");
  Serial.print(counts / 10);
  Serial.print(", uSv/hr: ");
  Serial.print(uSv, 2);           // Display 2 decimal places
  Serial.println();
  
  // Create/Open the file for logging. Only one file can be open at a time, 
  // so this one have to be closed before opening another.
  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  // If the file is available, write to it:
  if (dataFile) {
      //dataFile.print(rtc.getDOWStr());
      //dataFile.print(" ");
      dataFile.print(rtc.getDateStr());
      dataFile.print(" ");
      dataFile.print(rtc.getTimeStr());
      dataFile.print(" ");

      dataFile.print("CPM: ");
      dataFile.print(counts / 10);
      dataFile.print(", uSv/hr: ");
      dataFile.print(uSv, 2);         // Log 2 decimal places
      dataFile.println();
      dataFile.close(); 
   }
    // If the file isn't open, pop up an error:
    else {
      Serial.println("error opening datalog.txt");
   }
    counts = 0;
 }
  delay(100);
}
Svilen

User avatar
Pavel M.
Posts: 11
Joined: 29 Feb 2020, 12:35
Contact:

Re: DIY GM Environmental Radiation Monitor

Post by Pavel M. » 09 May 2020, 21:47

Cool project Svilen!

I've built a few Geiger counters/monitoring stations in the past (also mostly based on Arduino), and these tube driver kits are indeed the simplest way to go. Sometimes, the output from Geiger tubes can be quite messy, so you have to use an external "pulse shaper", before you feed the signal to an Arduino. Otherwise it may miss some pulses or count fake ones. It's nice to see that there are pre-made kits with better design (like yours), so far I've only used a cheap one from Ebay, and my own designs built from scratch (both of which could be improved by a lot). I will probably attempt a very similar project, once I get a better tube, I'm looking for something bigger and more sensitive, for accurate background monitoring, the small ones (SBM-20, M4011, J305) just don't do the trick for me.

I think that using a RaspberryPi for a device like this would be a bit too overkill (Arduino will work just fine and with lower power consumption). I just like to keep my projects as simple as possible.

Btw, if you want to connect it to the Internet everywhere, you may try experimenting with a GSM SIM-card module, but I don't know how well that works, I've always used WiFi with my Arduinos.

Pavel
Location: Czech Republic
Equipment:
  • Spectrometer: Scintillix SCGS-01 v3.0
  • Probe: Scintillix 2.5" with 3" PMT

User avatar
Svilen
Posts: 184
Joined: 23 Sep 2016, 04:25
Location: Germany
Contact:

Re: DIY GM Environmental Radiation Monitor

Post by Svilen » 09 May 2020, 22:07

Hi Pavel,

Thank you for your reply. I would also like to congratulate you for your intelligent posts.
This DIY geiger kit seems really well made and works very well with the Arduino indeed. You may be interested in this tube here (I bet you can negotiate the price ~10Eur lower and then you'll have a good deal):
[dead link removed - Steven]

Next thing I will do is adding WiFi or Ethernet connectivity to this station, but at the moment it is not needed, so I keep it simple as you said.

Greetings,
Svilen

Post Reply

Who is online

Users browsing this forum: No registered users and 22 guests