# 🥋 Taekwondo Electronic Scoring System – Developer Documentation > **Version:** 4.0 (Final & Complete) > **Last Updated:** July 2025 > **Target Developer:** .NET Android (MAUI/Xamarin) with TCP experience > **Project Goal:** Build a **fully automated, secure, broadcast-quality** Taekwondo scoring system that works **without any technical knowledge** from referees or staff. --- ## 📌 Table of Contents - [1. System Overview](#1-system-overview) - [2. Network Setup (Zero-Config Wi-Fi Hotspot)](#2-network-setup-zero-config-wi-fi-hotspot) - [3. Device Connection & Discovery](#3-device-connection--discovery) - [4. Device Identity Format (NAME, TYPE, MAC)](#4-device-identity-format-name-type-mac) - [5. Score Control App (Android Tablet)](#5-score-control-app-android-tablet) - [6. Android TV Apps](#6-android-tv-apps) - [7. Scoring Rules & Auto-Scoring Logic](#7-scoring-rules--auto-scoring-logic) - [8. Scoreboard Display Requirements](#8-scoreboard-display-requirements) - [9. Match Presentation Flow](#9-match-presentation-flow) - [10. Match Management](#10-match-management) - [11. Result Logging](#11-result-logging) - [12. Security & Validation](#12-security--validation) - [13. Full JSON Message Examples](#13-full-json-message-examples) - [14. Developer To-Do List](#14-developer-to-do-list) - [15. Appendix: Resources](#15-appendix-resources) --- ## 1. System Overview This system automates **Taekwondo sparring (kyorugi)** scoring for **clubs, tournaments, and non-technical users**. ### 🎯 Key Principles - **No IP, port, or network configuration** required - **Center referee has no device** — uses only voice and hand signals - **Scorekeeper** uses an Android tablet to manage the system - **All devices auto-connect** to a self-hosted Wi-Fi network - **Fully automatic scoring** based on sensors and corner referee votes - **Broadcast-quality display flow** for audience engagement ### 🧩 Components | Device | Role | |-------|------| | **Android Tablet** | TCP server, score control, match manager | | **ESP32-C3 Sensors** | Detect impact on hogu and headgear | | **ESP32-C3 Joysticks** | Corner referee voting (4 units) | | **Android TV 1** | Live scoreboard (ring display) | | **Android TV 2** | Upcoming matches (lobby display) | All devices connect via Wi-Fi and identify themselves securely. --- ## 2. Network Setup (Zero-Config Wi-Fi Hotspot) To eliminate technical barriers, the **Android tablet creates its own Wi-Fi network**. ### 📶 Wi-Fi Settings - **SSID**: `TKD_SCORING_COURT1` - **Password**: `taekwondo123` (default, printed on device label) - **Tablet IP**: `192.168.4.1` (fixed in hotspot mode) - **Server Ports**: - TCP: `5000` (data) - UDP: `5002` (discovery) ### 🔧 How It Works 1. Scorekeeper powers on tablet 2. App **automatically enables Wi-Fi hotspot** 3. Staff connects all devices to `TKD_SCORING_COURT1` 4. Devices **auto-discover and connect** to `192.168.4.1` 5. No user enters IP or port > ✅ Works **offline** — no internet required. --- ## 3. Device Connection & Discovery All devices **auto-discover** the server and connect with zero input. ### 🔄 Connection Flow 1. Device powers on → connects to `TKD_SCORING_COURT1` 2. Sends UDP broadcast: ```text TKD_DISCOVER ``` 3. Tablet responds: ```text SERVER_IP:192.168.4.1 ``` 4. Device connects to `192.168.4.1:5000` 5. Sends identity: ``` DEVICE:NAME=HOGU_RED,TYPE=SENSOR,MAC=30:85:A9:12:34:56 ``` 6. Server validates and registers ### 📱 Android TV Setup - Pre-install app - Auto-connect to `TKD_SCORING_COURT1` - App starts on boot and connects to server --- ## 4. Device Identity Format (NAME, TYPE, MAC) Every device must send this **exact format** as the **first line** after connection: ``` DEVICE:NAME=,TYPE=,MAC= ``` | Field | Description | Example | |------|-------------|--------| | `NAME` | Descriptive name | `HOGU_RED`, `JOYSTICK_CORNER_1`, `TV_SCOREBOARD` | | `TYPE` | Device category | `SENSOR`, `JOYSTICK`, `DISPLAY` | | `MAC` | Uppercase, colon-separated | `30:85:A9:12:34:56` | ### ✅ Valid Examples ``` DEVICE:NAME=HOGU_RED,TYPE=SENSOR,MAC=30:85:A9:12:34:56 ``` ``` DEVICE:NAME=HEAD_BLUE,TYPE=SENSOR,MAC=30:85:A9:12:34:57 ``` ``` DEVICE:NAME=JOYSTICK_CORNER_1,TYPE=JOYSTICK,MAC=30:85:A9:12:34:58 ``` ``` DEVICE:NAME=TV_SCOREBOARD,TYPE=DISPLAY,MAC=18:3D:A2:01:02:03 ``` ### 🛠️ ESP32: Get MAC Address ```cpp #include String getMacAddress() { uint8_t mac[6]; WiFi.macAddress(mac); char macStr[18]; sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); return String(macStr); } ``` ### 🖥️ Server: Parse Identity (C#) ```csharp Dictionary ParseDeviceIdentity(string line) { var result = new Dictionary(); if (!line.StartsWith("DEVICE:")) return result; var parts = line.Substring(7).Split(','); foreach (var part in parts) { var kv = part.Split('='); if (kv.Length == 2) result[kv[0]] = kv[1]; } return result; } ``` --- ## 5. Score Control App (Android Tablet) Built with **.NET MAUI / Xamarin**, this app is the **central brain**. ### 🎯 Responsibilities - Act as **TCP server** (Port 5000) - Receive sensor/joystick data - Apply **WT scoring rules** - Control **Android TV displays** (Port 5001) - Manage **match lifecycle** - Log results - Monitor connected devices ### 🖼️ UI Screens #### 🏁 Home Screen ``` [Start Setup Mode] ``` #### 🔍 Setup Mode - Auto-detects devices: ``` ✅ HOGU_RED ✅ HEAD_BLUE 🔔 Waiting for JOYSTICK_CORNER_1... ``` - When all found: ``` [Lock System & Start Match] ``` #### ⚔️ Live Match Screen - Timer (2:00) - Score: 🔴 4 vs 2 🔵 - Event log - Referee vote indicators - Controls: `Shi-jak`, `Kal-yeo`, `Next Round` #### 🖥️ Device Monitor | MAC | Name | Type | Status | |-----|------|------|--------| | 30:.. | HOGU_RED | SENSOR | ✅ | --- ## 6. Android TV Apps ### 📺 TV 1: Scoreboard App (Ring Display) #### Modes - `faceoff`: Fighter face-off - `score`: Live scoring - `break`: Ads + highlights - `call_to_action`: "Fighters, return!" - `winner`: Winner celebration #### Connection - Connects to `192.168.4.1:5001` - Sends device identity --- ### 📺 TV 2: Match Display App (Lobby) #### Features - Scrollable list of next 3–5 matches - Pulls from CSV or cloud - Tournament logo and sponsors #### Connection - Same as above, name: `TV_MATCH_DISPLAY` --- ## 7. Scoring Rules & Auto-Scoring Logic Based on **World Taekwondo (WT) 2024 rules**. ### ✅ Valid Techniques | Technique | Points | |---------|--------| | Kick to trunk | 1 | | Kick to head | 3 | | Spinning kick to trunk | 4 | | Spinning kick to head | 5 | | Punch to trunk | 1 | | Gam-jeom (penalty) | +1 to opponent | > ❗ **No input from center referee** — only voice and signals. --- ### 🔄 Auto-Scoring Logic A point is awarded if: 1. Sensor detects impact (force > threshold) 2. **≥3 out of 4 corner referees** press within **1 second** 3. For spinning kicks: MPU6050 confirms rotation > 180° #### Force Thresholds - **Hogu**: ≥ 500 (analog) or 800g - **Head**: ≥ 400 (for safety) #### Timing Window - Referee button presses must be within **±1 second** of impact - Debounce: Ignore same sensor hits within 500ms ```csharp void CheckForValidPoint(ImpactEvent impact) { var votes = GetJoystickPressesInRange(impact.Time, 1000); if (votes.Count >= 3) { int points = CalculatePoints(impact); AddPoints(impact.Attacker, points); BroadcastScoreUpdate(); } } ``` --- ## 8. Scoreboard Display Requirements The main scoreboard displays **13 elements**: | # | Element | Source | |---|--------|--------| | 1 | Court Number | Match data | | 2 | Match Number | Schedule | | 3 | Match Timer | App timer | | 4 | Round Counter | Match state | | 5 | Country Flag | Fighter data | | 6 | Country ISO3 | Fighter data | | 7 | Team Logo | Fighter data | | 8 | Fighter Name | Match setup | | 9 | Fighter Score | Scoring engine | | 10 | Fighter Fouls | Penalty tracker | | 11 | Fighter Weight (kg) | Fighter profile | | 12 | Weight Class & Category | Match data | | 13 | Team Name | Fighter data | ### 🎨 Example Layout ``` COURT 1 MATCH #105 ROUND 2/3 MEN'S -68KG SEMIFINAL 🇰🇷 KIM Min-jae vs LEE Jung-ho 🇨🇳 Seoul TKD Club vs Beijing TKD [Logo] vs [Logo] 8 vs 5 ⚠️ ⚠️⚠️ ⏱️ 01:45 67.2 kg 67.8 kg ``` --- ## 9. Match Presentation Flow ### 1. Face-Off (10 sec) - Fighter photos, names, flags - Before "Shi-jak" ### 2. Live Scoring (2:00) - Real-time score, timer, fouls ### 3. Break (60 sec) - 0–50 sec: Sponsor ad - 50–58 sec: Round highlights (video) - 58–60 sec: Fade to next phase ### 4. Call to Action (10 sec) - Full-screen: "FIGHTERS, RETURN TO THE RING!" - Flashing text, sound cues at 5 and 1 sec ### 5. Winner Screen (15 sec) - Winner enlarged - Confetti animation - Final score --- ## 10. Match Management Matches can be created in three ways: ### 1. Single Match (Manual) - Enter red/blue names, weight, team - Ideal for training ### 2. CSV Import ```csv match_id,red_name,blue_name,weight,round,red_country,blue_country,red_photo,blue_photo M101,Kim,Lee,-58kg,Quarter,KOR,CHN,https://...,https://... ``` ### 3. Cloud API Sync - GET `https://api.tournament.com/matches` - Polls every 60 seconds ### 🔄 Auto-Advance After match ends: 1. Log result 2. Load next match 3. Show face-off on TVs 4. Wait for "Start Match" --- ## 11. Result Logging After each match, results are saved. ### 📄 JSON Format ```json { "match_id": "M105", "court": "1", "weight_class": "Men's -68kg", "round": "Final", "red": { "name": "Kim", "team": "Seoul", "score": 8, "fouls": 1 }, "blue": { "name": "Lee", "team": "Beijing", "score": 5, "fouls": 2 }, "winner": "red", "duration": 180, "timestamp": "2025-07-10T11:15:30Z" } ``` ### 💾 Export Options - Save to `Documents/results.json` - Append to `results.csv` - POST to cloud API - Share via email or USB --- ## 12. Security & Validation ### 🔐 Allowed Device List - Server has **pre-loaded list** of allowed MAC addresses - Stored in app (JSON or SQLite) - Unknown devices are **ignored silently** ### 🚫 Connection Rules - After "Lock System" → **no new connections** - Disconnected device → **can only rejoin in Setup Mode** - Only devices with correct `TYPE` and `NAME` are accepted --- ## 13. Full JSON Message Examples ### From Sensor ```json {"type":"impact","device":"head_blue","force":900,"spinning":true,"time":1712345678901} ``` ### From Joystick ```json {"type":"button","device":"corner_2","pressed":true,"time":1712345678905} ``` ### To Scoreboard TV ```json { "mode": "score", "court": "1", "match_number": "105", "weight_class": "Men's -68kg", "category": "Semifinal", "round": "2", "timer": "01:45", "red": { "name": "Kim Min-jae", "country": "KOR", "team": "Seoul TKD Club", "logo": "https://logos/seoul.png", "flag": "https://flags/kor.png", "score": 8, "fouls": 1, "weight_kg": 67.2 }, "blue": { "name": "Lee Jung-ho", "country": "CHN", "team": "Beijing TKD", "logo": "https://logos/beijing.png", "flag": "https://flags/chn.png", "score": 5, "fouls": 2, "weight_kg": 67.8 } } ``` --- ## 14. Developer To-Do List | Task | Status | |------|--------| | Implement Wi-Fi hotspot mode (Android) | ☐ | | Build TCP server (Port 5000) | ☐ | | Implement UDP discovery (Port 5002) | ☐ | | Parse device identity (NAME,TYPE,MAC) | ☐ | | Validate devices against allowed list | ☐ | | Implement auto-scoring logic | ☐ | | Design Match Setup UI with all fields | ☐ | | Add country flag, team logo support | ☐ | | Send rich scoreboard JSON (13 fields) | ☐ | | Create Android TV apps | ☐ | | Support video playback for highlights | ☐ | | Implement break mode with ads | ☐ | | Add call-to-action screen | ☐ | | Create winner screen with animation | ☐ | | Add match flow timer engine | ☐ | | Implement CSV import with all fields | ☐ | | Implement Cloud API sync | ☐ | | Add match auto-advance | ☐ | | Implement result logging (file + API) | ☐ | | Export results to CSV | ☐ | | Add Device Monitor screen | ☐ | --- ## 15. Appendix: Resources - [.NET TCP](https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.tcpclient) - [Android Wi-Fi Hotspot API](https://developer.android.com/reference/android/net/wifi/WifiManager) - [UDP in .NET](https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.udpclient) - [ESP32 Arduino](https://github.com/espressif/arduino-esp32) - [CSV Helper](https://joshclose.github.io/CsvHelper/) - [ExoPlayer (Video)](https://github.com/google/ExoPlayer) - [Android TV](https://developer.android.com/tv) Hardware: ESP32-C3, FSR, MPU6050, push buttons, batteries Testing: `telnet 192.168.4.1 5000`, Wireshark, Serial Monitor