สกอร์บอร์ดฟุตบอลควบคุมผ่าน Blynk

ผู้เขียนบทความ : นายกิตติกร อักษรศรี 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)

วิดีโอนำเสนอการทำงานของ Scoreboard ฟุตบอลควบคุมผ่าน Blynk

You may also like...

ใส่ความเห็น

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *