# 📡 Taekwondo Scoring System – Device Signals & Communication Protocol

> **Version:** 2.0 (Full Device Coverage)  
> **Last Updated:** July 2025  
> **Target Developer:** Embedded (ESP32) & Android (.NET) Developers  
> **Purpose:** Define **two-way communication** for **all battery-powered devices**: joysticks, hogu, and headgear

---

## 📌 Table of Contents

- [1. Overview](#1-overview)
- [2. Device Types](#2-device-types)
- [3. Communication Model (TCP Full-Duplex)](#3-communication-model-tcp-full-duplex)
- [4. Common Device Signals](#4-common-device-signals)
- [5. Referee Joystick](#5-referee-joystick)
- [6. Hogu (Trunk Protector)](#6-hogu-trunk-protector)
- [7. Headgear](#7-headgear)
- [8. OLED Display (128x64, I2C 0x3C)](#8-oled-display-128x64-i2c-0x3c)
- [9. Telemetry: Battery & Health Monitoring](#9-telemetry-battery--health-monitoring)
- [10. Feedback: Vibration, LED, Buzzer](#10-feedback-vibration-led-buzzer)
- [11. Command & Response Format](#11-command--response-format)
- [12. ESP32 Code Structure (Modular)](#12-esp32-code-structure-modular)
- [13. Android .NET Server Integration](#13-android-net-server-integration)
- [14. Best Practices](#14-best-practices)

---

## 1. Overview

All **battery-powered devices** in the system support **two-way TCP communication**:

- ✅ **Send**: Sensor data, telemetry, events
- ✅ **Receive**: Feedback commands, display updates, calibration
- ✅ **Device Types**:
  - **Referee Joysticks** (4 units)
  - **Hogu (Trunk Protector)** – Red & Blue
  - **Headgear** – Red & Blue

Each device identifies itself with:
```
DEVICE:NAME=...,TYPE=...,MAC=...
```

---

## 2. Device Types

| Device | Type | Key Features |
|-------|------|-------------|
| **Joystick** | `JOYSTICK` | Button, OLED, vibration, LED, buzzer, battery telemetry |
| **Hogu** | `SENSOR` | Force sensor (FSR), MPU6050 (spinning), OLED, vibration, battery |
| **Headgear** | `SENSOR` | Force sensor, MPU6050, OLED, vibration, battery |

> All use **ESP32-C3**, **LiPo battery**, and **I2C OLED (0x3C)**.

---

## 3. Communication Model (TCP Full-Duplex)

```
[All Devices] ↔ [Android Tablet: TCP Server (Port 5000)]
```

- Devices connect to `192.168.4.1:5000` (hotspot mode)
- First message: `DEVICE:NAME=...,TYPE=...,MAC=...`
- Subsequent messages: JSON `\n`-terminated
- Server can send commands at any time

> Full-duplex: **Send and receive on same connection**.

---

## 4. Common Device Signals

### 4.1 Device Identity (Mandatory First Message)
```
DEVICE:NAME=HOGU_RED,TYPE=SENSOR,MAC=30:85:A9:12:34:56
```

### 4.2 Telemetry (Periodic, Every 60 sec)
```json
{
  "type": "telemetry",
  "device": "HOGU_RED",
  "battery_level": 88,
  "battery_voltage": 4.02,
  "rssi": -65,
  "uptime": 3420,
  "timestamp": 1712345679000
}
```

### 4.3 Command Acknowledgment
```json
{"ack": "vibrate", "time": 1712345679100}
```

---

## 5. Referee Joystick

### 📥 Outgoing
- `button` press
- `telemetry`

### 📤 Incoming Commands
- `vibrate` – tactile feedback
- `buzz` – audible alert
- `led` – status indication
- `display` – show text
- `ping` – liveness check

### Example Button Press
```json
{"type":"button","device":"JOYSTICK_CORNER_1","pressed":true,"time":1712345678905}
```

---

## 6. Hogu (Trunk Protector)

### 📥 Outgoing

#### 6.1 Impact Detection
```json
{
  "type": "impact",
  "device": "hogu_red",
  "force": 850,
  "spinning": true,
  "time": 1712345678901
}
```

- `force`: 0–1023 (analog read)
- `spinning`: from MPU6050 (rotation > 180°)

#### 6.2 Telemetry
Same as joystick, includes sensor health.

---

### 📤 Incoming Commands

| Command | Effect |
|--------|--------|
| `vibrate` | Confirm impact registered |
| `led` | Flash green/red for status |
| `display` | Show "HOGU RED", battery, status |
| `calibrate` | Recalibrate force sensor |
| `ping` | Liveness check |

#### Example: Calibrate Command
```json
{"cmd": "calibrate", "mode": "zero"}
```

---

## 7. Headgear

### 📥 Outgoing

#### 7.1 Impact Detection
```json
{
  "type": "impact",
  "device": "head_blue",
  "force": 720,
  "spinning": false,
  "time": 1712345678903
}
```

> Lower force threshold (safety).

#### 7.2 Telemetry
Same format, sent every 60 sec.

---

### 📤 Incoming Commands

| Command | Effect |
|--------|--------|
| `vibrate` | Confirm head kick detected |
| `led` | Status light (e.g., red = fault) |
| `display` | Show "HEAD BLUE", battery |
| `ping` | Liveness check |

> No `calibrate` — headgear is sealed.

---

## 8. OLED Display (128x64, I2C 0x3C)

All devices have the same OLED for **status and feedback**.

### 8.1 Display Modes

| Device | Normal | Active | Low Battery | Error |
|-------|--------|--------|-------------|-------|
| **Joystick** | `CORNER 1`<br>`READY` | `PRESSED!` | `⚠️ BATT: 20%` | `NO SIGNAL` |
| **Hogu** | `HOGU RED`<br>`OK` | `IMPACT!` | `⚠️ BATT: 15%` | `SENSOR FAULT` |
| **Headgear** | `HEAD BLUE`<br>`ACTIVE` | `HIT DETECTED` | `⚠️ BATT: 10%` | `DISCONNECTED` |

---

### 8.2 Server Command
```json
{
  "cmd": "display",
  "lines": [
    {"text": "HOGU RED", "y": 0},
    {"text": "IMPACT!", "y": 30, "color": "green"}
  ],
  "refresh": true
}
```

---

## 9. Telemetry: Battery & Health Monitoring

### 9.1 Battery Measurement (All Devices)
```cpp
float readBatteryVoltage() {
  int adc = analogRead(BATTERY_PIN);
  float voltage = (adc / 4095.0) * 3.3 * 2.0; // 2:1 divider
  return voltage;
}

int getBatteryLevel(float voltage) {
  if (voltage >= 4.2) return 100;
  if (voltage <= 3.3) return 0;
  return (int)((voltage - 3.3) / 0.9 * 100);
}
```

### 9.2 Telemetry Frequency
- Every **60 seconds**
- Or on **significant change** (e.g., battery drop >5%)

---

## 10. Feedback: Vibration, LED, Buzzer

### 10.1 Pin Assignments (Shared)

| Component | GPIO |
|---------|------|
| Vibration Motor | 4 |
| Buzzer | 5 |
| LED (RGB) | 6 (R), 7 (G), 8 (B) |
| OLED (SDA) | 21 |
| OLED (SCL) | 22 |
| FSR (Hogu) | 34 |
| FSR (Head) | 35 |
| MPU6050 (SCL/SDA) | 21, 22 (shared with OLED) |

> Use **I2C multiplexer** if needed.

---

### 10.2 Feedback Examples

#### Vibrate (200ms)
```json
{"cmd": "vibrate", "duration": 200}
```

#### LED: Green Blink (3 times)
```json
{"cmd": "led", "color": "#00FF00", "mode": "blink", "count": 3}
```

#### Buzzer: Short beep
```json
{"cmd": "buzz", "tone": 1000, "duration": 150}
```

---

## 11. Command & Response Format

### 11.1 Outgoing (Device → Server)
```json
{"type":"impact","device":"head_blue","force":720,"spinning":false,"time":1712345678903}
```
```json
{"type":"telemetry","device":"HOGU_RED","battery_level":88,"rssi":-65,"timestamp":1712345679000}
```

### 11.2 Incoming (Server → Device)
```json
{"cmd":"vibrate","duration":200}
{"cmd":"led","color":"#0000FF","mode":"solid"}
{"cmd":"display","lines":[{"text":"IMPACT!","y":30}]}
{"cmd":"ping"}
```

> Device responds to `ping` with:
```json
{"ack":"ping","time":1712345679100}
```

---

## 12. ESP32 Code Structure (Modular)

Use a **modular design** with shared components:

```
/src/
  ├── main.cpp
  ├── wifi_manager.cpp
  ├── tcp_client.cpp
  ├── oled_display.cpp
  ├── battery_monitor.cpp
  ├── sensors/
  │   ├── fsr.cpp
  │   └── mpu6050.cpp
  ├── feedback/
  │   ├── vibration.cpp
  │   ├── buzzer.cpp
  │   └── led.cpp
  └── device_config.h
```

### Example: `device_config.h`
```cpp
#define DEVICE_NAME "HOGU_RED"
#define DEVICE_TYPE "SENSOR"
#define OLED_ADDR 0x3C
#define BATTERY_PIN 35
#define VIBRO_PIN 4
#define BUZZER_PIN 5
#define LED_PIN 6
```

---

## 13. Android .NET Server Integration

### Send Command to Any Device
```csharp
void SendCommand(string mac, string commandJson)
{
    TcpClient client = GetDeviceByMac(mac);
    if (client?.Connected == true)
    {
        var stream = client.GetStream();
        var writer = new StreamWriter(stream);
        await writer.WriteLineAsync(commandJson);
        await writer.FlushAsync();
    }
}
```

### Example: Confirm Impact
```csharp
// After auto-scoring
SendCommand("30:85:A9:12:34:56", "{\"cmd\":\"vibrate\",\"duration\":200}");
SendCommand("30:85:A9:12:34:56", "{\"cmd\":\"led\",\"color\":\"#00FF00\",\"mode\":\"blink\",\"count\":2}");
```

### Broadcast to All Sensors
```csharp
foreach (var device in GetAllSensors())
{
    SendCommand(device.Mac, "{\"cmd\":\"display\",\"lines\":[{\"text\":\"MATCH START\"}]}");
}
```

---

## 14. Best Practices

| Practice | Why |
|--------|-----|
| Send telemetry every 60 sec | Monitor battery and health |
| Debounce sensor inputs | Prevent false triggers |
| Use I2C for OLED & MPU6050 | Save pins |
| Add `ping` command | Check device liveness |
| Log all commands | Debugging and auditing |
| Low-power mode | Extend battery life |
| Clear OLED on boot | Avoid ghosting |
| Validate MAC before sending | Prevent errors |

