#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define LOGO_HEIGHT 64
#define LOGO_WIDTH 128 
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

static const unsigned char PROGMEM logo[] = {
  0xff, 0xff, 0x80, 0x00, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x00, 0x7f, 0xf0, 0xff, 0xff, 0xf8, 0x00, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x01, 0xff, 0xfc, 
  0xff, 0xff, 0xf8, 0x00, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x03, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x0f, 0xff, 0xfe, 
  0xff, 0xff, 0xff, 0x00, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x1f, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x80, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x1f, 0xff, 0xfe, 
  0xfc, 0x00, 0xff, 0xc0, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x1f, 0xe0, 0x1e, 0xfc, 0x00, 0xff, 0xe0, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x3f, 0xc0, 0x1e, 
  0xfc, 0x00, 0x1f, 0xe0, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x3f, 0x80, 0x02, 0xfc, 0x00, 0x07, 0xf0, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x7f, 0x00, 0x00, 
  0xfc, 0x00, 0x07, 0xf0, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x7f, 0x00, 0x00, 0xfc, 0x00, 0x07, 0xf8, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x7f, 0x00, 0x00, 
  0xfc, 0x00, 0x03, 0xf8, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x7f, 0x00, 0x00, 0xfc, 0x00, 0x03, 0xf8, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x7f, 0x00, 0x00, 
  0xfc, 0x00, 0x01, 0xfc, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x7f, 0x80, 0x00, 0xfc, 0x00, 0x01, 0xfc, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x3f, 0x80, 0x00, 
  0xfc, 0x00, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x1f, 0xc0, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x1f, 0xe0, 0x00, 
  0xfc, 0x00, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x1f, 0xf8, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x0f, 0xfe, 0x00, 
  0xfc, 0x00, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x0f, 0xff, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x07, 0xff, 0xc0, 
  0xfc, 0x00, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x01, 0xff, 0xc0, 0xfc, 0x00, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x00, 0xff, 0xf0, 
  0xfc, 0x00, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x00, 0x3f, 0xf8, 0xfc, 0x00, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x00, 0x1f, 0xfc, 
  0xfc, 0x00, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x00, 0x07, 0xfe, 0xfc, 0x00, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x00, 0x01, 0xfe, 
  0xfc, 0x00, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x00, 0x01, 0xfe, 0xfc, 0x00, 0x01, 0xf8, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x00, 0x00, 0xff, 
  0xfc, 0x00, 0x01, 0xf8, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x7f, 0xfc, 0x00, 0x03, 0xf8, 0x03, 0xf0, 0x00, 0x1f, 0x80, 0x7e, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x3f, 
  0xfc, 0x00, 0x03, 0xf0, 0x03, 0xf8, 0x00, 0x3f, 0x80, 0x7f, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x07, 0xf0, 0x03, 0xf8, 0x00, 0x3f, 0x80, 0x7f, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x3f, 
  0xfc, 0x00, 0x0f, 0xf0, 0x01, 0xf8, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x1f, 0xe0, 0x01, 0xfc, 0x00, 0x7f, 0x00, 0x3f, 0x80, 0x0f, 0xe0, 0x00, 0x00, 0x7f, 
  0xfc, 0x00, 0x1f, 0xc0, 0x01, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xe0, 0x60, 0x00, 0x7f, 0xfc, 0x00, 0xff, 0x80, 0x01, 0xfe, 0x01, 0xfe, 0x00, 0x3f, 0xe0, 0x1f, 0xc0, 0x7c, 0x00, 0xfe, 
  0xfc, 0x00, 0xff, 0x80, 0x01, 0xff, 0x01, 0xfe, 0x00, 0x3f, 0xe0, 0x3f, 0xc0, 0x7e, 0x01, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xc0, 0x7f, 0xff, 0xfe, 
  0xff, 0xff, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0xfc, 0x00, 0x0f, 0xff, 0xff, 0x80, 0x7f, 0xff, 0xfc, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x7f, 0xff, 0xf8, 0x00, 0x07, 0xff, 0xff, 0x80, 0x7f, 0xff, 0xf8, 
  0xff, 0xff, 0xf0, 0x00, 0x00, 0x3f, 0xff, 0xe0, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x7f, 0xff, 0xf8, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x1f, 0xff, 0xe0, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x3f, 0xff, 0xf0, 
  0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x07, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0xff, 0xf8, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 
  0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 
  0x07, 0x03, 0xf8, 0x0f, 0xc7, 0x3c, 0x07, 0xe0, 0x73, 0x8f, 0x00, 0xf8, 0x3f, 0xc3, 0xe0, 0x77, 0x07, 0x07, 0xfc, 0x1f, 0xc7, 0x7e, 0x0f, 0xf0, 0x7f, 0xdf, 0x81, 0xfe, 0x3f, 0xc7, 0xf8, 0x7f, 
  0x07, 0x06, 0x1e, 0x3c, 0x47, 0x8f, 0x1c, 0x38, 0x79, 0xf3, 0xc3, 0x8e, 0x0e, 0x0e, 0x38, 0x78, 0x07, 0x00, 0x0e, 0x38, 0x07, 0x07, 0x3c, 0x1c, 0x70, 0xe1, 0xc7, 0x07, 0x0e, 0x1c, 0x1c, 0x78, 
  0x07, 0x00, 0xfe, 0x70, 0x07, 0x07, 0x38, 0x1c, 0x70, 0xe1, 0xc7, 0x07, 0x0e, 0x1c, 0x1c, 0x70, 0x07, 0x07, 0xfe, 0x70, 0x07, 0x07, 0x38, 0x1c, 0x70, 0xe1, 0xc7, 0xff, 0x0e, 0x1f, 0xfc, 0x70, 
  0x07, 0x0f, 0x8e, 0x70, 0x07, 0x07, 0x38, 0x1c, 0x70, 0xe1, 0xc7, 0xff, 0x0e, 0x1f, 0xfc, 0x70, 0x07, 0x0e, 0x0e, 0x70, 0x07, 0x07, 0x38, 0x1c, 0x70, 0xe1, 0xc7, 0x00, 0x0e, 0x1c, 0x00, 0x70, 
  0x07, 0x0e, 0x0e, 0x78, 0x07, 0x07, 0x3c, 0x1c, 0x70, 0xe1, 0xc7, 0x00, 0x0e, 0x1c, 0x00, 0x70, 0x07, 0x0f, 0x1e, 0x3c, 0x47, 0x07, 0x1c, 0x38, 0x70, 0xe1, 0xc3, 0x82, 0x0e, 0x0e, 0x08, 0x70, 
  0x07, 0x07, 0xfe, 0x1f, 0xc7, 0x07, 0x0f, 0xf0, 0x70, 0xe1, 0xc1, 0xfe, 0x0f, 0xc7, 0xf8, 0x70, 0x07, 0x03, 0xce, 0x0f, 0x87, 0x07, 0x07, 0xe0, 0x70, 0xe1, 0xc0, 0xfc, 0x07, 0xc3, 0xf0, 0x70,
};

float rev = 0;
unsigned long rpm;
unsigned long oldtime = 0;
unsigned long dutytime;
int sensePin = INT0; //Pin D2

void isr() { //interrupt service routine
 static unsigned long last_interrupt_time = 0;
 unsigned long interrupt_time = millis();
 // If interrupts come faster than 1ms, assume it's a bounce and ignore
 if (interrupt_time - last_interrupt_time > 1) {
   rev++;
 }
 last_interrupt_time = interrupt_time;
}

void setup() {
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);    // initialize with the I2C addr 0x3C
  display.ssd1306_command(SSD1306_SETCONTRAST); //Sæt lysstyrke til det lavest mulige (kommando)
  display.ssd1306_command(1);                   //Sæt lysstyrke til det lavest mulige (værdi)
  display.clearDisplay();
  
  display.drawBitmap(0, 0, logo, 128, 64, 1);
  display.display();                            //Skriv skærmbuffer (logo) til skærm
  delay(1000);
  
  for (int i = 1; i<256; i++) {
    display.ssd1306_command(SSD1306_SETCONTRAST); //Sæt lysstyrke til det lavest mulige (kommando)
    display.ssd1306_command(i);                   //Sæt lysstyrke til det lavest mulige (værdi)
    delay(5);
  }
  delay(1000);
  display.clearDisplay();

for (int i = 1; i<129; i=i+4) {
  display.drawFastHLine(0, 44, i, WHITE);
  display.display();
}
  
  display.setTextColor(WHITE);
  pinMode(sensePin, INPUT);
  attachInterrupt(sensePin,isr,RISING);  //attaching the interrupt
}

void loop() {
  detachInterrupt(0);                 //detaches the interrupt 
  dutytime = millis()-oldtime;        //finds the time
  oldtime = millis();                 //saves the current time
  rpm = (rev/dutytime)*60000;         //calculates rpm
  display.clearDisplay();
  display.setTextSize(3);
  display.setCursor(0,0);
  display.println(rpm,DEC);
  display.setTextSize(2);
  display.print("Omdr/minut");
  display.drawFastHLine(0, 44, 128, WHITE);
  display.setTextSize(1);
  display.setCursor(0,48);
  display.print("Omdrejninger: ");
  display.println((int)rev,DEC);
  display.print("Duty time: ");
  display.print(dutytime,DEC);
  display.println(" ms");
  display.display();
  rev = 0;
  attachInterrupt(sensePin,isr,RISING);  //attaching the interrupt
  delay(2950);
}