/*******************************************************************************************
geiger counter nano OLED 1 sw 2 leds voltmeter v2.12
Created Steve Barth Hungary 2021.
arduino nano and 128*32 oled display
GM detector counts, CPM, Dose meter, voltmeter, Warning, Danger led's, oled display
********************************************************************************************/
#include <Arduino.h>
#include <Wire.h> // wire library for I2C
#include <Adafruit_GFX.h> // grafical library for OLED
#include <Adafruit_SSD1306.h> // special library for SSD1306 driver
#include <SPI.h>
#include <Fonts/FreeSansBold9pt7b.h>
#include <Fonts/FreeSansBoldOblique9pt7b.h>
# define LOG_PERIOD 1000 // Logging period in milliseconds, recommended value 15000-60000.
# define MAX_PERIOD 60000 // Maximum logging period
# define pin_Tick 2 // connecting GM pulse // GPIO2
# define RED_LED 5 // danger led // GPIO5
# define YELLOW_LED 4 // warning led // GPIO4
# define Tick_out 13 // Tick output // GPIO6
// todo only required for software testing, in practice it is sufficient to select the external or internal reference voltage
#define v_ref 1.1; // external reference voltage LM4040 2.048V, internal v_ref=1.1V
// variables
unsigned long counts; // for GM pulse
unsigned long cpm; // for CPM
unsigned int multiplier; // for multiplier
unsigned long previousMillis; // for time
float usv; // container for uSv calculating
int conversion_factor; // GM tube special data
// OLED init
#define OLED_RESET 12 // GPIO13 (led control)
Adafruit_SSD1306 oled(128, 32, & Wire, OLED_RESET);
//const unsigned char radiation 32x32 bw logo1 pngtobmp32 [] =
static const unsigned char PROGMEM radiation_bmp[] =
{
0x00, 0x03, 0xC0, 0x00, 0x00, 0x3E, 0x7C, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x03, 0x80, 0x01, 0x80,
0x06, 0x00, 0x00, 0x60, 0x0C, 0x80, 0x03, 0x30, 0x1B, 0xC0, 0x03, 0x90, 0x13, 0xE0, 0x07, 0xC8,
0x27, 0xE0, 0x07, 0xEC, 0x2F, 0xF0, 0x0F, 0xF4, 0x4F, 0xF8, 0x1F, 0xF6, 0x5F, 0xF8, 0x1F, 0xFA,
0x5F, 0xF8, 0x3F, 0xFA, 0xDF, 0xF9, 0x9F, 0xFA, 0x9F, 0xF3, 0xCF, 0xFA, 0x9F, 0xF7, 0xEF, 0xFB,
0x80, 0x07, 0xE0, 0x03, 0xC0, 0x03, 0xC0, 0x02, 0x40, 0x01, 0x80, 0x02, 0x40, 0x00, 0x00, 0x02,
0x40, 0x07, 0xE0, 0x02, 0x60, 0x0F, 0xE0, 0x06, 0x20, 0x0F, 0xF0, 0x04, 0x30, 0x1F, 0xF8, 0x0C,
0x10, 0x1F, 0xF8, 0x08, 0x08, 0x3F, 0xFC, 0x10, 0x0C, 0x7F, 0xFE, 0x30, 0x06, 0x7F, 0xFE, 0x60,
0x01, 0x9F, 0xF9, 0x80, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x3F, 0xFC, 0x00, 0x00, 0x03, 0xC0, 0x00
};
// counting GM tube impulse
void tick()
{
counts++;
}
//**************************** Setup *************************************//
void setup()
{
Serial.begin(9600);
analogReference(EXTERNAL); // external voltage reference
//analogReference(INTERNAL); // internal voltage reference 1,1V
// pins settings
pinMode(RED_LED, OUTPUT);
pinMode(YELLOW_LED, OUTPUT);
pinMode(Tick_out, OUTPUT);
digitalWrite(Tick_out,LOW);
pinMode(pin_Tick, INPUT_PULLUP);
// OLED setting
delay(50); // This delay is needed to let the oled to initialize
oled.begin(SSD1306_SWITCHCAPVCC, 0x3D); // OLED oled initialize 128x64 pixel, if 0x03C 128x32 pixel
// basic settings
counts = 0; // counts reset
cpm = 0; // cpm reset
multiplier = MAX_PERIOD / LOG_PERIOD; // Calculate the multiplier as a function of time
attachInterrupt(0, tick, FALLING); // interrupt from GM tube pulse
conversion_factor = 540; // setting GM tube conversion factor (151 ~ basic: SBM-19; LND 71917 ~ 540)
// OLED boot screen
/*
oled.clearDisplay();
oled.display();
delay(200);
oled.drawBitmap(0, 0, NTI_logo, 128, 32, WHITE);
oled.display();
delay(200);
*/
oled.clearDisplay();
delay(100);
oled.setTextColor(WHITE);
oled.setTextSize(1);
oled.setCursor(34, 6); // cursor position
oled.print("GM counter"); // screen counts
oled.display();
delay(600);
oled.setCursor( 22, 21); // cursor position
oled.print("by Steve Barth"); // screen counts
oled.display();
delay(1500);
oled.clearDisplay();
delay(800);
oled.setCursor( 30, 12); // cursor position
oled.print("sw ver:2.12"); // screen counts
oled.display();
delay(800);
oled.clearDisplay();
delay(500);
oled.setCursor( 54, 24); // cursor position
oled.print("2022"); // screen counts
oled.display();
delay(600);
oled.clearDisplay();
delay(100);
}
//********************************* Loop **********************************//
void loop()
{
digitalWrite(YELLOW_LED, LOW);
digitalWrite(RED_LED, LOW);
if (digitalRead(pin_Tick) == 0) // read pin
{
digitalWrite(Tick_out, HIGH); // output state high
oled.fillCircle(56, 15, 6, WHITE); // draw circle in screen
oled.fillCircle(56, 15, 3, BLACK);
oled.display();
delay(100); // pause in millisecundum
digitalWrite(Tick_out, LOW); // output state low
oled.fillCircle(56, 15, 5, BLACK); // clear circle in screen
oled.fillCircle(56, 15, 3, WHITE);
oled.fillCircle(56, 15, 2, BLACK);
oled.fillCircle(56, 15, 1, WHITE);
oled.display();
}
/* calculating oled data*/
unsigned long currentMillis = millis();
if (currentMillis - previousMillis > LOG_PERIOD)
{
previousMillis = currentMillis;
cpm = counts * multiplier; // counts -> calculating CPM
usv = float(cpm) / conversion_factor; // cpm -> calculatig uSh
// ****************** screen display data ***************************//
// OLED display
/*
// segment number display
oled.setFont(&FreeSansBoldOblique9pt7b);
oled.setCursor(0,14); // (0,25)
oled.print("12unit");
delay(0.1);
oled.setFont();
*/
oled.display();
oled.clearDisplay();
oled.setTextColor(WHITE);
oled.setTextSize(1);
// display counts data // if log_period = 1000ms, else oled "cps"
oled.setCursor(2, 1); // cursor position
oled.print("cps: "); // screen counts
oled.print(counts * 195); // counts data */
/*
// display cpm data
oled.setCursor(2, 13); // cursor position
oled.print("CPM:"); // screen cpm
oled.print(cpm); // cpm data */
// display uSv data
/*
oled.setCursor(2, 12); // cursor position
oled.print(usv); // uSv data
oled.print("uSv/h"); // screen uSv */
// display counts data
oled.setCursor(1, 12); // cursor position
oled.print("counts->"); // screen cpm
//oled.print(cpm); // cpm data */
// GM detector tube voltmeter
int V_input=analogRead(0); // measurment voltage A0 input reading
float voltage = V_input * v_ref; // converting that reading to voltage, which is based off the reference voltage
voltage /= 1023 ;
oled.setCursor(2,24);
oled.print(voltage *1000);
oled.println(" V"); // print out the value you read:
/*
// if counts -> normal, warning, danger range oled setting
// normal
if (counts < 300)
{
oled.drawRoundRect(72,0,55,32,6,WHITE);
oled.setTextSize(1);
oled.setCursor(82,12);
oled.print("safety");
delay(0.1);
}
// Warning
else if (counts < 600 && counts >= 300)
{
oled.drawRoundRect(72,0,55,32,6,WHITE);
oled.setTextSize(1);
oled.setCursor(80,12);
oled.print("warning");
delay(0.1);
}
// Danger!
else if (counts >= 600)
{
oled.fillRoundRect(72,0,55,32,6,WHITE);
oled.setTextColor(BLACK);
oled.setTextSize(1);
oled.setCursor(80,12);
oled.print("DANGER!");
delay(0.1);
}
counts = 0; // counts reset
*/
// if CPM -> normal, warning, danger range oled setting
if (cpm < 80)
{
// SAFE oled
oled.drawRoundRect(64,0,64,32,0,WHITE);
oled.setFont(&FreeSansBold9pt7b);
oled.setCursor(73,21);
oled.print("SAFE");
delay(100);
oled.setFont();
}
else if (cpm < 200 && cpm >= 80)
{
// WARNING oled
oled.drawRoundRect(64,0,64,32,8,WHITE);
oled.drawRoundRect(65,1,62,30,3,WHITE);
oled.setFont(&FreeSansBoldOblique9pt7b);
oled.setCursor(66,21);
oled.print("WARN");
digitalWrite(YELLOW_LED, HIGH); // yellow led on
delay(250);
oled.setFont();
}
else if (cpm >= 200)
{
// DANGER oled
oled.fillRoundRect(72,0,49,32,20,WHITE); // or this rect
oled.drawBitmap(81, 0, radiation_bmp, 32, 32, BLACK); // and bitmap
digitalWrite(RED_LED, HIGH); // red led on
delay(250);
oled.setFont();
}
counts = 0; // counts reset
/*
// if (OLED) Counts -> normal, warning, danger range oled setting
if (counts >= 10000)
{
pinMode(RED_LED) HIGH; //danger red led on
delay(0.1);
}
else if (counts < 10000 && counts >= 5000)
{
pinMode(YELLOW_LED) HIGH; //warning yellow led on
delay(0.1);
}
else if (counts < 5000)
{
pinMode(RED_LED) LOW; //danger red led off
pinMode(YELLOW_LED) LOW; //warning yellow led off
}
counts = 0; // counts reset
*/
}
}
nano:12
nano:11
nano:10
nano:9
nano:8
nano:7
nano:6
nano:5
nano:4
nano:3
nano:2
nano:GND.2
nano:RESET.2
nano:0
nano:1
nano:13
nano:3.3V
nano:AREF
nano:A0
nano:A1
nano:A2
nano:A3
nano:A4
nano:A5
nano:A6
nano:A7
nano:5V
nano:RESET
nano:GND.1
nano:VIN
nano:12.2
nano:5V.2
nano:13.2
nano:11.2
nano:RESET.3
nano:GND.3
r1:1
r1:2
r2:1
r2:2
oled1:DATA
oled1:CLK
oled1:DC
oled1:RST
oled1:CS
oled1:3V3
oled1:VIN
oled1:GND
btn2:1.l
btn2:2.l
btn2:1.r
btn2:2.r
rgb1:R
rgb1:COM
rgb1:G
rgb1:B
rgb2:R
rgb2:COM
rgb2:G
rgb2:B
pot1:GND
pot1:SIG
pot1:VCC