ESP32 Bluetooth Controlled Working Clock Code

This is the code for my ESP32 Bluetooth Controlled clock. It is a 12 hour clock and it requires the BluetoothSerial.h and TM1637Display.h libraries.

#include <BluetoothSerial.h>

#include <TM1637Display.h>

BluetoothSerial SerialBT;

// —- TM1637 Pins —-

#define CLK  13

#define DIO  14

TM1637Display display(CLK, DIO);

// —- Clock Variables —-

int hours = 12;

int minutes = 0;

bool setMode = false;       // true = entering time

String buffer = “”;         // collects typed digits

unsigned long lastMinuteTick = 0;

// —- Flashing in set mode —-

unsigned long lastFlash = 0;

bool flashState = true;

// —- Brightness Levels —-

int brightness = 7;  // default bright

void setup() {

  Serial.begin(115200);

  SerialBT.begin(“ESP32_CLOCK”);

  Serial.println(“Bluetooth Started”);

  display.setBrightness(brightness);

  display.showNumberDecEx(1200, 0b01000000, true);

}

void loop() {

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

  //   HANDLE BLUETOOTH INPUT

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

  if (SerialBT.available()) {

    char c = SerialBT.read();

    // ————————————

    //   ENTER/EXIT SET MODE (A or a)

    // ————————————

    if (c == ‘a’ || c == ‘A’) {

      if (!setMode) {

        setMode = true;

        buffer = “”;

        SerialBT.println(“SET MODE: Type digits like 500 or 1159 then press A”);

      } else {

        setMode = false;

        parseTimeBuffer();

        SerialBT.println(“TIME SET. Returning to clock mode.”);

      }

    }

    // ————————————

    //   BRIGHTNESS CONTROL (only in normal mode)

    // ————————————

    if (!setMode) {

      if (c == ‘4’) {

        brightness = 1;

        display.setBrightness(brightness);

        SerialBT.println(“Brightness: DIM”);

      }

      else if (c == ‘5’) {

        brightness = 4;

        display.setBrightness(brightness);

        SerialBT.println(“Brightness: MEDIUM”);

      }

      else if (c == ‘6’) {

        brightness = 7;

        display.setBrightness(brightness);

        SerialBT.println(“Brightness: BRIGHT”);

      }

    }

    // ————————————

    //   DIGIT COLLECTION (only in set mode)

    // ————————————

    if (setMode) {

      if (c >= ‘0’ && c <= ‘9’) {

        buffer += c;

        SerialBT.print(“Typed: “);

        SerialBT.println(buffer);

      }

    }

  }

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

  //   CLOCK TICKING LOGIC

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

  if (!setMode) {

    unsigned long now = millis();

    if (now – lastMinuteTick >= 60000) {

      lastMinuteTick = now;

      incrementMinute();

    }

  }

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

  //   DISPLAY UPDATE

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

  int displayTime = hours * 100 + minutes;

  if (setMode) {

    // Flash every 500ms

    unsigned long now = millis();

    if (now – lastFlash >= 500) {

      lastFlash = now;

      flashState = !flashState;

    }

    if (flashState) {

      display.showNumberDecEx(displayTime, 0b01000000, true);

    } else {

      display.clear();

    }

  }

  else {

    // Normal mode: solid display

    display.showNumberDecEx(displayTime, 0b01000000, true);

  }

}

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

//   PARSE DIGIT-ONLY TIME INPUT

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

void parseTimeBuffer() {

  int len = buffer.length();

  if (len == 3) {

    hours = buffer.substring(0, 1).toInt();

    minutes = buffer.substring(1, 3).toInt();

  }

  else if (len == 4) {

    hours = buffer.substring(0, 2).toInt();

    minutes = buffer.substring(2, 4).toInt();

  }

  else {

    SerialBT.println(“Invalid time format.”);

    return;

  }

  if (hours < 1 || hours > 12) {

    SerialBT.println(“Invalid hour.”);

    return;

  }

  if (minutes < 0 || minutes > 59) {

    SerialBT.println(“Invalid minutes.”);

    return;

  }

}

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

//   INCREMENT MINUTE

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

void incrementMinute() {

  minutes++;

  if (minutes >= 60) {

    minutes = 0;

    hours++;

    if (hours > 12) hours = 1;

  }

}