Mutfak Zamanlayıcısı
Başlangıç30 dkÇay, yumurta ya da makarna için bir mutfak zamanlayıcısı: döner düğmeyi çevirerek süreyi ayarlarsın, 4 haneli ekranda dakika:saniye olarak görünür. Düğmeye basınca geri sayım başlar, ortadaki iki nokta saniyede bir yanıp söner; bir daha basınca duraklar, yine basınca kaldığı yerden devam eder, basılı tutunca ayarladığın süreye döner. Süre dolunca buzzer saniyede üç kez öter ve ekran yanıp söner; düğmeye basınca susar ve aynı süre yeniden kurulmaya hazır olur. Döner düğmenin (encoder) yönünü kesmeyle (interrupt) okumayı, tek düğmede kısa ve uzun basışı ayırmayı, millis() ile geri saymayı ve TM1637 ekranı iki kabloyla yönetmeyi öğretir. Kitaplık Yöneticisi'nden "TM1637" (Avishay Orpaz) kurulur.
Uygulamada adım adım yapGerekli malzemeler
1 × Arduino Uno R3
1 × Breadboard 830 Pin (MB-102)
1 × 4 Haneli 7 Segment Ekran Modülü (TM1637)
1 × Rotary Encoder (KY-040)
1 × Pasif Buzzer (Piezo)
11 × Jumper Kablo - Erkek/Erkek
4 × Jumper Kablo - Erkek/Dişi
Bağlantı adımları
- 1
Güç sıralarını bağla ve birleştir

Kırmızı erkek-erkek jumper kabloyu Arduino'nun güç başlığındaki 5V pinine tak, diğer ucunu breadboard'un alttaki kırmızı çizgili (+) güç sırasına bağla. Siyah kabloyu aynı başlıktaki GND pinine tak, alttaki mavi çizgili (−) sıraya bağla. Breadboard'un üstteki ve alttaki güç sıraları birbirine bağlı değildir: breadboard'un sağ ucunda kırmızı bir kabloyla alttaki (+) sırayı üstteki (+) sıraya, siyah bir kabloyla alttaki (−) sırayı üstteki (−) sıraya bağla. Artık dört sıranın hepsinde 5V ve GND var.
- Arduino 5V → alttaki kırmızı çizgili (+) sıra (kırmızı kablo)
- Arduino GND → alttaki mavi çizgili (−) sıra (siyah kablo)
- alttaki kırmızı çizgili (+) sıra → üstteki kırmızı çizgili (+) sıra (kırmızı kablo)
- alttaki mavi çizgili (−) sıra → üstteki mavi çizgili (−) sıra (siyah kablo)
- 2
Döner düğmeyi tak ve bağla

Döner düğme (encoder) modülünü, pinleri breadboard'un üst yarısında F sırasına gelecek şekilde tak: CLK 9., DT 10., SW 11., + 12., GND 13. sütuna gelsin. Pinleri yana bakan modüller breadboard'da dik durur. Sarı kabloyla 9. sütunu Arduino'nun 2, turuncu kabloyla 10. sütunu 3, beyaz kabloyla 11. sütunu 4 numaralı pinine bağla (ENCODER_CLK, ENCODER_DT, ENCODER_SW). Kısa kırmızı bir kabloyla 12. sütunu üstteki (+) sıraya, kısa siyah bir kabloyla 13. sütunu üstteki (−) sıraya bağla. CLK'nin 2 numaralı pine gitmesinin nedeni şu: Uno'da kesme (interrupt) yalnızca 2 ve 3 numaralı pinlerde var, kod her tıkı kesmeyle yakalar, böylece hızlı çevirince de tık kaçmaz.
- döner düğme CLK → 9. sütun, üst yarı
- döner düğme DT → 10. sütun, üst yarı
- döner düğme SW → 11. sütun, üst yarı
- döner düğme + pini → 12. sütun, üst yarı
- döner düğme GND → 13. sütun, üst yarı
- Arduino pin 2 → 9. sütun, üst yarı (sarı kablo)
- Arduino pin 3 → 10. sütun, üst yarı (turuncu kablo)
- Arduino pin 4 → 11. sütun, üst yarı (beyaz kablo)
- 12. sütun, üst yarı → üstteki kırmızı çizgili (+) sıra (kırmızı kablo)
- 13. sütun, üst yarı → üstteki mavi çizgili (−) sıra (siyah kablo)
- 3
Ekranı bağla

Ekran modülünün dört pinine erkek-dişi kabloların dişi uçlarını tak; pinlerin adları kartın üstünde yazar: CLK, DIO, VCC, GND. CLK'yi Arduino'nun 7, DIO'yu 6 numaralı pinine bağla (DISPLAY_CLK, DISPLAY_DIO). VCC'yi üstteki (+) sıraya, GND'yi üstteki (−) sıraya bağla. Bazı modüllerde pinlerin sırası farklıdır; kabloları sıraya göre değil, pinlerin yanında yazan adlara göre bağla.
- Arduino pin 7 → ekran CLK (yeşil kablo)
- Arduino pin 6 → ekran DIO (mavi kablo)
- ekran VCC → üstteki kırmızı çizgili (+) sıra (kırmızı kablo)
- ekran GND → üstteki mavi çizgili (−) sıra (siyah kablo)
- 4
Buzzer'ı tak ve bağla

Pasif buzzer'ın + bacağını üst yarıda 21. sütuna, öbür bacağını 22. sütuna tak; + bacak genelde daha uzundur ve gövdesinde + işareti vardır. Mor kabloyla Arduino'nun 5 numaralı pinini 21. sütuna bağla (BUZZER_PIN 5). Kısa siyah bir kabloyla 22. sütunu üstteki (−) sıraya bağla.
- buzzer + bacak → 21. sütun, üst yarı
- buzzer − bacak → 22. sütun, üst yarı
- Arduino pin 5 → 21. sütun, üst yarı (mor kablo)
- 22. sütun, üst yarı → üstteki mavi çizgili (−) sıra (siyah kablo)
Arduino kodu
// Kitaplık Yöneticisi'nden kurulacak:
// "TM1637" (Avishay Orpaz)
#include <TM1637Display.h>
// Döner düğme (KY-040): iki sinyal ve
// üstüne basınca kapanan düğme
const int ENCODER_CLK = 2;
const int ENCODER_DT = 3;
const int ENCODER_SW = 4;
// Ekran modülünün CLK ve DIO pinleri
const int DISPLAY_CLK = 7;
const int DISPLAY_DIO = 6;
const int BUZZER_PIN = 5;
// Sağa çevirince süre azalıyorsa true yap
const bool REVERSE = false;
// En uzun süre: 99 dakika
const long MAX_SECONDS = 99L * 60;
// Bu kadar basılı tutmak sıfırlar (ms)
const unsigned long LONG_PRESS = 800;
// Alarm en çok bu kadar çalar (ms)
const unsigned long ALARM_TIME = 60000;
// Ekranın ortasındaki iki nokta
const uint8_t COLON = 0b01000000;
TM1637Display display(DISPLAY_CLK, DISPLAY_DIO);
// Ayar, sayma, duraklama ve alarm
enum State { SETTING, RUNNING, PAUSED, ALARM };
State state = SETTING;
// Ayarlanan süre (sn) ve kalan süre (ms)
long setSeconds = 0;
long remainingMs = 0;
unsigned long lastTick = 0;
unsigned long alarmStart = 0;
bool beeping = false;
// Kesmenin saydığı tıklar (+ sağa)
volatile int turns = 0;
volatile unsigned long lastEdge = 0;
unsigned long lastTurn = 0;
bool buttonDown = false;
unsigned long buttonChange = 0;
unsigned long pressStart = 0;
bool longDone = false;
// Ekranda en son ne yazdığı
long shown = -1;
// Her tıkta çalışır: CLK düşerken DT'ye
// bakılır, yön oradan anlaşılır
void onTurn() {
// 3 ms içindeki sıçramalar sayılmaz
unsigned long now = millis();
if (now - lastEdge < 3) return;
lastEdge = now;
turns += digitalRead(ENCODER_DT) == HIGH ? 1 : -1;
}
long secondsLeft() {
return (remainingMs + 999) / 1000;
}
// Süreyi Seri Monitöre DD:SS yazar
void printTime(const char *label, long seconds) {
Serial.print(label);
if (seconds / 60 < 10) Serial.print("0");
Serial.print(seconds / 60);
Serial.print(":");
if (seconds % 60 < 10) Serial.print("0");
Serial.println(seconds % 60);
}
// Bir tıkın adımı: 2 dakikaya kadar 10
// sn, 10 dakikaya kadar 30 sn, sonra 1 dk
long stepFor(long seconds, int dir) {
if (dir > 0) seconds++;
if (seconds > 600) return 60;
if (seconds > 120) return 30;
return 10;
}
void stopAlarm() {
noTone(BUZZER_PIN);
beeping = false;
state = SETTING;
// Aynı süre için bir basış yeter
remainingMs = setSeconds * 1000;
Serial.println("Alarm durdu.");
}
void turn(int dir) {
if (state == ALARM) {
stopAlarm();
return;
}
long seconds = state == SETTING ? setSeconds : secondsLeft();
long step = stepFor(seconds, dir);
// Adımın katına oturur: 47'den sağa 50
long next = dir > 0 ? (seconds / step + 1) * step
: ((seconds + step - 1) / step - 1) * step;
next = constrain(next, 0, MAX_SECONDS);
if (next == seconds) return;
// Sayarken süre sıfıra indirilmez
if (next == 0 && state != SETTING) return;
if (state == SETTING) setSeconds = next;
remainingMs = next * 1000;
printTime("Süre: ", next);
tone(BUZZER_PIN, 4000, 2);
}
void shortPress() {
if (state == SETTING) {
if (setSeconds == 0) return;
remainingMs = setSeconds * 1000;
state = RUNNING;
lastTick = millis();
tone(BUZZER_PIN, 1500, 80);
printTime("Başladı: ", setSeconds);
} else if (state == RUNNING) {
state = PAUSED;
tone(BUZZER_PIN, 800, 80);
printTime("Duraklatıldı: ", secondsLeft());
} else if (state == PAUSED) {
state = RUNNING;
lastTick = millis();
tone(BUZZER_PIN, 1500, 80);
printTime("Devam ediyor: ", secondsLeft());
}
}
// Basılı tutunca: sayıyorsa baştaki
// süreye döner, ayardaysa sıfırlar
void longPress() {
if (state == SETTING) setSeconds = 0;
state = SETTING;
remainingMs = setSeconds * 1000;
tone(BUZZER_PIN, 600, 150);
printTime("Sıfırlandı: ", setSeconds);
}
// Kısa basış başlatır ya da duraklatır,
// uzun basış sıfırlar
void readButton() {
bool down = digitalRead(ENCODER_SW) == LOW;
if (down != buttonDown) {
// Kontak sıçraması: 30 ms bekle
if (millis() - buttonChange < 30) return;
buttonChange = millis();
buttonDown = down;
if (down) {
pressStart = millis();
longDone = false;
// Alarm, basar basmaz susar
if (state == ALARM) {
stopAlarm();
longDone = true;
}
} else if (!longDone) {
shortPress();
}
} else if (down && !longDone && millis() - pressStart >= LONG_PRESS) {
longDone = true;
longPress();
}
}
void update() {
unsigned long now = millis();
if (state == RUNNING) {
remainingMs -= (long)(now - lastTick);
lastTick = now;
if (remainingMs <= 0) {
remainingMs = 0;
state = ALARM;
alarmStart = now;
Serial.println("Süre doldu!");
}
}
if (state == ALARM) {
unsigned long t = now - alarmStart;
// Bir dakika sonra kendisi susar
if (t >= ALARM_TIME) {
stopAlarm();
return;
}
// Saniyede üç kısa bip
bool on = t % 1000 < 600 && t % 200 < 100;
if (on != beeping) {
beeping = on;
if (on) tone(BUZZER_PIN, 2000);
else noTone(BUZZER_PIN);
}
}
}
// Ekrana yalnızca bir şey değişince
// yazar; yazmak birkaç ms sürer
void updateDisplay() {
unsigned long now = millis();
long seconds = state == SETTING ? setSeconds : secondsLeft();
bool colon = true;
bool visible = true;
if (state == RUNNING) {
// İki nokta saniyede bir yanıp söner
colon = remainingMs % 1000 >= 500;
} else if (state == PAUSED) {
// Duraklayınca rakamlar yanıp söner;
// çevirince yeni süre görünür kalır
visible = now % 1000 < 600 || now - lastTurn < 1500;
} else if (state == ALARM) {
visible = (now - alarmStart) % 1000 < 500;
}
long key = seconds * 4 + colon * 2 + visible;
if (key == shown) return;
shown = key;
if (!visible) {
display.clear();
return;
}
int value = seconds / 60 * 100 + seconds % 60;
display.showNumberDecEx(value, colon ? COLON : 0, true);
}
void setup() {
Serial.begin(9600);
pinMode(ENCODER_CLK, INPUT_PULLUP);
pinMode(ENCODER_DT, INPUT_PULLUP);
pinMode(ENCODER_SW, INPUT_PULLUP);
// Tık kaçmasın diye CLK bir kesme pini
attachInterrupt(digitalPinToInterrupt(ENCODER_CLK), onTurn, FALLING);
display.setBrightness(5);
Serial.println("Mutfak zamanlayıcısı hazır.");
}
void loop() {
// Kesmenin saydığı tıkları al
noInterrupts();
int n = turns;
turns = 0;
interrupts();
if (REVERSE) n = -n;
if (n != 0) lastTurn = millis();
while (n > 0) {
turn(1);
n--;
}
while (n < 0) {
turn(-1);
n++;
}
readButton();
update();
updateDisplay();
}
Seri Monitörde göreceğin
Mutfak zamanlayıcısı hazır. Süre: 00:10 Süre: 00:20 Süre: 00:30 Başladı: 00:30 Duraklatıldı: 00:21 Devam ediyor: 00:21 Süre doldu! Alarm durdu.
Sonuç
Kodu yükleyince ekranda 00:00 görünür. Döner düğmeyi sağa çevir: her tıkta buzzer küçük bir tık sesi çıkarır ve süre 2 dakikaya kadar 10 saniye, 10 dakikaya kadar 30 saniye, sonra 1'er dakika artar (en çok 99:00); sola çevirince azalır. Düğmeye bir kez bas: kısa bir bip çalar, geri sayım başlar ve ortadaki iki nokta saniyede bir yanıp söner. Sayarken çevirerek süre ekleyip çıkarabilirsin. Bir daha basınca duraklar ve rakamlar yanıp söner, yine basınca devam eder. Basılı tutarsan ayarladığın süreye döner; süre ayarlanırken basılı tutarsan 00:00 olur. Süre dolunca buzzer saniyede üç kez öter ve 00:00 yanıp söner; düğmeye basınca ya da çevirince susar, bir dakika sonra kendiliğinden de susar. Ekranda yine ayarladığın süre görünür, aynı süre için bir basış yeter. Sağa çevirince süre azalıyorsa koddaki REVERSE'ü true yapıp kodu yeniden yükle. Ekranda hiçbir şey yanmıyorsa CLK ve DIO kablolarının 7 ve 6'da olduğunu, VCC ile GND'nin karışmadığını kontrol et. Çevirince süre değişmiyorsa CLK'nin 2'ye, DT'nin 3'e takılı olduğuna bak.
Uygulamada her bağlantıyı tek tek işaretle, envanterindeki parçalarla eşleştir ve kaldığın yerden devam et.
Uygulamada adım adım yap