I2C OLED intermittently freezing

I have this tiny OLED for the DataSleeve, but every now and then, the output freezes and the Arduino has to be reset. I found that reducing the refresh rate of the screen helps, but it still happens. I found another thread where someone had the same problem, and replacing their counterfeit Arduino fixed it.

However.

I'm using both a different library AND a different board (still knockoff, my Micro has a corrupted bootloader right now), and it's still happening. Furthermore, the board in my final project isn't genuine either, it's Adafruit's KB2040 with a 3rd party core to get it working in Arduino.

Hardware details:
Knockoff Nano (CH340)
I2C OLED
MPU6050 (I2C)
Rotary encoder

Code: (this code is pointless and serves as R&D)

#include <SPI.h>
#include <MPU6050.h>
#include <Wire.h>
#include <U8g2lib.h>

MPU6050 mpu;

int16_t ax, ay, az, gx, gy, gz;

U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0);

const int buttonPin = 4;

int counter = 0;
int buttonState;        
int lastButtonState = LOW;   

unsigned long lastDebounceTime = 0;  
unsigned long debounceDelay = 50;    

void setup() {
  pinMode(buttonPin, INPUT);
  u8g2.begin();
  Serial.begin(9600);
  mpu.initialize();
  if (!mpu.testConnection()) {
    while (1);
  }
}

void loop() {
  mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);

  int reading = digitalRead(buttonPin);
  
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {

    if (reading != buttonState) {
      buttonState = reading;

      if (buttonState == LOW && counter >= 0 && counter < 10) {
        counter++;
      }
      else if (buttonState == LOW && counter >= 10) {
        counter = 0;
      }
    }
  }

  lastButtonState = reading;

  switch (counter) {
    case 1:
      printInt(10, 10, ax);
      break;
    case 2:
      printInt(10, 10, ay);
      break;
    case 3:
      printInt(10, 10, az);
      break;
    case 4:
      printInt(10, 10, gx);
      break;
    case 5:
      printInt(10, 10, gy);
      break;
    case 6:
      printInt(10, 10, gz);
      break;
    default:
      printInt(10, 10, 0);
      break;
  }
  delay(100)
}

Uses a secondary function called printInt()

void printInt(int _cursorX, int _cursorY, int _varToPass) {
  u8g2.clearBuffer();				
  u8g2.setFont(u8g2_font_t0_11_tf); 
  u8g2.setCursor(_cursorX, _cursorY);
  u8g2.print(_varToPass);	
  u8g2.sendBuffer();			
}

First thing I would check is if the power (i.e. 5v supply) is good / add a capacitor between them.
I can't tell you how many times I have spent hours trying to find a problem only to later realise it is just a power issue.

Power's coming from USB, and I've never had problems with it before.