// Custom Libraries from:         https://wokwi.com/projects/371042933135787009

// For Programming the Attiny85:  https://www.instructables.com/How-to-Program-an-Attiny85-From-an-Arduino-Uno/
//                                https://homemadehardware.com/guides/programming-an-attiny85/

// For Temperature Stuff Example: https://randomnerdtutorials.com/arduino-lm35-lm335-lm34-temperature-sensor/


#include <TinyWireM.h>
#include "LiquidCrystal_I2C.h"

#define GPIO_ADDR     0x27                  // (PCA8574A A0-A2 @5V) typ. A0-A3 Gnd 0x20 / 0x38 for A
LiquidCrystal_I2C lcd(GPIO_ADDR, 16, 2);    // set address & 16 chars / 2 lines

const byte sensorPin = A3;                  // Set Analog Input Pin For Temperature Sensor
const byte buttonPin = PB4;                 // Set Input Pin For Mode Selector Button

// Create Global Variables:
float vOut = 0;                             // Create Variable To Store The Sensor's Output Voltage
float tempSum = 0;                          // Create Variable To Store Measurements
float tempK = 0;                            // Create Variable To Store Temperature In Kelvin
float tempC = 0;                            // Create Variable To Store Temperature In Celcius
float tempF = 0;                            // Create Variable To Store Temperature In Fahrenheit
bool lastButtonState = HIGH;                // Create Variable To Store The Previous Button State
byte displayMode = 0;                       // Create Variable To Store The Display Mode
// Display Modes:
// displayMode = 0  --> Display Temperature In Degrees Fahrenheit
// displayMode = 1  --> Display Temperature In Degrees Celcius
// displayMode = 2  --> Display Temperature In Kelvin
// displayMode = 3  --> Display vOut (Average)


// Create Global Constants:
const long delTime_Main = 50;              // Set Main Loop Delay
const long delTime_Measurement = 5;         // Set Measurement Delay
const long delTime_ModeChange = 200;        // Set Mode Change Pause/Delay
const int numMeasurements = 50;             // Set Number Of Measurements Per Cycle
const byte maxDisplayMode = 3;              // Set The Highest Display Mode Value


void setup() {
  TinyWireM.begin();
  lcd.init();
  lcd.backlight();
  lcd.clear();
  pinMode(buttonPin, INPUT_PULLUP);
}

void loop() {
  // Check for Mode Switching:
  modeSelect();
  // Read Temperature:
  tempSum = 0;                    // Reset tempSum Variable
  for (int i=0; i<numMeasurements; i++) {
    tempSum = tempSum + analogRead(sensorPin);
    delay(delTime_Measurement);
  }
  vOut = ((tempSum/numMeasurements) * 5000) / 1024;    // Convert Measurement To Voltage (might need to divide by 1023 instead of 1024)
  tempK = vOut/10;
  tempC = tempK - 273;
  tempF = (tempC * 1.8) + 32;

  // Clear Previous Temperature From Display:
  lcd.setCursor(0, 1);
  lcd.print("                ");
  // Display Temperature:
  switch (displayMode) {
    case 0:   // Display Degrees Fahrenheit
      lcd.setCursor(0, 0);
      lcd.print("Temperature:");
      lcd.setCursor(0, 1);
      lcd.print(tempF);
      lcd.print((char)223);
      lcd.print("F");
      break;
    case 1:   // Display Degrees Celcius
      lcd.setCursor(0, 0);
      lcd.print("Temperature:");
      lcd.setCursor(0, 1);
      lcd.print(tempC);
      lcd.print((char)223);
      lcd.print("C");
      break;
    case 2:
      lcd.setCursor(0, 0);
      lcd.print("Temperature:");
      lcd.setCursor(0, 1);
      lcd.print(tempK);
      lcd.print("K");
      break;
    case 3:
      lcd.setCursor(0, 0);
      lcd.print("Voltage Out:");
      lcd.setCursor(0, 1);
      lcd.print(vOut);
      lcd.print((char)223);
      lcd.print("mV");
      break;
  }
  
  // Wait:
  delay(delTime_Main);
}

void modeSelect() {
  bool buttonState = digitalRead(buttonPin);
  if ((buttonState==LOW) && (lastButtonState == HIGH)) {
    displayMode = displayMode + 1;        // Advance Display Mode Value
    if (displayMode > maxDisplayMode) {   // If Display Mode Exceeds The Maximum Value, Reset It To 0
      displayMode = 0;
    }
  }
  lastButtonState = buttonState;
  delay(delTime_ModeChange);
}
ATTINY8520PU