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


