/*
NOTE: the wowki simulation of the pushbotton seems to work as a toggle button rather than a
momentary tactile switch. so there may be some odd behavior there. the code works as intended in real life

James Khan Fab Academy simulation. Embedded programming week.
https://fabacademy.org/2021/labs/vancouver/students/james-khan/assignments/week06/

started by using these Wowki samples:
https://wokwi.com/projects/375237011181407233
https://wokwi.com/projects/290056311044833800
https://wokwi.com/projects/365718993906978817
*/

#include <Wire.h>             // for OLED
#include <Adafruit_GFX.h>     // for OLED
#include <Adafruit_SSD1306.h> // for OLED

const int SCREEN_WIDTH = 128; // OLED display width, in pixels
const int SCREEN_HEIGHT = 64; // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); // for OLED


// Define variables button and LED
int buttonPin = 4; // Digital pin where the button is connected.
int ledPin = 13;   // Digital pin where the LED is connected.
bool buttonState = false;
int timer = 0;     // variable to keep count for timer

// DEfine variables Ultrasonic
#define ECHO_PIN 2
#define TRIG_PIN 3

void setup() {
  pinMode(ledPin, OUTPUT);    // LED pin as an output.
  pinMode(buttonPin, INPUT);  // Button pin as an input.

    // for OLED

  Serial.begin(9600);

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    while(true);
  }

    // for ultrasonic
  // Serial.begin(115200);    this was the ultrasonic samples code that conflicted
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);

}


float readDistanceCM() {
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  int duration = pulseIn(ECHO_PIN, HIGH);
  return duration * 0.034 / 2;
}

void loop() {

  float distance = readDistanceCM();    // ultrasonic read 

                // use for troubleshooting
  // Serial.print("Measured distance: ");  // serial output static 
  // Serial.print(readDistanceCM());     // serial output distance
  // Serial.print("  ");
  // Serial.println(buttonState);
  // buttonState = digitalRead(buttonPin);

      // read state of button only if buttonstate is LOW
  if (buttonState == LOW){
    buttonState = digitalRead(buttonPin);
    delay(50);
    if (buttonState == HIGH){             // resets timer on button press
      timer = 0;
    };
    digitalWrite(ledPin, LOW);         // LED off when timer not running
    display.clearDisplay();               // oled clear
    display.setTextSize(1);               // oled setup
    display.setTextColor(WHITE);
    display.setCursor(0, 10);  
    display.println("Press button to");   // static display
    display.println("start timer");
    display.println(" ");
    display.print("last time:");
    display.println(timer/10);
    display.println(" ");    
    display.print("Distance:  ");         
    display.println(distance);            // display distance
    display.display();
    delay(100);

  }
  
  if (buttonState == HIGH){ // once buttonState is HIGH then run rest of code
    
  digitalWrite(ledPin, HIGH);         // LED on when timer running

  display.clearDisplay();               // oled clear
  display.setTextSize(1);               // oled setup
  display.setTextColor(WHITE);
  display.setCursor(0, 10);  
  display.print("Time:  ");
  display.println(timer/10);            /// FILL IN TIME CODE
  display.println("seconds");
  display.println(" ");
  display.print("Distance:  ");         // static display
  display.println(distance);            // display distance
  display.display();
  delay(100);
  timer = timer + 1;                    // increment timer by 0.1 seconds
  if (distance < 200){                  // stop timer code
    buttonState = digitalRead(buttonPin);  // set buttonstate low so it stops timing
    };
  };

}