ผู้เขียนบทความ : นายกิตติกร อักษรศรี COE#15
คณะวิศวกรรมศาสตร์ สาขาวิศวกรรมคอมพิวเตอร์
วิชา : 04-513-201 การโปรเเกรมคอมพิวเตอร์ขั้นสูง
1.ความเป็นมา
โครงงาน Scoreboard ฟุตบอล สร้างขึ้นมาเพื่อความสะดวกสบายในการแสดงผลข้อมูลแบบเรียลไทม์และเพื่อความรวดเร็วและแม่นยำของผลคะแนนในการแข่งขันกีฬาฟุตบอลโดยใช้แพลตฟอร์มที่มีชื่อว่า Blynk ในการควบคุมผลคะแนนต่างๆบนหน้าจอ LCD ซึ่งสามารถควบคุมผลคะแนนระยะไกลได้โครงงาน Scoreboard เกิดขึ้นมาเพราะบางสถานที่ เช่นโรงเรียน หรือ มหาลัย บางแห่งที่มีการจัดกิจกรรมการแข่งขันกีฬาฟุตบอลยังใช้ Scoreboard แบบ Manual ซึ่งทำให้เกิดความล่าช้าในการเปลี่ยนผลคะแนน หรืออาจจะเกิดข้อผิดพลาดต่างๆขึ้นได้
ด้วยเหตุนี้ จึงเกิดเป็นโครงงาน Scoreboard ฟุตบอลควบคุมผ่าน Blynk ขึ้นมาเพื่อตอบสนองปัญหาเหล่านี้ รวมถึงความสะดวกสบายในการเปลี่ยนผลคะเเนนที่รวดเร็ว
2.วัตถุประสงค์
2.1 เพื่อเเสดงผลคะเเนนเเละเปลี่ยนผลคะเเนนได้เเบบเรียลไทม์
2.2 เพื่อความสะดวกสบายในการใช้งาน
2.3 เพื่อรับรู้ถึงการเกิดเหตุการณ์สำคัญที่เกิดขึ้นได้ด้วยเสียงจาก Buzzer
2.4 เพื่อความรวดเร็วเเละความเเม่นยำ
3.ขอบเขต
3.1 เเสดงผลคะเเนนเเละเปลี่ยนคะเเนนของเเต่ละทีมได้เเบบเรียลไทม์
3.2 เปลี่ยนผลคะเเนนระยะไกลได้ผ่านเเพลตฟอร์ม Blynk
3.3 มีเสียงจาก Buzzer ดังขึ้นเมื่อเกิดเหตุการณ์สำคัญ
4.ประโยชน์ที่คิดว่าจะได้รับ
4.1 ทำให้เราได้ศึกษาการใช้งานบอร์ด ESP32 ในการควบคุมเเละสั่งการไปยังอุปกรณ์ตัวอื่น
4.2 สามารถนำไปต่อยอดเเละเพิ่มมูลค่าได้
4.3 ความสะดวกสบายในการใช้งาน
5.ความรู้ที่เกี่ยวข้อง
5.1 Arduino IDE
- Arduino IDE เป็นโปรแกรมที่ “แจกฟรี” ในการใช้งานลักษณะ Open source ซึ่ง Arduino IDE จะทำหน้าที่ ติดต่อระหว่างคอมพิวเตอร์ ไม่ว่าจะเป็นระบบWindows, Mac OS X หรือ Linux กับ บอร์ด Arduino ซึ่งโปรแกรมนี้ออกแบบให้ง่ายต่อการเขียนโค้ดและอัปโหลดโปรแกรมที่เราเขียนเข้าสู่บอร์ด Arduino
- Arduino IDE ส่วน IDE ย่อมาจก (Integrated Development Environment) คือ ส่วนเสริมของระบบการพัฒนา หรือตัวช่วยต่าง ๆ ที่จะคอยช่วยเหลือ Developer หรือช่วยเหลือคนที่พัฒนา Application เพื่อเสริมให้เกิดความรวดเร็ว ถูกต้อง แม่นยำ ตรวจสอบระบบที่จัดทำได้ ทำให้การพัฒนางานต่าง ๆ เร็วมากขึ้น
- ส่วนในการเขียนโปรแกรมและคอมไพล์ลงบอร์ด โดยขนาดของโปรแกรม Arduino โดยปกติแล้วจะใหญ่กว่าโค้ด AVR ปกติเนื่องจากโค้ด AVR เป็นการเข้าถึงจากรีจิสเตอร์โดยตรง แต่โค้ด Arduino เข้าถึงผ่านฟังก์ชั่น เพื่อให้สามารถเขียนโค้ดได้ง่ายมากกว่าการเขียนโค้ดแบบ AVR หรือเวอร์ชั่นอื่นๆ ของ Arduino
5.2 Blynk
แอปพลิเคชันสำเร็จรูปที่ใช้สำหรับงานที่เกี่ยวกับอินเทอร์เน็ตของสรรพสิ่ง (Internet of Things, IoT) ที่ทำให้เราสามารถเชื่อมต่ออุปกรณ์ต่าง ๆ เข้ากับอินเทอร์เน็ตในลักษณะการเชื่อมต่อเครื่องแม่ข่าย (Server) ไปยังอุปกรณ์ลูกข่าย (Client) เช่น Arduino, ESP-8266, ESP-32, NodeMCU และ Raspberry Pi ซึ่งแอปพลิเคชัน Blynk สามารถใช้งานได้ฟรีและใช้งานได้ทั้งบนระบบปฏิบัติการ IOS และ Android รูปที่ 12.2 แสดงภาพรายการอุปกรณ์ต่าง ๆ ที่สามารถเชื่อมต่อ แสดงผล และ/หรือ ควบคุมด้วย Blynk App ได้ โดยเริ่มต้นหลังจากสมัครเข้าใช้งาน เราจะได้รับ “Energy” ซึ่งเปรียบเสมือนเงินในโปรแกรมนี้ ในการเรียกใช้งานอุปกรณ์แต่ละตัว เราจะต้องแลกด้วย “Energy” และหาก “Energy” นี้ไม่เพียงพอ เราก็สามารถซื้อเพิ่มเติมได้ภายหลัง
—-5.2.1 <BlynkSimpleEsp32.h>
ซึ่งเป็นไลบรารี่ที่ใช้ในการเรียกใช้ Blynk ในการควบคุมผลคะเเนนบนหน้าจอ LCD
#define BLYNK_TEMPLATE_ID "TMPL6r5ljVw0f" // BLYNK ID
#define BLYNK_TEMPLATE_NAME "Scoreboard" // BLYNK NAME
#define BLYNK_AUTH_TOKEN "f5mkAZF7kbmGwPJFYFIzQRoAokn4dk9w" // BLYNK TOKEN
เรียกใช้งาน
char auth[] = BLYNK_AUTH_TOKEN; // BLYNK TOKEN
char ssid[] = "POCO F3"; // ชื่อ WiFi
char pass[] = "0997015275"; // รหัส WiFi
กำหนด WiFi Name, WiFi Password และ AuthToken
6.ผลการดำเนินการ
Diagram เป็นภาพรวมการทำงานของระบบ เพื่อทำให้เข้าใจการทำงานของระบบมากขึ้น โดยจะมีขั้นตอนการทำงานดังนี้
- Switching 12V 5A ต่อไปยัง Stepdown เพื่อลดไฟที่จ่ายไปยังบอร์ด ESP32 ให้เหลือ 5V เพราะบอร์ด ESP32 รับไฟได้เเค่ 5V
- Blynk ทำหน้าที่ในการควบคุมผลคะเเนนบนหน้าจอ LCD โดยใช้บอร์ด ESP32 เป็นสื่อกลาง
- Buzzer ทำหน้าที่ในการส่งเสียงเเจ้งเตือนเมื่อมีการกดปุ่มจาก Blynk โดยใช้บอร์ด ESP32 เป็นสื่อกลาง
โค้ดในส่วนของการประกาศตัวเเปร, กำหนดขนาดของหน้าจอ LCD เเละกำหนดขารับสัญญาณของ Buzzer
LiquidCrystal_I2C lcd(0x27, 20, 4); // กำหนดขนาดของจอ LCD
int scoreTeam1 = 0; // ประกาศตัวเเปร
int scoreTeam2 = 0; // ประกาศตัวเเปร
bool blueGoal = false; // ประกาศตัวเเปร
bool redGoal = false;
unsigned long goalTimer = 0; // ประกาศตัวเเปร
int buzzerPin = 23; // ประกาศตัวเเปร
unsigned long lasttime; // ประกาศตัวเเปร
bool isCounting = false; // ประกาศตัวเเปร
bool pauseCounting = false; // ประกาศตัวเเปร
int sec, m; // ประกาศตัวเเปร
โค้ดในส่วนของการกำหนด Buzzer ให้เป็น OUTPUT, กำหนดการเเสดงผลบนหน้าจอ LCD เเละกำหนด Mode ปุ่มใน Blynk
void setup() {
pinMode(buzzerPin, OUTPUT); // กำหนด buzzerPin ให้เป็น OUTPUT
Blynk.begin(auth, ssid, pass); // เรียกใช้งาน auth, ssid, pass
lcd.init(); // เริ่มต้นใช้งานจอ LCD
lcd.backlight(); // เปิดไฟ backlight
lcd.clear(); // เคลียค่าที่เเสดงอยู่บนหน้าจอ LCD
lcd.setCursor(5, 0); // กำหนดตำเเหน่งที่ 5 บรรทัดที่ 0
lcd.print("Scoreboard"); // ให้จอ LCD พิมพ์ Scoreboard
lcd.setCursor(0, 1); // กำหนดตำเเหน่งที่ 0 บรรทัดที่ 1
lcd.print("Blue team : 0"); // ให้จอ LCD พิมพ์ Blue team : 0
lcd.setCursor(0, 2); // กำหนดตำเเหน่งที่ 0 บรรทัดที่ 2
lcd.print("Red team : 0"); // ให้จอ LCD พิมพ์ Red team : 0
lcd.setCursor(0, 3); // กำหนดตำเเหน่งที่ 0 บรรทัดที่ 3
lcd.print("Time: 0m 0s"); // ให้จอ LCD พิมพ์ Red team : 0
Blynk.setProperty(V0, "mode", "PUSH"); // กำหนดปุ่มใน Blynk ให้เป็นขา V0
Blynk.setProperty(V1, "mode", "PUSH"); // กำหนดปุ่มใน Blynk ให้เป็นขา V1
Blynk.setProperty(V2, "mode", "PUSH"); // กำหนดปุ่มใน Blynk ให้เป็นขา V2
Blynk.setProperty(V3, "mode", "PUSH"); // กำหนดปุ่มใน Blynk ให้เป็นขา V3
Blynk.setProperty(V4, "mode", "PUSH"); // กำหนดปุ่มใน Blynk ให้เป็นขา V4
Blynk.setProperty(V5, "mode", "PUSH"); // กำหนดปุ่มใน Blynk ให้เป็นขา V5
}
โค้ดในส่วนของการเรียกใช้ Blynk, ฟังก์ชั่นเริ่มนับเวลา/หยุดนับเวลาเมื่อมีการกดปุ่ม, รับค่าเเละสั่งการต่างๆเมื่อมีการกดปุ่ม เเละฟังก์ชั่นเพิ่มคะเเนน/ลดคะเเนน
void loop() {
Blynk.run(); // ใช้งาน Blynk
if (blueGoal || redGoal) { // เงื่อนไขเช็ค blueGoal || redGoal เพื่อถ้าเกิดมีการเพิ่มคะเเนน LCD จะทำการอัพเดดข้อมูล
if (millis() - goalTimer >= 900) {
blueGoal = false;
redGoal = false;
updateLCD();
digitalWrite(buzzerPin, HIGH);
}
}
if (isCounting && !pauseCounting) { // เช็ค isCounting && !pauseCounting เพื่อจับเวลาการเล่น
if(millis() - lasttime >= 1000){ // ฟังชั่นการนับเวลาเพิ่มทุกๆ 1 วิ
lasttime = millis();
sec++;
if(sec >= 60){
m++;
sec=0;
}
if(m == 0 && sec == 0){ // เมื่อ m == 0 && sec == 0 คือเริ่มเกมส์ให้มีเสียง buzzer ยาว 2 วิ
digitalWrite(buzzerPin, LOW);
delay(2000);
digitalWrite(buzzerPin, HIGH);
}
}
lcd.setCursor(0, 3); // กำหนดตำเเหน่งที่ 0 บรรทัดที่ 3
lcd.print("Time: " + String(m) + "m " + String(sec) + "s "); // ให้จอ LCD พิมพ์ Red team : 0
}
}
BLYNK_WRITE(V0) { // เมื่อมีการกดปุ่ม V0
if (param.asInt() == 1) { // จะทำการเเพิ่มคะเเนนของทีม BLUE และมีเสียง buzzerPin ดัง
if (!blueGoal) {
blueGoal = true;
goalTimer = millis();
addScoreTeam1(1);
lcd.clear();
lcd.setCursor(5, 1);
lcd.print("BLUE TEAM");
lcd.setCursor(7, 2);
lcd.print("GOAL!!");
digitalWrite(buzzerPin, LOW);
delay(300);
digitalWrite(buzzerPin, HIGH);
delay(300);
digitalWrite(buzzerPin, LOW);
delay(300);
}
}
}
BLYNK_WRITE(V1) { // เมื่อมีการกดปุ่ม V1
if (param.asInt() == 1) { // จะทำการเพิ่มคะเเนนของทีม RED และมีเสียง buzzerPin ดัง
if (!redGoal) {
redGoal = true;
goalTimer = millis();
addScoreTeam2(1);
lcd.clear();
lcd.setCursor(5, 1);
lcd.print(" RED TEAM ");
lcd.setCursor(7, 2);
lcd.print("GOAL!!");
digitalWrite(buzzerPin, LOW);
delay(300);
digitalWrite(buzzerPin, HIGH);
delay(300);
digitalWrite(buzzerPin, LOW);
delay(300);
}
}
}
BLYNK_WRITE(V2) { // เมื่อมีการกดปุ่ม V2
if (param.asInt() == 1) { // จะทำการลดคะเเนนของทีม BLUE
subtractScoreTeam1(1);
updateLCD();
}
}
BLYNK_WRITE(V3) { // เมื่อมีการกดปุ่ม V3
if (param.asInt() == 1) { // จะทำการลดคะเเนนของทีม RED
subtractScoreTeam2(1);
updateLCD();
}
}
BLYNK_WRITE(V4) { // เมื่อมีการกดปุ่ม V4
if (param.asInt() == 1) { // จะทำการรีเซ็ตคะเเนนของทั้งสองทีม
resetScores();
updateLCD();
}
}
BLYNK_WRITE(V5) { // เมื่อมีการกดปุ่ม V5
if (param.asInt() == 1) { // จะมีการเช็คเงื่อนไขต่อไปนี้
if (isCounting && !pauseCounting) { // เมื่อ isCounting && !pauseCounting คือการ หยุดการนับเวลา
pauseCounting = true;
} else if (isCounting && pauseCounting) { // เมื่อ isCounting && pauseCounting คือการ นับเวลาต่อ
pauseCounting = false;
} else if (!isCounting && !pauseCounting){ // เมื่อ !isCounting && !pauseCounting คือการเริ่มนับเวลาใหม่
isCounting = true;
pauseCounting = false;
if(m == 0 && sec == 0){ // เมื่อ m == 0 && sec == 0 คือเริ่มเกมส์ให้มีเสียง buzzer ยาว 2 วิ
digitalWrite(buzzerPin, LOW);
delay(2000);
digitalWrite(buzzerPin, HIGH);
}
}
}
}
void addScoreTeam1(int increment) { //ฟังชั่น เพิ่ม-ลด คะเเนน
scoreTeam1 += increment;
}
void addScoreTeam2(int increment) {
scoreTeam2 += increment;
}
void subtractScoreTeam1(int decrement) {
scoreTeam1 -= decrement;
}
void subtractScoreTeam2(int decrement) {
scoreTeam2 -= decrement;
}
โค้ดในส่วนของการรีเซ็ตคะแนน/รีเซ็ตเวลาบนจอ LCD เเละสั่งการให้มีเสียง buzzer ดังขึ้นเมื่อมีการรีเซ็ตหน้าจอเปรียบเสมือนจบการเเข่งขัน
void resetScores() { // ฟังชั่นรีเซ็ตคะแนน เเละรีเซ็ตเวลา เเละมีเสียง buzzer จบเกมส์
scoreTeam1 = 0;
scoreTeam2 = 0;
sec = 0;
m = 0;
isCounting = false;
pauseCounting = false;
digitalWrite(buzzerPin, LOW);
delay(500);
digitalWrite(buzzerPin, HIGH);
delay(250);
digitalWrite(buzzerPin, LOW);
delay(500);
digitalWrite(buzzerPin, HIGH);
delay(250);
digitalWrite(buzzerPin, LOW);
delay(1000);
digitalWrite(buzzerPin, HIGH);
}
โค้ดในส่วนของการ Update การเเสดงผลบนหน้าจอ LCD
void updateLCD() { // ฟังชั่นอัพเดดข้อมูลบนจอ LCD
lcd.clear();
lcd.setCursor(5, 0);
lcd.print("Scoreboard"); // Add "Scoreboard" text to the first line
lcd.setCursor(0, 1);
lcd.print("Blue team : " + String(scoreTeam1));
lcd.setCursor(0, 2);
lcd.print("Red team : " + String(scoreTeam2));
lcd.setCursor(0, 3); // Move to the fourth line
lcd.print("Time: " + String(m) + "m " + String(sec) + "s ");
}
การทดลอง
การทดลองที่ 1 คือการทดลองในส่วนของการแสดงผลเพิ่มคะแนน/ลดคะแนน เเละเริ่มนับเวลา/หยุดเวลา บนหน้าจอ LCD โดยควบคุมผ่าน Blynk
ผลการทดลองที่ได้
การทดลองที่ 2 คือการทดลองให้ Buzzer ดังเมื่อกดปุ่มเพิ่มคะแนน/เริ่มนับเวลาและReset
ผลการทดลองที่ได้
7.สรุปผลการทดลองเเละข้อเสนอเเนะ
สรุปผลการทดลอง ระบบควบคุมผลคะแนนบนจอ LCD, ระบบเริ่มนับเวลาหยุดเวลาและระบบเสียงจาก Buzzer เมื่อมีการกดปุ่มผ่าน Blynk ทำงานได้อย่างมีประสิทธิภาพเเละตรงตามเงื่อนไขตามที่กำหนดไว้ ได้แก่
- เมื่อกดปุ่มข้อความแสดงบนจอ LCD ได้ตามที่กำหนด
- Buzzer ดังได้ตามที่กำหนดไว้เมื่อกดปุ่ม
- Blynk สามารถสั่งการเพิ่มคะแนน/ลดคะแนน, เริ่มนับเวลา/หยุดนับเวลา และ Reset หน้าจอ LCD ได้ตามที่กำหนดไว้
ข้อเสนอเเนะ
- สามารถนำชิ้นงานไปต่อยอดเป็น Scoreboard อันใหญ่ได้ เพื่อเพิ่มลูกเล่นเเละฟังก์ชั่นต่างๆในการเเสดงผลให้มีความน่าสนใจมากยิ่งขึ้น
- สามารถนำชิ้นไปพัฒนาในส่วนของเสียงการเเจ้งเตือนเมื่อเกิดเหตุการณ์สำคัญในการเเข่งขัน จากเดิมที่เเจ้งเตือนเสียงด้วย Buzzer อาจพัฒนาเป็นการเเจ้งเตือนด้วยเสียง AI ผ่าน Speaker โดยใช้บอร์ดโมดูล MP3 ในการขยายเสียงเเละส่งไปยัง Speaker
8.ข้อมูลอ้างอิง
8.1 ต้นฉบับ เคเอ็น พลูปริทวิราช, เอ็น มาเฮช, เอ็มเอส โมเนช, ซี ปรา เนชราช, ส วรุณ, วันที่เพิ่มใน IEEE Xplore : 07 กรกฎาคม
2566 สืบค้นจาก https://ieeexplore.ieee.org/document/10169251/authors#authors
8.2 LCD สอนใช้งาน ESP32 กับ LCD CyberTice, 07 ธันวาคม 2565 สืบค้นจาก สอนใช้งาน ESP32 2004 LCD 20×4 โมดูลจอแสดงผล LCD พร้อม I2C Interface – ขาย Arduino อุปกรณ์ Arduino คุณภาพดี ราคาถูก ส่งไว ส่งฟรี (cybertice.com)
8.3 Buzzer สอนใช้งาน ESP32 กับ โมดูลสัญญาณเสียง Active Buzzer Module 3.3 – 5V CyberTice, 25 กรกฎาคม 2565 สืบค้นจาก สอนใช้งาน ESP32 โมดูลสัญญาณเสียง Active Buzzer Module 3.3 – 5V – ขาย Arduino อุปกรณ์ Arduino คุณภาพดี ราคาถูก ส่งไว ส่งฟรี (cybertice.com)