/* Geiger counter monitor. Displays current Counts Per Minute (CPM) and maximum CPM since startup. Time isn't kept, so if there's a peak we won't know when it happened State change detection (edge detection) from http://www.arduino.cc/en/Tutorial/ButtonStateChange Geiger counter trigger is 12V, so use an opto coupler for isolation. */ #include unsigned long DELAY_TIME = 60000; // 60 seconds initial period unsigned long keeplit = 500; // .5 second before counter light is turned off millisDelay ledDelay; millisDelay lightout; #include LiquidCrystal_I2C lcd(0x3F, 16, 2); // set the LCD I2C address ( probably 0x27 or 0x3F ) int screenWidth = 16; // Screen width (in characters) int screenHeight = 2; // Screen height (in characters) int maxCPM = 0; String msg; // this constant won't change: const int buttonPin = 2; // the pin to which the geiger counter trigger is attached byte block[8] = { B11111, B11111, B11111, B11111, B11111, B11111, B11111, }; int buttonPushCounter = 0; // counter for the number of button presses int buttonState = 0; // current state of the button int lastButtonState = 0; // previous state of the button bool lightisout = true; void setup() { // initialize the button pin as an input - pulse from geiger counter: pinMode(buttonPin, INPUT); // initialize serial communication: Serial.begin(115200); // set the countdown timer ledDelay.start(DELAY_TIME);// reset the countdown timer Serial.println(); Serial.println("==========================================="); Serial.println("Geiger counter, ticks per minute (.5 mR/hr)"); Serial.println("==========================================="); lcd.init(); // initialize the lcd lcd.begin(screenWidth, screenHeight); // Print a message to the LCD. lcd.clear(); lcd.backlight(); lcd.createChar(1, block); // character 1 for solid block lcd.setCursor(0, 0); lcd.print(" Alisdair's"); lcd.setCursor(0, 1); lcd.print(" Rad. monitor"); delay(1000); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Rad. monitor"); } void loop() { while (ledDelay.remaining() > 0 ) { // 60 second countdown // read the trigger pin: if ( lightout.remaining() == 0 && lightisout == false ) { lcd.setCursor(15, 0); lcd.print(' '); // clear solid block lightisout = true; // don't want to continually write to the display } buttonState = digitalRead(buttonPin); // compare the buttonState to its previous state if (buttonState != lastButtonState) { // increment the counter if the state has changed if (buttonState == HIGH) { // if the current state is HIGH then the button went from off to on: buttonPushCounter++; lcd.setCursor(15, 0); lcd.write(1); // solid block for a tick // keep the block lit for a minimum period, but keep counting the ticks lightout.start(keeplit);// reset the countdown timer for the indicator. lightisout = false; // Serial.print("."); // write to console msg = "CPM " + String(buttonPushCounter) + " Max " + String(maxCPM) + " "; Serial.println(msg); lcd.setCursor(0, 1); lcd.print(msg); } } // save the current state as the last state, for next time through the loop lastButtonState = buttonState; } Serial.println(buttonPushCounter); if (buttonPushCounter > maxCPM ) { maxCPM = buttonPushCounter; } msg = "CPM " + String(buttonPushCounter) + " Max " + String(maxCPM) + " "; Serial.println(msg); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Rad. monitor"); lcd.setCursor(0, 1); lcd.print(msg); buttonPushCounter = 0; ledDelay.start(DELAY_TIME);// reset the countdown timer }