Arduino, problem with interrupt and SSD1306 OLED I'm not that good at this. Calculates RPM through Peripheral Speed and Interrupt.
Everything works fine when I show this in the IDE with Serial.print without OLED. When I connect an SSD1306 OLED I2C, the interrupt stops working. No serial.print.
If I uncomment the display.display(), Same problem with display.setRotation(90): everything is fine and serial.print starts working, but of course not the OLED.
In the code I have a void addressing, visadisplay(). If I put this addressing in void loop () then everything works but then there is a risk of unsynchronization, wrong values. I have also removed visadisplay(); without change.
Help...
#include &lt;SPI.h&gt;
#include &lt;Wire.h&gt;
#include &lt;Adafruit_GFX.h&gt;
#include &lt;Adafruit_SSD1306.h&gt;

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///&lt; See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &amp;Wire, OLED_RESET);

// Function for serial display.
// Connections for Nano.
// Hall sensor connection: (Signal out) --- (D2).
// Display connection: (SDA) --- (4A) / (SCL) --- (A5)

volatile unsigned long PulsTid = 0UL;
volatile unsigned long StartTid = 0;
volatile unsigned long SlutTid = 0;
volatile unsigned long CalcTid = 0;
volatile float omkrets = 7.5;
volatile float HastighetPerferi = 0;
volatile unsigned long Rpm = 0;
volatile float Vinkel = 0UL;

void isr() { // interrupt service routine
  Vinkel = 0;
  StartTid = millis();
  CalcTid = SlutTid;

  detachInterrupt(0);             //detaches the interrupt while calculating

  PulsTid = (StartTid - SlutTid);
  HastighetPerferi = (omkrets / PulsTid);
  SlutTid = StartTid;
  Rpm = ((HastighetPerferi / (omkrets / 1000) * 60) / 2); // Calculate speed

  visadisplay();
  attachInterrupt(0, isr, FALLING);  //attaching the interrupt again
}

void visadisplay(void) {
  Serial.print(&quot;Varvtal: &quot;);
  Serial.println(Rpm);
 
  display.setRotation(90);
  display.clearDisplay();
  display.setTextSize(1);              // Text size.
  display.setTextColor(SSD1306_WHITE); // White text.
  display.setCursor(0, 0);             // Start position
  display.println(&quot;RPM: &quot;);
  display.setCursor(40, 10);
  display.setTextSize(2);
  display.print(Rpm);
  display.display();
}

void setup() {
  Serial.begin(115200);
  attachInterrupt(0, isr, FALLING);  //attaching the interrupt

  //SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
    Serial.println(F(&quot;SSD1306 allocation failed&quot;));
    for(;;); // Don't proceed, loop forever
  }
}    

void loop(){
}
Your problem is (most likely) that you are doing everything from an interrupt. That is not only bad practice, but on Arduinos it is generally impossible.
On small microcontrollers you typically only have one interrupt priority (occasionally two). That means that only one interrupt can run at a time, and if an interrupt is running then no other interrupt can interrupt it.
So anything that relies on interrupts to operate can never be used inside an interrupt service routine, or it will never function.
That includes things like delay() and, depending on the implementation, such things as Wire (I2C) and SPI.
Instead your ISR really should be as short as possible. It should at most do any short calculations and store results, and then indicate (through the use of a semaphore) to the main thread that it should do some work.
The simplest &quot;fix&quot; to your problem would be to move visadisplay() into loop() and in isr() simply set a bool flag when there is data to display. Your loop() then checks that flag and, if set, resets it and calls visadisplay().
Also, you don't need to detach and re-attach the interrupt all the time - if the ISR is running then interrupts can't happen anyway.
// ... snip ...
volatile bool doDisplay = false;

void isr()          //interrupt service routine
{
  Vinkel = 0;
  StartTid = millis();
  CalcTid = SlutTid;

  PulsTid = (StartTid - SlutTid);
  HastighetPerferi = (omkrets/PulsTid);
  SlutTid = StartTid;
  Rpm = ((HastighetPerferi/(omkrets/1000)* 60)/2);  //Calculate speed

  doDisplay = true; // Signal to the main thread there's data to display
}

// ... snip ...

void loop() {
    if (doDisplay) {       // If there is something to display
        doDisplay = false; // then clear the flag for next time
        visadisplay();     // and display the data.
    }
}