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();
}


