include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <max6675.h>

// setup the screen...
#define SIM true             // if running in a simulator
#define SCREEN_WIDTH 128     // OLED display width, in pixels
#define SCREEN_HEIGHT 32     // OLED display height, in pixels
#define OLED_RESET -1        // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C  //< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
#define MOV_AV_SIZE 10       // size of the moving average buffer
#ifdef SIM
#define POTPIN A0            // poteniometer pin
#define POTLOW      65       // low value on pot
#define POTHIGH     130      // high value on pot
#endif

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#ifdef SIM
float pot, wasPot=0;
#endif
int thermoDO = 4;
int thermoCS = 5;
int thermoCLK = 6;
float tempf = 0.0;
int timeCounter = 0;
int pushButtonPin = 2;
int relayPin = 10;
bool relayState = false;
bool runValve = false;
float move_av_buffer[MOV_AV_SIZE];
int   move_av_buffer_sz = 0;
int   buffer_pointer = 0;

MAX6675 thermocouple(thermoDO, thermoCS, thermoCLK);

void setup() {
  Serial.begin(9600);
  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;)
      ;  // Don't proceed, loop forever
  }
  display.display();
  delay(2000);  // Pause for 2 seconds

  // Clear the buffer
  display.clearDisplay();
  pinMode(pushButtonPin, INPUT_PULLUP);
  pinMode(relayPin, OUTPUT);
  digitalWrite(relayPin, HIGH);
}

void loop() {
  delay(100);
  timeCounter += 100;
  checkButton();
  readPot();
  checkTemp();
}

void checkButton() {
  if (digitalRead(pushButtonPin) == HIGH)
    runValve = true;
}

void readPot() {
  
}

void checkTemp() {
  if (timeCounter < 1000) return;
  timeCounter = 0;
  Serial.println(F("Reading..."));
  tempf = get_temperature_moving_av();
  display.clearDisplay();
  display.setCursor(10, 10);
  display.setTextColor(SSD1306_WHITE);
  display.setTextSize(2);
  display.print("T: ");
  display.setCursor(40, 10);
  display.print(tempf);
  display.print("F");
  display.display();
  if (tempf < 105.0) {
    if (not relayState and runValve) {
      digitalWrite(relayPin, LOW);
      relayState = true;
    }
  } else if (relayState) {
    digitalWrite(relayPin, HIGH);
    relayState = false;
  }
  runValve = false;
}

float get_temperature_moving_av() {
  // bump the buffer size if less than the max
  move_av_buffer_sz = move_av_buffer_sz < MOV_AV_SIZE ? move_av_buffer_sz + 1 : MOV_AV_SIZE;
  move_av_buffer[buffer_pointer] = thermocouple.readFarenheit();
  // bump the buffer pointer...
  buffer_pointer = buffer_pointer < MOV_AV_SIZE-1 ? buffer_pointer + 1 : 0;

  float sum = 0.0;
  for (int i=0; i < move_av_buffer_sz; i++)
    sum += move_av_buffer[i];
  return sum / static_cast<float>(move_av_buffer_sz);
}
NOCOMNCVCCGNDINLED1PWRRelay Module