#include <Adafruit_NeoPixel.h>
/*
==============================
ESP32 LAIKRODIS + CHRONOMETRAS (FIXED)
==============================
*/
#define LED_PIN 23
#define LED_COUNT 112
#define BTN_START 13
#define BTN_HOUR 25
#define BTN_MIN 26
#define BTN_RESET 27
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
// ================== LAIKAI ==================
int clockSeconds = 12 * 3600; // pradinis laikas (12:00)
int stopwatchSeconds = 0;
bool stopwatchRunning = false;
// dvitaškis
bool colonState = false;
unsigned long lastTick = 0;
// spalvos
uint32_t colorClock;
uint32_t colorGreen;
uint32_t colorRed;
// 7 segmentai
byte digits[10][7] = {
{1,1,1,1,1,1,0},
{0,1,1,0,0,0,0},
{1,1,0,1,1,0,1},
{1,1,1,1,0,0,1},
{0,1,1,0,0,1,1},
{1,0,1,1,0,1,1},
{1,0,1,1,1,1,1},
{1,1,1,0,0,0,0},
{1,1,1,1,1,1,1},
{1,1,1,1,0,1,1}
};
#define SEG_SIZE 4
// ================== SETUP ==================
void setup() {
pinMode(BTN_START, INPUT_PULLUP);
pinMode(BTN_HOUR, INPUT_PULLUP);
pinMode(BTN_MIN, INPUT_PULLUP);
pinMode(BTN_RESET, INPUT_PULLUP);
strip.begin();
strip.show();
colorClock = strip.Color(0, 0, 150);
colorGreen = strip.Color(0, 150, 0);
colorRed = strip.Color(150, 0, 0);
}
// ================== SEGMENTAS ==================
void setSegment(int startLED, int segment, bool on, uint32_t color) {
int offset = segment * SEG_SIZE;
for (int i = 0; i < SEG_SIZE; i++) {
strip.setPixelColor(
startLED + offset + i,
on ? color : 0
);
}
}
// ================== SKAITMUO ==================
void showDigit(int digit, int pos, uint32_t color) {
int start = pos * 28;
for (int i = 0; i < 7; i++) {
setSegment(start, i, digits[digit][i], color);
}
}
// ================== DVITAŠKIS ==================
void drawColon() {
int base = 56;
uint32_t c = colonState ? colorClock : 0;
for (int i = 0; i < 4; i++) {
strip.setPixelColor(base + i, c);
}
}
// ================== LAIKRODIS ==================
void showClock() {
int h = (clockSeconds / 3600) % 24;
int m = (clockSeconds / 60) % 60;
showDigit(h / 10, 0, colorClock);
showDigit(h % 10, 1, colorClock);
showDigit(m / 10, 3, colorClock);
showDigit(m % 10, 4, colorClock);
drawColon();
strip.show();
}
// ================== CHRONOMETRAS ==================
void showStopwatch() {
int m = stopwatchSeconds / 60;
int s = stopwatchSeconds % 60;
uint32_t col = (stopwatchSeconds < 60) ? colorGreen : colorRed;
showDigit(m / 10, 0, col);
showDigit(m % 10, 1, col);
showDigit(s / 10, 3, col);
showDigit(s % 10, 4, col);
drawColon();
strip.show();
}
// ================== LOOP ==================
void loop() {
// ===== MYGTUKAI =====
if (digitalRead(BTN_START) == LOW) {
stopwatchRunning = !stopwatchRunning;
delay(200);
}
if (digitalRead(BTN_RESET) == LOW) {
stopwatchSeconds = 0;
stopwatchRunning = false;
delay(200);
}
if (digitalRead(BTN_HOUR) == LOW) {
clockSeconds += 3600;
delay(200);
}
if (digitalRead(BTN_MIN) == LOW) {
clockSeconds += 60;
delay(200);
}
// ===== LAIKAS =====
if (millis() - lastTick >= 1000) {
lastTick = millis();
colonState = !colonState;
if (stopwatchRunning) {
stopwatchSeconds++;
if (stopwatchSeconds >= 600) {
stopwatchRunning = false;
stopwatchSeconds = 0;
}
} else {
clockSeconds++;
}
}
// ===== RODYMAS =====
if (stopwatchRunning) showStopwatch();
else showClock();
}