// กำหนดขาสำหรับควบคุมแต่ละหลักของ 7-segment
#define DG1 23 // หลักที่ 1 (นาที หลักสิบ)
#define DG2 25 // หลักที่ 2 (นาที หลักหน่วย)
#define DG3 18 // หลักที่ 3 (วินาที หลักสิบ)
#define DG4 14 // หลักที่ 4 (วินาที หลักหน่วย)
#define A 32 // ขาสำหรับส่วน A ของ 7-segment
#define B 13 // ขาสำหรับส่วน B ของ 7-segment
#define C 5 // ขาสำหรับส่วน C ของ 7-segment
#define D 22 // ขาสำหรับส่วน D ของ 7-segment
#define E 19 // ขาสำหรับส่วน E ของ 7-segment
#define F 33 // ขาสำหรับส่วน F ของ 7-segment
#define G 27 // ขาสำหรับส่วน G ของ 7-segment
#define DP 12 // ขาสำหรับจุดทศนิยม (ไม่ได้ใช้งานในโค้ดนี้)
#define DPColon 26 // ขาสำหรับจุดคั่นกลาง (ใช้แสดงโคลอน)
// ON = LOW, เนื่องจากการทำงานของ 7-segment แบบ common anode
hw_timer_t *timer1 = NULL; // ตัวจับเวลาสำหรับควบคุมการแสดงผล
unsigned int Time_min = 0; // ตัวแปรสำหรับเก็บค่านาที
unsigned int Time_sec = 0; // ตัวแปรสำหรับเก็บค่าวินาที
int status7Seg = 1; // ตัวแปรสำหรับระบุหลักที่กำลังแสดงผลใน 7-segment
bool runClock = false; // ตัวแปรควบคุมการทำงานของนาฬิกา (เริ่ม/หยุด)
bool toggleColon = false; // ตัวแปรควบคุมการแสดงผลของโคลอน
unsigned long current_Time = 0; // ตัวแปรเก็บเวลาปัจจุบัน (ไม่ได้ใช้ในโค้ดนี้)
unsigned long lastMillis_1sec = 0; // ตัวแปรเก็บเวลาล่าสุดที่ผ่านไป 1 วินาที
unsigned long lastMillis_500ms = 0; // ตัวแปรเก็บเวลาล่าสุดที่ผ่านไป 0.5 วินาที
void timer1_callback(void); // ฟังก์ชัน callback ของ timer
void showNumber(int num); // ฟังก์ชันสำหรับแสดงตัวเลขใน 7-segment
void showTime(); // ฟังก์ชันสำหรับแสดงเวลาบน 7-segment
void clearDisplay(); // ฟังก์ชันสำหรับล้างการแสดงผลของ 7-segment
void setup() {
Serial.begin(115200); // เริ่มต้นการสื่อสาร Serial ที่ความเร็ว 115200 bps
pinMode(DG1, OUTPUT); pinMode(DG2, OUTPUT); pinMode(DG3, OUTPUT); pinMode(DG4, OUTPUT);
pinMode(DPColon, OUTPUT);
pinMode(A, OUTPUT); pinMode(B, OUTPUT); pinMode(C, OUTPUT); pinMode(D, OUTPUT);
pinMode(E, OUTPUT); pinMode(F, OUTPUT); pinMode(G, OUTPUT); pinMode(DP, OUTPUT);
// ตั้งค่า timer1 ให้ทำงานทุกๆ 5 ms เพื่อแสดงผลแต่ละหลักของ 7-segment
timer1 = timerBegin(1000000); // เริ่มต้น timer ที่ 1,000,000 ไมโครวินาที (1 วินาที)
timerAttachInterrupt(timer1, &timer1_callback); // ผูกฟังก์ชัน callback กับ timer
timerAlarm(timer1, 5000, true, 0); // ตั้งให้เรียก callback ทุกๆ 5 ms
}
void loop() {
if (runClock) {
// อัปเดตเวลาทุกๆ 1 วินาที
if (millis() - lastMillis_1sec >= 1000) {
lastMillis_1sec = millis();
Time_sec++; // เพิ่มค่าวินาทีขึ้น 1
if (Time_sec == 60) {
Time_sec = 0; // ถ้าวินาทีครบ 60 ให้รีเซ็ตเป็น 0
Time_min++; // เพิ่มค่านาทีขึ้น 1
}
Serial.printf("Clock RUN -> %02d:%02d\n", Time_min, Time_sec); // แสดงเวลาปัจจุบันใน Serial Monitor
}
// สลับการแสดงผลของจุดคั่นกลาง (โคลอน) ทุกๆ 0.5 วินาที
if (millis() - lastMillis_500ms >= 500) {
lastMillis_500ms = millis();
toggleColon = !toggleColon;
digitalWrite(DPColon, toggleColon ? LOW : HIGH); // สลับสถานะของโคลอน
}
}
// ตรวจสอบคำสั่ง Serial เพื่อเริ่มหรือหยุดการทำงานของนาฬิกา
if (Serial.available()) {
char cmd = Serial.read();
if (cmd == '1') {
runClock = true; // เริ่มการทำงานของนาฬิกา
Serial.println("Clock RUN 1");
} else if (cmd == '2') {
runClock = false; // หยุดการทำงานของนาฬิกา
Serial.println("Clock STOP 2");
}
}
}
// ฟังก์ชัน callback ของ timer
void timer1_callback(void) {
clearDisplay(); // ล้างการแสดงผลของ 7-segment ก่อน
showTime(); // แสดงเวลาปัจจุบันบน 7-segment
}
// ฟังก์ชันสำหรับแสดงเวลา
void showTime() {
int minutes = Time_min;
int seconds = Time_sec;
int digit1 = minutes / 10; // หลักสิบของนาที
int digit2 = minutes % 10; // หลักหน่วยของนาที
int digit3 = seconds / 10; // หลักสิบของวินาที
int digit4 = seconds % 10; // หลักหน่วยของวินาที
// แสดงตัวเลขแต่ละหลักโดยใช้การสลับการแสดงผล
switch (status7Seg) {
case 1:
showNumber(digit1); // แสดงเลขหลักสิบของนาที
digitalWrite(DG1, LOW); // เปิดการแสดงผลที่ DG1
status7Seg = 2; // สลับไปแสดงหลักต่อไป
break;
case 2:
showNumber(digit2); // แสดงเลขหลักหน่วยของนาที
digitalWrite(DG2, LOW); // เปิดการแสดงผลที่ DG2
status7Seg = 3;
break;
case 3:
showNumber(digit3); // แสดงเลขหลักสิบของวินาที
digitalWrite(DG3, LOW); // เปิดการแสดงผลที่ DG3
status7Seg = 4;
break;
case 4:
showNumber(digit4); // แสดงเลขหลักหน่วยของวินาที
digitalWrite(DG4, LOW); // เปิดการแสดงผลที่ DG4
status7Seg = 1; // กลับไปแสดงหลักแรกในครั้งถัดไป
break;
}
}
// ฟังก์ชันสำหรับล้างการแสดงผลของ 7-segment
void clearDisplay() {
digitalWrite(DG1, HIGH); // ปิดการแสดงผลที่ DG1
digitalWrite(DG2, HIGH); // ปิดการแสดงผลที่ DG2
digitalWrite(DG3, HIGH); // ปิดการแสดงผลที่ DG3
digitalWrite(DG4, HIGH); // ปิดการแสดงผลที่ DG4
}
void showNumber(int num) {
switch (num) {
case 0:
digitalWrite(A, HIGH); digitalWrite(B, HIGH); digitalWrite(C, HIGH);
digitalWrite(D, HIGH); digitalWrite(E, HIGH); digitalWrite(F, HIGH); digitalWrite(G, LOW);
break;
case 1:
digitalWrite(A, LOW); digitalWrite(B, HIGH); digitalWrite(C, HIGH);
digitalWrite(D, LOW); digitalWrite(E, LOW); digitalWrite(F, LOW); digitalWrite(G, LOW);
break;
case 2:
digitalWrite(A, HIGH); digitalWrite(B, HIGH); digitalWrite(C, LOW);
digitalWrite(D, HIGH); digitalWrite(E, HIGH); digitalWrite(F, LOW); digitalWrite(G, HIGH);
break;
case 3:
digitalWrite(A, HIGH); digitalWrite(B, HIGH); digitalWrite(C, HIGH);
digitalWrite(D, HIGH); digitalWrite(E, LOW); digitalWrite(F, LOW); digitalWrite(G, HIGH);
break;
case 4:
digitalWrite(A, LOW); digitalWrite(B, HIGH); digitalWrite(C, HIGH);
digitalWrite(D, LOW); digitalWrite(E, LOW); digitalWrite(F, HIGH); digitalWrite(G, HIGH);
break;
case 5:
digitalWrite(A, HIGH); digitalWrite(B, LOW); digitalWrite(C, HIGH);
digitalWrite(D, HIGH); digitalWrite(E, LOW); digitalWrite(F, HIGH); digitalWrite(G, HIGH);
break;
case 6:
digitalWrite(A, HIGH); digitalWrite(B, LOW); digitalWrite(C, HIGH);
digitalWrite(D, HIGH); digitalWrite(E, HIGH); digitalWrite(F, HIGH); digitalWrite(G, HIGH);
break;
case 7:
digitalWrite(A, HIGH); digitalWrite(B, HIGH); digitalWrite(C, HIGH);
digitalWrite(D, LOW); digitalWrite(E, LOW); digitalWrite(F, LOW); digitalWrite(G, LOW);
break;
case 8:
digitalWrite(A, HIGH); digitalWrite(B, HIGH); digitalWrite(C, HIGH);
digitalWrite(D, HIGH); digitalWrite(E, HIGH); digitalWrite(F, HIGH); digitalWrite(G, HIGH);
break;
case 9:
digitalWrite(A, HIGH); digitalWrite(B, HIGH); digitalWrite(C, HIGH);
digitalWrite(D, HIGH); digitalWrite(E, LOW); digitalWrite(F, HIGH); digitalWrite(G, HIGH);
break;
default:
digitalWrite(A, LOW); digitalWrite(B, LOW); digitalWrite(C, LOW);
digitalWrite(D, LOW); digitalWrite(E, LOW); digitalWrite(F, LOW); digitalWrite(G, LOW);
break;
}
}