Sigurthr
0
- Joined
- Dec 11, 2011
- Messages
- 4,364
- Points
- 83
I decided to work on an old pancake geiger counter I picked up a few years back. I did the circuitry repairs years ago but I never got around to making a computer interface for pulse counting/scaling. Today I rectified that.
I'm posting it here because it may be of use for our members for other applications. The program simply looks for >2.3V to 5V pulses on Arduino's Pin3 and flashes the built in led (and drives Pin13 HIGH for 33mS) every time there is a pulse. The program then tallies up all the pulses observed over the time period indicated in the SamplePeriod variable (which is in mS, so it is set by default to 60,000, or 1 minute) and displays this count via the built in Serial Monitor on the Arduino IDE program. If you adjust the SamplePeriod variable it will automatically correct for the time period and update the serial monitor display to display the correct time period. You'll have to push the code to the arduino any time yoiu make changes though, I didn't do live serial two way communication.
Sample applications would be RPM counter, Frequency Counter (set SamplePeriod to 1000), item counter, etc.
UPDATE: New version of counter program optimized for general pulse counting use with dead time compensation to prevent retriggering on a single pulse. Requires the user to input the expected pulse length in uS.
Also, here is a Geiger Counter Friendly version, which includes dosimetry data output and a cleaned up serial interface. Again, requires expected pulse length in uS and also requires CPM per uR/hr sensitivity for the GM tube used if accurate dosimetry data is to be expected.
I'm posting it here because it may be of use for our members for other applications. The program simply looks for >2.3V to 5V pulses on Arduino's Pin3 and flashes the built in led (and drives Pin13 HIGH for 33mS) every time there is a pulse. The program then tallies up all the pulses observed over the time period indicated in the SamplePeriod variable (which is in mS, so it is set by default to 60,000, or 1 minute) and displays this count via the built in Serial Monitor on the Arduino IDE program. If you adjust the SamplePeriod variable it will automatically correct for the time period and update the serial monitor display to display the correct time period. You'll have to push the code to the arduino any time yoiu make changes though, I didn't do live serial two way communication.
Sample applications would be RPM counter, Frequency Counter (set SamplePeriod to 1000), item counter, etc.
UPDATE: New version of counter program optimized for general pulse counting use with dead time compensation to prevent retriggering on a single pulse. Requires the user to input the expected pulse length in uS.
Code:
// Arduino Pulse Counter
// Written by Matt "Sigurthr" Giordano 7/17/14
// email me at Sigurthr@SigurthrEnterprises.com
// TTL input on Pin 3
// Indicator LED on Pin 13 (continuous above 30cps)
// Writes counts per SamplePeriod to Serial Monitor
// once every sample period.
// Set PulseDuration variable to incoming pulse length in uS.
// This code is released for free use and sharing.
// Please just cite the author (me!) upon reuse/republishing!
void setup(){
Serial.begin(9600);
Serial.println("Arduino Pulse Counter");
pinMode(3, INPUT);
pinMode(13, OUTPUT);
}
unsigned long X = 0;
unsigned long SamplePeriod = 60000; // in mS
unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
unsigned long LEDmillis = 0;
int timeperiod = (SamplePeriod / 1000); // converts mS to S
int PulseDuration = 100; // Pulse Duration in uS
boolean LEDstate = false;
void loop(){
currentMillis = millis();
if (digitalRead(3) == HIGH){
X = X + 1;
LEDstate = true;
LEDmillis = currentMillis;
delayMicroseconds(PulseDuration); // prevents multiple triggering on a single pulse
}
if (currentMillis - LEDmillis >= 33){ //keeps indicator LED on for 33mS
LEDstate = false;
digitalWrite(13,LOW);
}
switch (LEDstate){
case true:
digitalWrite(13,HIGH);
break;
case false:
digitalWrite(13,LOW);
break;
}
if (currentMillis - previousMillis >= SamplePeriod) {
previousMillis = currentMillis;
Serial.print("Counts per ");
Serial.print(timeperiod);
Serial.print(" seconds: ");
Serial.println(X);
X = 0;
}
}
Also, here is a Geiger Counter Friendly version, which includes dosimetry data output and a cleaned up serial interface. Again, requires expected pulse length in uS and also requires CPM per uR/hr sensitivity for the GM tube used if accurate dosimetry data is to be expected.
Code:
// Arduino Geiger Counter Scaler
// Written by Matt "Sigurthr" Giordano 7/17/14
// email me at Sigurthr@SigurthrEnterprises.com
// TTL input on Pin 3
// Indicator LED on Pin 13 (continuous above 30cps)
// Writes counts per SamplePeriod to Serial Monitor
// once every sample period.
// Set PulseDuration variable to incoming pulse length in uS.
// This code is released for free use and sharing.
// Please just cite the author (me!) upon reuse/republishing!
void setup(){
Serial.begin(9600);
Serial.println("Arduino Geiger Counter Scaler"); // Header for Serial Text
pinMode(3, INPUT); // Pin 3 TTL input
pinMode(13, OUTPUT); // Pin13 LED indicator output
}
//User Serviceable Variables
unsigned long SamplePeriod = 60000; // Sample Period in mS
int PulseDuration = 100; // Pulse Duration in uS
float GMsensitivity = 3; // GM Tube cpm per uR/hr
//Non-Serviceable Variables
unsigned long X = 0;
unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
unsigned long LEDmillis = 0;
int timeperiod = (SamplePeriod / 1000); // converts mS to S
boolean LEDstate = false;
float uRem;
void loop(){
currentMillis = millis();
if (digitalRead(3) == HIGH){
X = X + 1;
LEDstate = true;
LEDmillis = currentMillis;
delayMicroseconds(PulseDuration); // prevents multiple triggering on a single pulse
}
if (currentMillis - LEDmillis >= 33){ //keeps indicator LED on for 33mS
LEDstate = false;
digitalWrite(13,LOW);
}
switch (LEDstate){
case true:
digitalWrite(13,HIGH);
break;
case false:
digitalWrite(13,LOW);
break;
}
if (currentMillis - previousMillis >= SamplePeriod) {
previousMillis = currentMillis;
uRem = (float)X / (float)GMsensitivity;
Serial.print(X);
Serial.print("CPM, ");
Serial.print(uRem);
Serial.println("uR/hr");
X = 0;
}
}
Last edited: