Average cpm per hour with geiger

Dear all,
I'm trying to use a geiger tube counter with the Arduino mega board. I have used the code below that works correctly. However, I would like to implement a pulse count for one hour to obtain an average cpm during 60 minutes. I suppose may not be possible works with Millis since I have tried without success other conditions inside or outside the "if".
could someone help me with this.

Thanks in advanced...

Cesar

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


int geiger_input = 7;
long count = 0;
long cpmH = 0;
long countPerMinute = 0;
long timePrevious = 0;
long timePreviousMeassure = 0;
long time = 0;
long countPrevious = 0;
float radiationValue = 0.0;
long cpmM = 0;
void countPulse() { // Captures count of events from Geiger counter board
    count++;
}

   void setup(){
   pinMode(geiger_input, INPUT);
   digitalWrite(geiger_input,HIGH);
   interrupts(); 
   Serial.begin(19200);
   attachInterrupt(0,countPulse,FALLING);
   }

   void loop(){
   if (millis()-timePreviousMeassure > 60000){
    cpmM=1*count;
    radiationValue = cpmM * CONV_FACTOR;
    timePreviousMeassure = millis();
    Serial.print("cpmM = "); 
    Serial.print(cpmM,DEC);
    Serial.print(" - ");   
    Serial.print("uSv/h = ");
    Serial.println(radiationValue,4);      
    count = 0;
   }
   }

You need to also post the sketch you wrote that doesn't work. Otherwise we can only guess the error.

I'm surprised that the posted code works correctly, because there are a couple of fairly serious problems with it. You've been lucky so far!

  1. variables shared with interrupt routines must be declared "volatile", fixed as follows:
volatile long count = 0;
  1. Likewise, variables shared with interrupts must be protected from corruption by the interrupt, while it is being accessed by the main program. Do this by making a copy of the variable (with the interrupts turned off) before using it in the main program. Fixed as follows:
noInterrupts(); //off
long count_copy=count;
count=0; //reset count here, not later in the code
interrupts(); //back on
    cpmM=1*count_copy;  //why bother to multiply by "1"?

Hint: one hour in milliseconds is 3600000UL.

My difficulty here is how to make two counts happen simultaneously without interrupting the other. When I do,

if (millis()-timePreviousMeassure > 60000){
cpmS = sec_count;
.........
sec_count = 0;
}

the count starts again from zero. I can't use other if(Millis().....for 3600000

I never need this before, but I suppose that there is some rule or some way to do.

Hi UltraSeven,

if (millis()-timePreviousMeassure > 60000) means every 60 thousand milliseconds which is every 60 seconds = every minute.

You get the counts from one minute. To obtain an averaged value each hour you could add the counts of each minute to another variable and increment a second countervariable.

If this countervariable reaches value 60 one hour is over then calculate hour-average value.

This would result in a averaged value updated one every 60 minutes.

A floating average could be calculated with an array of 60 elements.
Whenever a minute is over actualise array-element of this minute.

If minute 3 is over MinuteCounts[3] = count
If minute 4 is over MinuteCounts[4] = count
etc. etc.

calculate hour-average by adding all 60 elements of the array.

best regards

Stefan

Hi Stefan,

Looks very easy. I will try.
Thanks a lot.

Also thanks to aarg and jremington for the observations.

Regards,

UltraSeven