#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>

// Data wire is plugged in4to digital pin 2 on the Arduino
#define ONE_WIRE_BUS 4
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Setup a oneWire instance to communicate with any OneWire device
OneWire oneWire(ONE_WIRE_BUS);  

// Pass oneWire reference to DallasTemperature library
DallasTemperature sensors(&oneWire);

const int buttonPin = 7;     
const byte OC1A_PIN = 9;
const byte OC1B_PIN = 10;
const word PWM_FREQ_HZ = 25000; //Adjust this value to adjust the frequency
const word TCNT1_TOP = 16000000/(2*PWM_FREQ_HZ);
const int SETTEMPINTERVAL = 1000;

int buttonState = 0;      
void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(OC1B_PIN, OUTPUT);

  // PWM settings
  // Clear Timer1 control and count registers
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;

  // Set Timer1 configuration
  // COM1A(1:0) = 0b10   (Output A clear rising/set falling)
  // COM1B(1:0) = 0b00   (Output B normal operation)
  // WGM(13:10) = 0b1010 (Phase correct PWM)
  // ICNC1      = 0b0    (Input capture noise canceler disabled)
  // ICES1      = 0b0    (Input capture edge select disabled)
  // CS(12:10)  = 0b001  (Input clock select = clock/1)
  
  TCCR1A |= (1 << COM1A1) | (1 << WGM11);
  TCCR1B |= (1 << WGM13) | (1 << CS10);
  ICR1 = TCNT1_TOP;

   // start serial port 
   Serial.begin(9600);
   Serial.println("Starting");
   // Start up the temperature library 
   sensors.begin();
   if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }
  display.setRotation(4); //sets rotation 1 through 4  
  display.clearDisplay();
  // Draw text
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);        // Draw white text
  display.setCursor(0,0);             // Start at top-left corner
  display.print("Starting");

  // Show the display buffer on the screen. You MUST call display() after
  // drawing commands to make them visible on screen!
  display.display();
  delay(2000);
  display.setTextSize(1);
}

void loop() {
    tempToPwmDuty();
    delay(SETTEMPINTERVAL);
}

void setPwmDuty(byte duty) {
  OCR1A = (word) (duty*TCNT1_TOP)/100;
  Serial.println("Fan duty cycle");
  Serial.println(duty);

  //display.setCursor(0,0);
  display.print("Fan duty cycle: ");
  display.print(duty);
  display.println("%");
  display.display();
}

void tempToPwmDuty() {
 // Override temp sensor with button
 buttonState = digitalRead(buttonPin);
 if (buttonState == HIGH) {
  Serial.println("Button ON, overriding temp sensor");

  display.clearDisplay();
  display.setCursor(0,0);
  display.println("Button ON!");
  display.println("Overriding sensor");
  display.display();

  setPwmDuty(100);
  return;
 }
 
 sensors.requestTemperatures();
 int temp = sensors.getTempCByIndex(0);
 Serial.println("Setting temp via sensor");
 Serial.println(temp);

  display.clearDisplay();
  display.setCursor(0,0);
  display.println("Button OFF");
  display.print("Temp: ");
  display.println(temp);
  display.display();

 if (temp <= 35){
   setPwmDuty(0);
 }
 else if (temp > 35 && temp < 42){
   setPwmDuty(20);
 }
 else if (temp > 50){
   setPwmDuty(100);
 }
 else {
    setPwmDuty((temp-40)*10);
 }
}
$abcdeabcde151015202530fghijfghij