Willing to pay for a simple "single-held-button-time-counter"

Welp,
I've read and read, pieced together some random snippets of code from examples,
and I've got the counting working correctly, along with button functionality, and even the display.

But I'm getting random freezes and restarts... =\

Oh, but the "button" is now a SW-420 Vibration sensor on an interrupt pin.
Could that cause the freezing?

My Sketch so far:

// Include Libraries for OLED
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 0  // GPIO0
Adafruit_SSD1306 display(OLED_RESET);

#define led_pin 2
  char Upmsg[15] = "";
  char Onmsg[15] = "";
  char Offmsg[15] = "";
  char Idlemsg[15] = "";
  struct Time{
  String msg;
  unsigned char hours;
  unsigned char minutes;
  unsigned char seconds;
};


Time Up,On,Off,Idle;
unsigned char s, button, idle_flag;
unsigned int percentage;
void setup() {
  Up = {" ",0,0};
  On = {" ", 0,0};
  Off = {" ", 0,0};
  Idle = {" ", 0,0};
  s = 0;
  idle_flag = 0;
  Serial.begin(115200);
  pinMode(led_pin, OUTPUT);
  pinMode(button_pin,INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(14), IntCallback, CHANGE);

    // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 64x48)
  // init done

  // Clear the buffer and Initialize Display.
  display.clearDisplay();
  display.display();  
  
  // text display setup
  display.setTextSize(1);
  display.setTextColor(WHITE);
}

void loop() {
//  if (digitalRead(button_pin)==1){button = 1;}
  delay(1000);
  s++;
//  if (digitalRead(button_pin)==1){button = 1;}
  s = 0;
  print_time();
  update_time();
}


void update_time(){
  Up.seconds = Up.seconds + 1; // Update after every minute
  if (Up.seconds>=60){
    Up.seconds = 0;
    Up.minutes = Up.minutes + 1;
  }
    if (Up.minutes>=60){
    Up.minutes = 0;
    Up.hours = Up.hours + 1;
  }
  
  // Updating on/off
  if(button == 1){
    digitalWrite(led_pin, LOW); //LED Shows button if button is pressed
    button = 0;
    idle_flag = 0;
    On.seconds = On.seconds + 1; // Update after every minute
    if (On.seconds>=60){
      On.seconds = 0;
      On.minutes = On.minutes + 1;
      }
      if (On.minutes>=60){
      On.minutes = 0;
      On.hours = On.hours + 1;
      }
  }
  else{
    digitalWrite(led_pin, HIGH);
    idle_flag  = 1; //
    Off.seconds = Off.seconds + 1; // Update after every minute
    if (Off.seconds>=60){
      Off.seconds = 0;
      Off.minutes = Off.minutes + 1;
      }
      if (Off.minutes>=60){
      Off.minutes = 0;
      Off.hours = Off.hours + 1;
      }
  }

  if(idle_flag == 1){
    Idle.seconds = Idle.seconds + 1; // Update after every minute
    if (Idle.seconds>=60){
      Idle.seconds = 0;
      Idle.minutes = Idle.minutes + 1;
      }
      if (Idle.minutes>=60){
      Idle.minutes = 0;
      Idle.hours = Idle.hours + 1;
      }
  }
  else{
    Idle.seconds = 0;
    Idle.minutes = 0;
    Idle.hours = 0;
  }
 
  sprintf(Upmsg, "UP %01d:%02d:%02d", Up.hours, Up.minutes, Up.seconds);
  sprintf(Onmsg, "ON %01d:%02d:%02d", On.hours, On.minutes, On.seconds);
  sprintf(Offmsg, "OF %01d:%02d:%02d", Off.hours, Off.minutes, Off.seconds);
  sprintf(Idlemsg, "ID %01d:%02d:%02d", Idle.hours, Idle.minutes, Idle.seconds);
  calculate_percentage();
}

void print_time(){
  display.clearDisplay(); //Display buffer is persistant so we must clear it each loop
  display.setCursor(0,0); //Return to top line
  display.println(Upmsg);
  display.println(Onmsg);
  display.println(Offmsg);
  display.println(Idlemsg);
  display.println();   //Drop down a line
  display.print(String(percentage)+" Percent");
  display.display();  //Draw buffer on screen

}

void calculate_percentage(){
  percentage = (unsigned int) (((On.minutes*60 + On.seconds)*100) / (Up.minutes*60+ Up.seconds));
}

void IntCallback(){
 button = 1;
}