# DWIN_UNI_HMI Library

[![Arduino Library](https://img.shields.io/badge/Arduino-Library-blue.svg)](https://www.arduino.cc/)
[![Platform](https://img.shields.io/badge/Platform-ESP32%20|%20STM32%20|%20Mega-orange.svg)](https://platformio.org/)
[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
[![Version](https://img.shields.io/badge/version-1.2.0-blue.svg)](https://github.com/askinkeles/DWIN_UNI_HMI)

**A Universal, Event-Driven, and Non-Blocking library for DWIN DGUS II T5L Displays.**

Designed for industrial reliability, this library supports **ESP32, STM32, and Arduino Mega** platforms via the standard `Stream` interface. It simplifies complex HMI tasks like 32-bit data transfer, dynamic text updates, and system controls without blocking your main loop.

---

## 🛠️ Reference Hardware

This library has been developed and strictly tested with the following industrial hardware setup:

| Component | Model / Spec | Description |
| :--- | :--- | :--- |
| **HMI Display** | **DMG48270C043_03WTR** | 4.3", 480x272, Resistive Touch, T5L ASIC |
| **Controller** | **ESP32 Dev Kit V1** | 240MHz Dual Core, WiFi/BT, 3.3V Logic |
| **Protocol** | **UART (TTL)** | 8N1, 115200 Baud Rate |

> **Note:** While tested on the 4.3" resistive model, this library is compatible with **ALL DWIN DGUS II (T5L)** displays regardless of size or touch type (Capacitive/Resistive).

---

## 🔌 Wiring & Connection Diagram

**Warning:** DWIN T5L Displays typically require **5V power**. Do not power large screens directly from the ESP32's 5V pin if the USB current is insufficient; use an external 5V source if needed.

![Wiring Diagram](extras/pictures/connection_diagram.png)

### Pinout Table (ESP32 Example)

| ESP32 Pin | DWIN Pin | Function |
| :--- | :--- | :--- |
| **GPIO 16** (RX2) | **TX** | Receive Data from Display |
| **GPIO 17** (TX2) | **RX** | Send Commands to Display |
| **GND** | **GND** | **Common Ground (Required)** |
| **5V / 3.3V** | **VCC** | Power Supply |

---

## 🚀 Key Features

* **Universal Compatibility:** Works with `HardwareSerial`, `SoftwareSerial`, or any class implementing the Arduino `Stream` interface.
* **Event-Driven Architecture:** Stop polling registers! Use `attachCallback()` to handle button presses, slider movements, and data returns instantly.
* **Non-Blocking Parser:** The `listen()` function uses an asynchronous Finite State Machine (FSM), keeping your `loop()` running fast for other tasks (sensors, WiFi, etc.).
* **Comprehensive Data Support:**
    * ✅ **16-bit Integers** (`writeVP`)
    * ✅ **32-bit Longs** (`writeVP32`)
    * ✅ **Float Numbers** (`writeVP` overload) - *Essential for sensors!*
    * ✅ **Dynamic Text** (`setText`) - *Send strings easily.*
* **Full System Control:**
    * Change Pages, Adjust Brightness, Trigger Buzzer (Beep).
    * Read/Set RTC (Real Time Clock).
    * Multi-language support via Page Offset engine.

---

## 📦 Installation

### Method 1: Arduino Library Manager (Recommended)
1.  Open **Arduino IDE**.
2.  Go to `Sketch` -> `Include Library` -> `Manage Libraries...`.
3.  Search for **"DWIN_UNI_HMI"**.
4.  Click **Install** on the latest version.

### Method 2: Manual Installation (.ZIP)
1.  Download the latest release from this repository as a ZIP file.
2.  In Arduino IDE, go to `Sketch` -> `Include Library` -> `Add .ZIP Library`.
3.  Select the downloaded file.

*Compatible with PlatformIO (drop into `lib` folder) and Arduino IDE.*

---

## 📂 Test Project & Firmware (Ready-to-Run)

We provide a **Complete DWIN Project** to help you test the library immediately, ruling out any GUI design errors.

Navigate to the `extras/DWIN_DGUS/test/` folder in this repository:

1.  **Compiled Firmware (`DWIN_SET` folder):**
    * Copy the entire `DWIN_SET` folder directly to the root of a formatted SD Card (FAT32, <16GB).
    * Insert it into the DWIN display and power cycle to flash the **"ZEUS System"** test interface.
    * *Includes all required fonts, icons, and configuration files.*

2.  **Source Project:**
    * Contains the `.hmi` (or `.imp`) project file.
    * Open with **DGUS II Software** to inspect how the variables and buttons are addressed.

---

## 💻 Usage Example

Here is a comprehensive test suite. It demonstrates sending Text, Numbers (Int/Float), and handling Touch Feedback via Callbacks.

```cpp
#include <Arduino.h>
#include <DWIN_UNI_HMI.h>

// Initialize the Library Object
Dwin hmi;

// --- Event Callback Function ---
// This function is triggered automatically when the screen sends data.
// It handles both 16-bit (Buttons) and 32-bit (Keyboards/Sliders) data.
void onHmiEvent(uint16_t address, uint32_t data, uint8_t len) {
    Serial.print("Event Captured -> Addr: 0x");
    Serial.print(address, HEX);
    
    Serial.print(" | Data: ");
    Serial.print(data);
    
    Serial.print(" | Type: ");
    if (len == 2) Serial.println("16-bit (Word)");
    else if (len == 4) Serial.println("32-bit (DWord/Float)");
    else Serial.println("Unknown");
    
    // Example: Beep if button at 0x5000 is pressed
    if (address == 0x5000) {
        hmi.beep(5); // 50ms Feedback
    }
}

void setup() {
    Serial.begin(115200);
    
    // --- Initialize UART for DWIN ---
    // ESP32: Using Serial2 (RX=GPIO16, TX=GPIO17)
    // For Mega/STM32, use Serial1 or Serial3 as needed.
    Serial2.begin(115200, SERIAL_8N1, 16, 17);
    hmi.begin(Serial2);

    // Register the event callback
    hmi.attachCallback(onHmiEvent);

    Serial.println("DWIN HMI Initialized. Sending Test Data...");

    // --- TEST 1: System Controls ---
    hmi.setPage(0);          // Switch to Home Page
    hmi.setBrightness(100);  // Set Backlight to 100%
    hmi.beep(10);            // Startup Beep (100ms)
    delay(500);

    // --- TEST 2: Dynamic Text ---
    // Sends a String to the Text Display at VP 0x1000
    hmi.setText(0x1000, "ZEUS SYSTEM ONLINE");

    // --- TEST 3: Numeric Data Types ---
    // 16-bit Integer (VP 0x2000)
    hmi.writeVP(0x2000, (uint16_t)1024);
    
    // 32-bit Long Integer (VP 0x3000)
    hmi.writeVP32(0x3000, 123456789);

    // Float / Decimal (VP 0x4000)
    // Note: DWIN uses IEEE 754 standard for floats
    hmi.writeVP(0x4000, 24.50f);
}

void loop() {
    // CRITICAL: The listen() function must be called in the loop.
    // It handles incoming serial data asynchronously.
    hmi.listen();
}
```

## 📚 API Reference

### 1. Initialization & Core

#### `void begin(Stream &serial)`
Initializes the DWIN object with the specified Serial port.
* **@param** `serial`: Reference to HardwareSerial (e.g., `Serial2`) or SoftwareSerial object.

#### `void listen()`
**MUST** be called inside `loop()`. Processes incoming data from the display asynchronously (Non-blocking).

#### `void attachCallback(DwinEventCallback func)`
Registers a user-defined function to handle events (Button presses, Keypad entries).
* **Callback Signature:** `void func(uint16_t address, uint32_t data, uint8_t len)`

---

### 2. Data Operations

#### `void writeVP(uint16_t address, uint16_t value)`
Writes a standard 16-bit Integer (2 Bytes) to a Variable Pointer address.
* **@param** `address`: VP Address (e.g., `0x1000`).
* **@param** `value`: The integer to write.

#### `void writeVP32(uint16_t address, uint32_t value)`
Writes a 32-bit Long Integer (4 Bytes) to a Variable Pointer address.
* **@param** `address`: VP Address.
* **@param** `value`: The long integer value.

#### `void writeVP(uint16_t address, float value)`
Writes a Floating Point number (4 Bytes, IEEE 754) to a Variable Pointer address.
* **@param** `address`: VP Address.
* **@param** `value`: The float value (e.g., `24.50`).

#### `void setText(uint16_t address, const char* text)`
Writes a String to a Text Display control.
* **@param** `address`: VP Address of the Text Display.
* **@param** `text`: The string character array (Max 200 chars).

#### `void readVP(uint16_t address, uint8_t wordLen)`
Requests data from the display. The response is handled asynchronously via the attached callback.
* **@param** `address`: VP Address to read from.
* **@param** `wordLen`: Number of words to read (1 word = 2 bytes).

---

### 3. System Controls

#### `void setPage(uint16_t pageID)`
Switches the screen to a specific Page ID.

#### `void setBrightness(uint8_t level)`
Sets the backlight brightness.
* **@param** `level`: Brightness level (0-100).

#### `void beep(uint8_t duration)`
Activates the internal buzzer.
* **@param** `duration`: Beep duration in 10ms units (e.g., `10` = 100ms).

#### `void setRTC(uint8_t year, uint8_t month, uint8_t day, uint8_t weekDay, uint8_t hour, uint8_t minute, uint8_t second)`
Sets the Real Time Clock (Address `0x9C`).

#### `void readRTC()`
Requests current time (Address `0x10`). Response comes via callback.

#### `void playAudio(uint8_t musicID, uint8_t volume)`
Plays a `.wae` audio file from the SD card.
* **@param** `musicID`: ID of the audio file.
* **@param** `volume`: Volume level (0x00 - 0x40).

#### `void systemReset()`
Performs a software reboot of the HMI (Address `0x04`).

#### `void getSoftwareVersion()`
Requests OS/GUI versions (Address `0x0F`).

#### `void setBaudRate(long newBaudRate)`
Dynamically changes the UART2 baud rate (Address `0x0C`).
* **Note:** Calculation is `3225600 / BaudRate`.

#### `void setSystemConfig(bool touchSound, bool dataUpload)`
Enables or disables system flags (Address `0x80`).
* **@param** `touchSound`: Enable buzzer on touch.
* **@param** `dataUpload`: Enable auto-upload data on touch.

---

### 4. Advanced UI Features

#### `void setPageOverlay(bool enable, uint16_t overlayPageID)`
Shows or hides a "Popup" page over the current screen (Address `0xE8`).
* **@param** `enable`: `true` to show, `false` to hide.
* **@param** `overlayPageID`: The Page ID to show as overlay.

#### `void setTextColor(uint16_t spAddress, uint16_t color)`
Changes the color of a Text Display control dynamically.
* **@param** `spAddress`: The Description Pointer (SP) address (NOT VP!).
* **@param** `color`: 16-bit RGB565 Color.

#### `void setLanguageOffset(uint16_t offset)`
Sets a Page ID offset for multi-language applications.
* **Example:** If offset is `10` and you call `setPage(0)`, it goes to Page `10`.

#### `void setLanguageICL(uint8_t iclID)`
Switches the background image library (ICL) instantly (Address `0xDE`).

---

## 📝 License

This library is open-source and licensed under the **MIT License**.

**Author:** Askin Keles  
**Maintainer:** Askin Keles (<askinkeles@gmail.com>)