ESP32 Bluetooth Controlled Calculator That Hates 67 as An Answer

This is the code for my calculator. Before using, make sure you have the TM1637Display.h and BluetoothSerial.h libraries installed.

#include <BluetoothSerial.h>

#include <TM1637Display.h>

BluetoothSerial SerialBT;

// —- TM1637 Pins —-

#define CLK  13

#define DIO  14

TM1637Display display(CLK, DIO);

// —- Buzzer Pin —-

#define BUZZ 25

// —- Calculator Variables —-

String inputBuffer = “”;

// —- Error Buzzer Timing —-

unsigned long lastBuzz = 0;

bool buzzing = false;

int buzzStep = 0;

// —- 67 Hate Mode —-

bool hate67 = false;

unsigned long lastRoast = 0;

// ————————————————–

//   VALID CHARACTER CHECK

// ————————————————–

bool isValidChar(char c) {

  return (c >= ‘0’ && c <= ‘9’) ||

         c == ‘+’ || c == ‘-‘ || c == ‘*’ ||

         c == ‘/’ || c == ‘:’ || c == ‘÷’;

}

void setup() {

  Serial.begin(115200);

  SerialBT.begin(“ESP32_CALC”);

  pinMode(BUZZ, OUTPUT);

  digitalWrite(BUZZ, LOW);

  display.setBrightness(7);

  display.showNumberDec(0, true);

}

void loop() {

  // —————————–

  //   HANDLE BLUETOOTH INPUT (BURST)

  // —————————–

  if (SerialBT.available()) {

    inputBuffer = “”;

    // small wait to let the whole message arrive

    delay(30);

    while (SerialBT.available()) {

      char c = SerialBT.read();

      if (isValidChar(c)) {

        inputBuffer += c;

      }

    }

    SerialBT.print(“Received: “);

    SerialBT.println(inputBuffer);

    if (inputBuffer.length() > 0) {

      evaluateExpression();

      inputBuffer = “”;

    }

  }

  // —————————–

  //   NORMAL ERROR BUZZER

  // —————————–

  if (buzzing && !hate67) {

    unsigned long now = millis();

    if (now – lastBuzz >= 500) {

      lastBuzz = now;

      buzzStep++;

      if (buzzStep % 2 == 1) tone(BUZZ, 60);

      else noTone(BUZZ);

      if (buzzStep >= 6) {

        buzzStep = 0;

        buzzing = false;

        noTone(BUZZ);

      }

    }

  }

  // —————————–

  //   67 HATE MODE

  // —————————–

  if (hate67) {

    unsigned long now = millis();

    // Buzz once per second

    if (now – lastBuzz >= 1000) {

      lastBuzz = now;

      tone(BUZZ, 60);

      delay(200);

      noTone(BUZZ);

    }

    // Roast every 2 seconds

    if (now – lastRoast >= 2000) {

      lastRoast = now;

      const char* roasts[] = {

        “67? Even my resistors cringe.”,

        “I hate 67!!!”,

        “67 detected. Initiating maximum disrespect.”,

        “You suck!”,

        “67 is the math equivalent of stepping on a LEGO.”,

        “Nice try. 67 is banned for crimes against arithmetic.”

      };

      int r = random(0, 6);

      SerialBT.println(roasts[r]);

    }

  }

}

// ————————————————–

//   EVALUATE EXPRESSION

// ————————————————–

void evaluateExpression() {

  String expr = inputBuffer;

  // Normalize operators

  expr.replace(“x”, “*”);

  expr.replace(“X”, “*”);

  expr.replace(“:”, “/”);

  expr.replace(“÷”, “/”);

  int operatorCount = 0;

  int opIndex = -1;

  char op = 0;

  for (int i = 0; i < expr.length(); i++) {

    if (expr[i]==’+’ || expr[i]==’-‘ || expr[i]==’*’ || expr[i]==’/’) {

      operatorCount++;

      opIndex = i;

      op = expr[i];

    }

  }

  if (operatorCount != 1 || opIndex <= 0 || opIndex >= expr.length() – 1) {

    triggerError();

    return;

  }

  int left = expr.substring(0, opIndex).toInt();

  int right = expr.substring(opIndex + 1).toInt();

  long result = 0;

  switch (op) {

    case ‘+’: result = left + right; break;

    case ‘-‘: result = left – right; break;

    case ‘*’: result = left * right; break;

    case ‘/’:

      if (right == 0) {

        triggerError();

        return;

      }

      result = left / right;

      break;

  }

  // Range check

  if (result > 9999 || result < -999) {

    triggerError();

    return;

  }

  // 67 HATE MODE

  if (result == 67) {

    hate67 = true;

    buzzing = false;

    display.clear();

    SerialBT.println(“ERROR: Calculator refuses to display 67.”);

    return;

  }

  // Normal valid result

  hate67 = false;

  displayNumber(result);

  SerialBT.print(“Result: “);

  SerialBT.println(result);

}

// ————————————————–

//   DISPLAY NUMBER

// ————————————————–

void displayNumber(int num) {

  if (num >= 0)

    display.showNumberDec(num, true);

  else

    display.showNumberDec(num, true, 4, 0);

}

// ————————————————–

//   ERROR BUZZER

// ————————————————–

void triggerError() {

  SerialBT.println(“ERROR!”);

  hate67 = false;

  buzzing = true;

  buzzStep = 0;

  lastBuzz = millis();

  display.clear();

}