   }
 }
 
-void setup() {
+void show_number(int n, uint8_t size=5) {
+  display.clearDisplay();
+  display.setTextSize(size);
+  display.setTextColor(WHITE);
+  uint16_t fw = FONTW * size;
+  uint16_t fh = FONTH * size;
+  uint16_t x = (LCDW >> 1) - fw;
+  uint16_t y = (LCDH - fh) >> 1;
+  uint16_t mx = 4;
+  uint16_t my = 2;
+  for (int i = 0; i < 2; i++) {
+    int offset = i << 1;
+    display.drawRect(x - mx - 1 - offset, y - my - 1 - offset, (fw << 1) + (mx << 1) + (offset << 1), fh + (my << 1) + (offset << 1), WHITE);
+  }
+  if (n < 10) {
+    x += fw;
+  }
+  display.setCursor(x, y);
+  display.print(n);
+}
+
+void button_pressed() {
+  number = LIMIT >> 1;
+}
+
+void setup_button() {
+  pinMode(BUTTON_PIN, INPUT_PULLUP);
+  attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), button_pressed, RISING);
+}
+
+void setup_i2c_devices() {
   // 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 0x3D (for the 128x64)
-  // Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties
-  displayLog("inited display");
+  Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties
+  show_number(number);
+  mpu.initialize();
+  if (!(mpu_test = mpu.testConnection())) {
+    display_log("MPU6050 connection failed");
+  }
+}
 
-  displayLog("initing MPU...");
-  mpu.initialize();
-
-  displayLog("Testing device connections...");
-  displayLog(mpu.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
-
+void setup_mpu_offset() {
   // supply your own gyro offsets here, scaled for min sensitivity
   // mpu.setXGyroOffset(220);
   // mpu.setYGyroOffset(76);

  // mpu.setZAccelOffset(1788); // 1688 factory default for my test chip
}

void loop() {
  mpu.getMotion6(raw, raw + 1, raw + 2, raw + 3, raw + 4, raw + 5);
  displayLog("ax\nay\naz\ngx\ngy\ngz\n", false);
  unsigned long time = millis();
  unsigned long fps = 1000 / (time - prev);
  prev = time;
  display.print("fps: ");
  display.println(fps);
  int rate = 32768 / 56;
  for (int i = 0; i < 6; i++) {
    int x0 = 16 + 56;
    int y0 = i * 8 + 1;
    display.drawRect(16, y0, 112, 6, WHITE);
    int len = raw[i] / rate;
    int x1 = x0 + len;
    display.fillRect(min(x0, x1), y0 + 1, abs(len), 4, WHITE);
  }

  display.display();
}


#include <math.h>

#define OLED_RESET  (-1)
#define BUTTON_PIN  2
#define MAX_DISP_NUM     100
#define LCDW        SSD1306_LCDWIDTH
#define LCDH        SSD1306_LCDHEIGHT
#define FONTW       6
#define FONTH       8

#define LIMIT       3000L

const long MAX_NUM = MAX_DISP_NUM * LIMIT;

Adafruit_SSD1306 display(OLED_RESET);
MPU6050 mpu;
bool mpu_test;

unsigned long prev = 0;

volatile long number = 0;

void display_log(const char* message, bool complete=true, uint8_t size=1) {
  display.clearDisplay();
  display.setTextSize(size);
  display.setTextColor(WHITE);
