Connect Geiger counter with Arduino and display

Hello,

i successful connect Arduino with display and get data from Geiger with software (Radiation Logger).
Now i want data from Geiger to be shown on display but i cannot figure out how to setup that…

I use simple serialdisplay code:

/*Serial Communication for Radiation Detector Arduino Compatible DIY Kit ver 2.01 or higher
* http://radiohobbystore.com/radiation-detector-geiger-counter-diy-kit-second-edition.html
* Allow to connect the kit to computer and use the kit with Radiation Logger PC software
* http://radiohobbystore.com/radiation-logger/
* This Arduino sketch written by Alex Boguslavsky RH Electronics; mail: support@radiohobbystore.com
* CPM counting algorithm is very simple, it just collect GM Tube events during presettable log period.
* For radiation monitoring station it's recommended to use 30-60 seconds logging period. Feel free to modify
* or add functions to this sketch. This Arduino software is an example only for education purpose without any
* warranty for precision radiation measurements. You are fully responsible for your safety in high
* radiation area!!
* --------------------------------------------------------------------------------------
* WHAT IS CPM?
* CPM (or counts per minute) is events quantity from Geiger Tube you get during one minute. Usually it used to 
* calculate a radiation level. Different GM Tubes has different quantity of CPM for background. Some tubes can produce
* about 10-50 CPM for normal background, other GM Tube models produce 50-100 CPM or 0-5 CPM for same radiation level.
* Please refer your GM Tube datasheet for more information. Just for reference here, SBM-20 can generate 
* about 10-50 CPM for normal background.
* --------------------------------------------------------------------------------------
* HOW TO CONNECT GEIGER KIT?
* The kit 3 wires that should be connected to Arduino UNO board: 5V, GND and INT. PullUp resistor is included on
* kit PCB. Connect INT wire to Digital Pin#2 (INT0), 5V to 5V, GND to GND. Then connect the Arduino with
* USB cable to the computer and upload this sketch. 
*/


#include <SPI.h>
#include <LiquidCrystal.h>
#define LOG_PERIOD 15000  //Logging period in milliseconds, recommended value 15000-60000.
#define MAX_PERIOD 60000  //Maximum logging period without modifying this sketch

unsigned long counts;     //variable for GM Tube events
unsigned long cpm;        //variable for CPM
unsigned int multiplier;  //variable for calculation CPM in this sketch
unsigned long previousMillis;  //variable for time measurement

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void tube_impulse(){       //subprocedure for capturing events from Geiger Kit
  counts++;
}

void setup(){             //setup subprocedure
  counts = 0;
  cpm = 0;
  multiplier = MAX_PERIOD / LOG_PERIOD;      //calculating multiplier, depend on your log period
  Serial.begin(9600);
  attachInterrupt(0, tube_impulse, FALLING); //define external interrupts 
   // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // initialize the serial communications:
  Serial.begin(9600);
}

void loop(){                                 //main cycle
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > LOG_PERIOD){
    previousMillis = currentMillis;
    cpm = counts * multiplier;
    
    Serial.print(cpm);
    counts = 0;
  }

///////////////////// LCD 
if (Serial.available()) {
    // wait a bit for the entire message to arrive
    delay(100);
    // clear the screen
    lcd.clear();
    // read all the available characters
    while (Serial.available() > 0) {
      // display each character to the LCD
      lcd.write(Serial.read());
    }


////////////////// LCD
}

}

can you get me some tips where to look or what i miss? :slight_smile:

thank you!

Not sure what the problem is besides it is not working how you want.

Are you sure that the LCD is wired to match the constructor?

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
lcd.write(Serial.read());

This might need to be

lcd.print(Serial.read());

Nope, i am getting -1 value all the time…

But, i think i made progress, i change code to:

#include <SPI.h>
#include <LiquidCrystal.h>
#define LOG_PERIOD 15000  //Logging period in milliseconds, recommended value 15000-60000.
#define MAX_PERIOD 60000  //Maximum logging period without modifying this sketch

unsigned long counts;     //variable for GM Tube events
unsigned long cpm;        //variable for CPM
unsigned int multiplier;  //variable for calculation CPM in this sketch
unsigned long previousMillis;  //variable for time measurement

int sievertPin = 13;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void tube_impulse(){       //subprocedure for capturing events from Geiger Kit
  counts++;
}

void setup(){             //setup subprocedure
  counts = 0;
  cpm = 0;
  multiplier = MAX_PERIOD / LOG_PERIOD;      //calculating multiplier, depend on your log period
  Serial.begin(9600);
  attachInterrupt(0, tube_impulse, FALLING); //define external interrupts 
   // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // initialize the serial communications:
  Serial.begin(9600);
}

void loop(){                                 //main cycle
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > LOG_PERIOD){
    previousMillis = currentMillis;
    cpm = counts * multiplier;
    
    Serial.print(cpm);
    counts = 0;
  }

///////////////////// LCD 
int sievertReading = analogRead(sievertPin);
lcd.print(sievertPin);

  delay(500);


////////////////// LCD
}

but now getting value “13” all the time…

int sievertPin = 13;

int sievertReading = analogRead(sievertPin);

pin 13 on an Uno is a digital pin not an analog input. Try using A0 to A5 for sievertPin.

lcd.print(sievertPin);

Prints the pin number assigned to sievertPin. You need:

lcd.print(sievertReading);

Unless you want to print the pin number.

ah yes, i miss that … but now i am not sure did i need analog or digital input :s
anyway i now getting 0 with code:

#include <SPI.h>
#include <LiquidCrystal.h>
#define LOG_PERIOD 15000  //Logging period in milliseconds, recommended value 15000-60000.
#define MAX_PERIOD 60000  //Maximum logging period without modifying this sketch

unsigned long counts;     //variable for GM Tube events
unsigned long cpm;        //variable for CPM
unsigned int multiplier;  //variable for calculation CPM in this sketch
unsigned long previousMillis;  //variable for time measurement

int sievertPin = 5;
int sievertReading = analogRead(sievertPin);

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void tube_impulse(){       //subprocedure for capturing events from Geiger Kit
  counts++;
}

void setup(){             //setup subprocedure
  counts = 0;
  cpm = 0;
  multiplier = MAX_PERIOD / LOG_PERIOD;      //calculating multiplier, depend on your log period
  Serial.begin(9600);
  attachInterrupt(0, tube_impulse, FALLING); //define external interrupts 
   // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
}

void loop(){                                 //main cycle
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > LOG_PERIOD){
    previousMillis = currentMillis;
    cpm = counts * multiplier;
    
    Serial.print(cpm);
    counts = 0;
      }
 // lcd
  lcd.setCursor(6, 1);
lcd.print(sievertReading);
  delay(500);

}

What does sievertReading represent? Pin 5 is also a digital pin so will not work with analogRead. Use digitalRead with a digital pin (like pin 5). The analog pins are A0 to A5. Also I don't think using analogRead before setup() is going to work right.

well, here is my setup: https://www.dropbox.com/s/65nb6zajs1cr4gr/IMG_20160414_224026.jpg?dl=0

Geiger have gnd, V and VIN pins. I dont know where to put VIN and dont know how to show value to display.

I made sievertpin mark for pin where Geiger is connected. I try analog and digital, but results are the same.

i am sorry for newbie questions, but this is my first project with arduino, i just start to learn :)

well, here is my setup: https://www.dropbox.com/s/65nb6zajs1cr4gr/IMG_20160414_224026.jpg?dl=0

We take a dim view here when links are posted requiring us to sign up to things. Please post the pictures correctly. If you don't know how to do this then please read this:- How to use this forum

well you dont need, just click on X which he shows, but its fine with me to upload, no problem.
i am sorry.

OK I see what is going on. Connect 5V to Arduino 5V, Gnd to Arduino gnd and Vin to pin 2 on the Arduino.

Try this code. It compiles. but I can’t test it. It should show something on the LCD and serial monitor. It will take 15 seconds for the first reading and will read every 15 seconds. Note that the counts variable is made volatile for use in the ISR.

#include <Wire.h>
#include <LiquidCrystal.h>
#define LOG_PERIOD 15000  //Logging period in milliseconds, recommended value 15000-60000.
#define MAX_PERIOD 60000  //Maximum logging period without modifying this sketch

// variables used in an ISR (Interrupt Service Routine) need to be volatile
volatile unsigned long counts;     //variable for GM Tube events
unsigned long cpm;        //variable for CPM

// 4 15 second periods in one minute
unsigned int multiplier = MAX_PERIOD / LOG_PERIOD;  //variable for calculation CPM in this sketch

unsigned long previousMillis;  //variable for time measurement

//int sievertPin = 5;
//int sievertReading = analogRead(sievertPin);

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void tube_impulse(){       //subprocedure for capturing events from Geiger Kit
  counts++;
}

void setup()
{             //setup subprocedure
  counts = 0;
  cpm = 0;
  multiplier = MAX_PERIOD / LOG_PERIOD;      //calculating multiplier, depend on your log period
  Serial.begin(9600);
  attachInterrupt(0, tube_impulse, FALLING); //define external interrupts
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
}

void loop()
{                                 //main cycle
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > LOG_PERIOD)  // LOG_PERIOD = 15 seconds
  {
    previousMillis = currentMillis;
    cpm = counts * multiplier;          // counts for 15 seconds * 4 = cpm
    Serial.print(cpm);
    lcd.clear();
    lcd.setCursor(6, 1);    
    lcd.print(cpm);
    counts = 0;    
  }
}

groundfungus, thank you for support. I put this code and now i got on first screen 12 and after that always 0 You mean by pin 2, RX pin? and how to decrees timing to ... 2 second for example?

Pin 2 is the pin for the external interrupt 0. It is the physical pin 3 of the chip.

This line registers the interrupt

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

This is the ISR (Interrupt Service Routine). Each time a tick comes from the Geiger counter the count increments.

void tube_impulse(){       //subprocedure for capturing events from Geiger Kit
  counts++;
}

A quote from your first post:

Some tubes can produce about 10-50 CPM for normal background, other GM Tube models produce 50-100 CPM or 0-5 CPM for same radiation level. * Please refer your GM Tube datasheet for more information. Just for reference here, SBM-20 can generate * about 10-50 CPM for normal background.

So you may need to increase the sample time to be able to see the background radiation if your tube is a 0-5 CPM background tube. The sample period is set with the LOG_PERIOD constant at the top of the program. It is set to 15000 (15 seconds), but can be changed if you want.

With this, i get on start value 90 and after that always 0.

but, now is more clear about log period.

Ok, my tube is M4011 and have conversion index 151.
So if the counter number is 30 CPM, the radiation is also: (30/151) µSv/h=0.1987 µSv/h

I change code to:

#include <Wire.h>
#include <LiquidCrystal.h>
#define LOG_PERIOD 2000  //Logging period in milliseconds, recommended value 15000-60000.
#define MAX_PERIOD 60000  //Maximum logging period without modifying this sketch

// variables used in an ISR (Interrupt Service Routine) need to be volatile
volatile unsigned long counts;     //variable for GM Tube events
unsigned long cpm;        //variable for CPM

// 4 15 second periods in one minute
unsigned int multiplier = MAX_PERIOD / LOG_PERIOD;  //variable for calculation CPM in this sketch

unsigned long previousMillis;  //variable for time measurement

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void tube_impulse(){       //subprocedure for capturing events from Geiger Kit
  counts++;
}

void setup()
{             //setup subprocedure
  counts = 0;
  cpm = 151;
  multiplier = MAX_PERIOD / LOG_PERIOD;      //calculating multiplier, depend on your log period
  Serial.begin(9600);
  attachInterrupt(0, tube_impulse, FALLING); //define external interrupts
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
    }

void loop()
{                                 //main cycle
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > LOG_PERIOD)  // LOG_PERIOD = 2 seconds
  {
    previousMillis = currentMillis;
    cpm = counts * multiplier;          // counts for 15 seconds * 4 = cpm

    Serial.print(cpm);
   lcd.clear();
    lcd.setCursor(6, 1);    
    lcd.print(cpm);
  // counts = 0;    
  }
}

Well now i getting random values, seems that he just increasing number for 30…
What is counts at the end of script represent?

After each LOG_PERIOD the counts variable needs to be set back to zero so it can accumulate a new count of ticks.

hi groundfungus again :slight_smile:
sorry for this long delay… :slight_smile:

I am in problem with free time…

So, i still this do not understand…
Whatever i do he always + numbers…

here is little diffrnet code from above, he always adding ~30 on results:

#include <Wire.h>
#include <LiquidCrystal.h>
#define LOG_PERIOD 2000  //Logging period in milliseconds, recommended value 15000-60000.
#define MAX_PERIOD 60000  //Maximum logging period without modifying this sketch

// variables used in an ISR (Interrupt Service Routine) need to be volatile
volatile unsigned long counts;     //variable for GM Tube events
unsigned long cpm;        //variable for CPM

// 4 15 second periods in one minute
unsigned int multiplier = MAX_PERIOD / LOG_PERIOD;  //variable for calculation CPM in this sketch

unsigned long previousMillis;  //variable for time measurement

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void tube_impulse(){       //subprocedure for capturing events from Geiger Kit
  counts++;
}

void setup()
{             //setup subprocedure
  counts = 0;
  cpm = 151;
  multiplier = MAX_PERIOD / LOG_PERIOD;      //calculating multiplier, depend on your log period
  Serial.begin(9600);
  attachInterrupt(0, tube_impulse, FALLING); //define external interrupts
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
    }

void loop()
{                                 //main cycle
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > LOG_PERIOD)  // LOG_PERIOD = 2 seconds
  {
    previousMillis = currentMillis;
    cpm = counts * multiplier;          // counts for 15 seconds * 4 = cpm

    Serial.print(cpm);
   lcd.clear();
    lcd.setCursor(6, 1);    
    lcd.print(cpm);
  // counts = 0;    
  }
}

because this is for now only project which i will work with arduino, i just want to make it work… :slight_smile:

thank you for all your time.

i found new code, but no luck … :confused:

// include the library code:

#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);


// Threshold values for the led bar
#define TH1 45
#define TH2 95
#define TH3 200
#define TH4 400
#define TH5 600

// Conversion factor -  to uSV/h
#define CONV_FACTOR 0.00151

// Variables
int ledArray [] = {10,11,12,13,9};
int geiger_input = 7;
long count = 0;
long countPerMinute = 0;
long timePrevious = 0;
long timePreviousMeassure = 0;
long time = 0;
long countPrevious = 0;
float radiationValue = 0.0;



void setup(){
  pinMode(geiger_input, INPUT);
  digitalWrite(geiger_input,HIGH);
  for (int i=0;i<5;i++){
    pinMode(ledArray[i],OUTPUT);
  }

  Serial.begin(19200);

  //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 - Arduino");  
  delay(2000);

  lcd.clear();  
  lcd.setCursor(0, 0);
  lcd.print("CPM=");
  lcd.setCursor(4,0);
  lcd.print(6*count);
  lcd.setCursor(0,1);
  lcd.print(radiationValue);

  attachInterrupt(0,countPulse,FALLING);

}

void loop(){
  if (millis()-timePreviousMeassure > 10000){
    countPerMinute = 6*count;
    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(0,1);
    lcd.print(radiationValue,4);
    lcd.setCursor(6,1);
    lcd.print(" uSv/h");

    //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;

  }

}

void countPulse(){
  detachInterrupt(0);
  count++;
  while(digitalRead(7)==0){
  }
  attachInterrupt(0,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);
    }
  }
}[

always getting the same (starting with cpm 6 and usv/h 0.0091 when i turned on):

cpm = 6 - uSv/h = 0.0091
cpm = 0 - uSv/h = 0.0000
cpm = 0 - uSv/h = 0.0000
cpm = 6 - uSv/h = 0.0091
cpm = 0 - uSv/h = 0.0000
cpm = 0 - uSv/h = 0.0000
cpm = 0 - uSv/h = 0.0000
cpm = 0 - uSv/h = 0.0000
cpm = 0 - uSv/h = 0.0000
cpm = 0 - uSv/h = 0.0000
cpm = 0 - uSv/h = 0.0000

Your previous code is so much simpler. I think you should try to get it working before trying anything else. You commented out the line that resets counts, that is why it was accumulating.
How do you know, for sure, that the Geiger tube is putting counts (ticks) out?
What is the specification for counts per minute for normal background radiation for your tube?
if the normal background ticks is 5 counts per minute, how many counts for 2 seconds?

Try this code. It will take a reading every 30 seconds, increasing the chances of getting a number of counts.
I uncommented the reset of counts so it should not accumulate.

Again, make sure that the Geiger tube is actually outputting counts or no amount of code will work.

#include <Wire.h>
#include <LiquidCrystal.h>
#define LOG_PERIOD 30000  //Logging period in milliseconds, recommended value 15000-60000.
#define MAX_PERIOD 60000  //Maximum logging period without modifying this sketch

// variables used in an ISR (Interrupt Service Routine) need to be volatile
volatile unsigned long counts;     //variable for GM Tube events
unsigned long cpm;        //variable for CPM

// 2 30 second periods in one minute
unsigned int multiplier = MAX_PERIOD / LOG_PERIOD;  //variable for calculation CPM in this sketch

unsigned long previousMillis;  //variable for time measurement

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void tube_impulse(){       //subprocedure for capturing events from Geiger Kit
  counts++;
}

void setup()
{             //setup subprocedure
  counts = 0;
  cpm = 151;
  multiplier = MAX_PERIOD / LOG_PERIOD;      //calculating multiplier, depend on your log period
  Serial.begin(9600);
  attachInterrupt(0, tube_impulse, FALLING); //define external interrupts
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
}

void loop()
{                                 //main cycle
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > LOG_PERIOD)  // LOG_PERIOD = 30 seconds
  {
    previousMillis = currentMillis;
    cpm = counts * multiplier;          // counts for 30- seconds * 2 = cpm

    Serial.print(cpm);
    lcd.clear();
    lcd.setCursor(6, 1);
    lcd.print(cpm);
    counts = 0;        // you must  reset  counts to zero or counts will accumulate
  }
}

Well agree with you. Oh, maybe in many combinations, i left commented ...

Well i hear, see the led blinking on it and when i connect him via stereo 3.5mm with application on android or windows, seems that he working proper.. Now idea is to join with Arduino, display and make a case for it.

In specification for this tube says that cpm is 151 (M4011 GM tube).

this code shows first 6 and rest all 0...

I was looking over prior posts and saw a mistake on my part. Interrupt 0 is on pin D2 or physical (chip) pin 4.

hm, but i cannot connect to that pin because that is connected with LCD. can i use different pin ? https://arduino-info.wikispaces.com/file/view/ArduinoUNO-900.jpg/421496636/ArduinoUNO-900.jpg

here is my setup: https://cloud.nisam.video/owncloud/index.php/s/Cm8BuK6Cz5G0vPK

yelow one is from Geiger ..