/*************************************************************************************************-**********
                    GM detector tube tester ver.2.95
    Oled display pulse counter, can be started with a start button, with a measurement time of 10 seconds.
                Created by Steve Barth BME-NTI January 2022
                    VS Code Version: 1.63.2 (user setup)
            https://wokwi.com/projects/322136496449520210
        RAM:   [===       ]  34.4% (used 705 bytes from 2048 bytes)
        Flash: [========= ]  85.5% (used 26272 bytes from 30720 bytes)

************************************************************************************************************/

//* declaration
#include <Arduino.h>                            // only for VS Code
#include <SPI.h>                                // Serial Peripheral Interface (SPI) library
#include <Adafruit_GFX.h>                       // GFX library
#include <Adafruit_SSD1306.h>                   // oled driver library
#include <Wire.h>                               // TWI/I2C library
#include <Fonts/FreeSansBold9pt7b.h>            // use font
#include <Fonts/FreeSans9pt7b.h>                // use font
#include <Fonts/FreeSansBoldOblique9pt7b.h>

//* OLED init
#define OLED_RESET 12                                         // GPIO12 (led control)
Adafruit_SSD1306 oled(128, 64, &Wire, OLED_RESET);            // oled display config

//* connected
#define v_ref 1.1                 // external reference voltage LM4040 2.048V, internal v_ref=1.100V
#define start_Sw 4                 // connect start switch
const int pulse_In = 12;            // This is pulse input pin

//* data type
long startTime;                // data type for starting time
long pulse;                    // variable pulse count
int timerMode = 0;             // start state for timer mode
int count_mode = 0;            // start state counting mode

//****************************   Setup   *************************************//

void setup()
{
  //* OLED DISPLAY SETTINGS
  oled.begin(SSD1306_SWITCHCAPVCC, 0x3D);             // OLED oled initialize 128x64 pixel, if 0x03C 128x32 pixel
  delay(200);                                         // This delay is needed to let the oled to initialize
  oled.clearDisplay();                                // screen clear

  //* START DISPLAY
  oled.drawRoundRect(2, 0, 124, 62, 5, WHITE);    // white frame
  oled.setTextColor(WHITE);                       // set text color
  oled.setFont(&FreeSansBold9pt7b);               // set font type
  oled.setTextSize(1);                            // set font size
  oled.setCursor(12, 18);                         // cursor position
  oled.print("GM detector");                      // text on the display
  oled.setCursor(5, 36);                          // cursor position
  oled.print("pulse counter");                    // text on the display
  oled.display();                                 // display on the screen
  delay(500);                                    // pause
  oled.setFont();                                 // set font default
  oled.setTextSize(1);                            // set font size
  oled.setCursor(8, 46);                         // cursor position
  oled.print("Made by Steve Barth");                   // text on the display
  oled.display();                                 // display on the screen
  delay(1000);                                    // pause
  oled.clearDisplay();                            // screen clear
  oled.setFont(&FreeSans9pt7b);                   // set font type
  oled.setTextSize(1);                            // set text size
  oled.setCursor(27, 20);                         // cursor position
  oled.print("BME-NTI");                          // text on the display
  oled.display();                                 // display on the screen
  delay(500);                                    // pause
  oled.setCursor(43, 41);                         // cursor position
  oled.print("2022");                             // text on the display
  oled.display();                                 // display on the screen
  delay(500);                                    // pause
  oled.setFont();                                 // set font default
  oled.setTextSize(1);                            // set font size
  oled.setCursor(29, 50);                         // cursor position
  oled.print("SW ver. 2.95");                     // text on the display
  oled.display();                                 // display on the screen
  delay(500);                                    // pause
  oled.clearDisplay();                            // screen clear

  //* SERIAL MONITOR & Vref SETTINGS
  Serial.begin(9600);                   // serial monitor set
  analogReference(EXTERNAL);            // ! external voltage reference Wokwi Reverse!
  //analogReference(INTERNAL);          // ! internal voltage reference 1,1V Wokwi Reverse!

  //* PIN SETTINGS
  pinMode(start_Sw, INPUT_PULLUP);            // start switch input pin
  pinMode(pulse_In, INPUT_PULLUP);            // set input pin
}

//*********************************   Loop   **********************************//

void loop()
{
  // COUNTING OF DETECTING PULSES
  if (digitalRead(pulse_In) != count_mode)            // when a pulse is received
  {
    delay(10);
    count_mode = 1;            // start counting
    pulse++;                   // increase the number
  }

  if (digitalRead(pulse_In) == 0)            // if no pulse input
  {
    count_mode = 0;            // stop counting
  }

  // WHEN A START SIGNAL RECEIVED
  if (digitalRead(start_Sw) == LOW)            // if start switch impuls (high-low-high)
  {
    delay(200);                                          // delay for no bounce
    startTime = millis();                                // starttime settings
    timerMode++;                                         // increase the timermode status
  }

  // STAND-BY STATE
  if (timerMode == 0)            // if timermode "0" status
  {
    pulse = 0;            // all detected pulse reset

    oled.clearDisplay();                            // screen clear
    oled.drawRoundRect(2, 0, 124, 62, 5, WHITE);    // create frame
    oled.setTextColor(WHITE);                       // set text color
    oled.setFont(&FreeSansBoldOblique9pt7b);        // set font type
    oled.setTextSize(1);                            // set font size
    oled.setCursor(23, 18);                         // cursor position
    oled.print("Press the");                        // text on the display
    oled.setCursor(12, 36);                         // cursor position
    oled.print("start button");                     // text on the display
    oled.setFont();                                 // set font default
    oled.setTextSize(1);                            // set font size
    oled.drawLine(7, 42, 120, 42, WHITE);           // create line


    // GM TUBE VOLTMETER
    int V_input = analogRead(0);                      // measurment voltage A0 input reading
    float voltage = (V_input * v_ref) / 1023;                  // converting that reading to voltage, which is based off the reference voltage
    oled.setCursor(6, 48);                           // cursor position
    oled.print("High Voltage:");                      // text on the display
    oled.setCursor(83, 48);                           // cursor position
    char string[7];                                   // string max 6 digit (0000.0)
    dtostrf(voltage * 1000, 4, 1, string);            // convert data to string (0000), dtostrf(FLOAT,WIDTH,PRECSISION,BUFFER)
    oled.print(string);                               // screen data
    oled.print("V");                                 // text on the display
    oled.display();                                   // display on the screen

  }

  // START TIME OF THE MEASUREMENT
  if (timerMode == 1)            // if timermode status 1
  {
    // TIME DISPLAY
    oled.clearDisplay();                              // screen clear
    oled.drawRoundRect(4, 1, 120, 45, 4, WHITE);      // create frame
    oled.setFont();                                   // set font default
    oled.setTextSize(1);                              // set font size
    oled.setCursor(20, 5);                            // cursor position
    oled.print("THE MEASUREMENT");                    // text on the display
    oled.setCursor(52, 16);                           // cursor position
    oled.print("TIME:");                              // text on the display
    oled.setFont(&FreeSansBold9pt7b);                 // set font type
    oled.setTextSize(1);                              // set font size
    oled.setCursor(30, 39);                           // cursor position
    oled.print((millis() - startTime) / 1000.0);      // time on the display
    oled.setCursor(70, 39);                           // cursor position
    oled.print("sec.");                               // text on the display

    // PULSE COUNTING
    oled.setFont();                                   // set font default
    oled.setTextSize(1);                              // set font size
    oled.setCursor(55, 52);                           // cursor position
    oled.print("pulse:");                             // text on the display
    oled.print(pulse / 2);                            // text on the display

    // GM TUBE VOLTMETER
    int V_input = analogRead(0);                      // measurment voltage A0 input reading
    float voltage = (V_input * v_ref) / 1023;                  // converting that reading to voltage, which is based off the reference voltage
    oled.setCursor(4, 52);                            // cursor position
    oled.print("HV:");                                // text on the display
    oled.setCursor(20, 52);                           // cursor position
    char string[6];                                   // string max 6 digit (0000.0)
    dtostrf(voltage * 1000, 4, 0, string);            // convert data to string (0000), dtostrf(FLOAT,WIDTH,PRECSISION,BUFFER)
    oled.print(string);                               // screen data
    oled.print("V");                                  // text on the display
    oled.display();                                   // display on the screen


    // SETTING THE MEASUREMENT TIME
    if ((millis() - startTime) >= 10000)            // stoptime max.: 10 sec
    {
      timerMode++;            // increase the timermode status
    }
  }

  if (timerMode > 1)            // if timermode status bigger 1
  {
    // COUNTING RESULT
    delay(50);
    oled.clearDisplay();                        // screen clear
    oled.setFont(&FreeSansBold9pt7b);           // set font type
    oled.setTextSize(1);                        // set font size
    oled.setCursor(16, 20);                     // cursor position 32,31
    oled.print("All counts:");                  // text on the display
    oled.fillRoundRect(4, 30, 120, 23, 4, WHITE); // 4,39,120,23,4,WHITE
    oled.setTextColor(BLACK);                   // set text color
    oled.setCursor(28, 47);                     // cursor position
    char string[8];                             // max 6 digit wide string
    dtostrf((pulse / 2), 7, 0, string);         // counts convering string (_//_ = 2 counts !!)
    oled.print(string);                         // data string on the display
    oled.display();                             // display on the screen
    delay(3500);                                // pause
    timerMode = 0;                              // set timermode status 0
  }
  //' ******************** LOOP END ******************************
}