Hướng Dẫn Giao Tiếp Với Bảng LED (Scoreboard) Qua UDP LDNam

Giới thiệu

Bảng LED (scoreboard) LDNam, hỗ trợ giao tiếp qua WiFi hoặc Ethernet bằng giao thức UDP. Lập trình viên có thể gửi các gói tin UDP từ máy tính để thực hiện các tác vụ sau:

  • Hiển thị điểm số: Gửi một số nguyên để hiển thị trên bảng LED.
  • Đọc điểm số hiện tại: Yêu cầu bảng trả về điểm số đang hiển thị.
  • Cấu hình mạng: Đặt IP tĩnh/DHCP cho WiFi hoặc Ethernet, hoặc đặt địa chỉ MAC.
  • Reset thiết bị: Khởi động lại bảng LED.

Bài hướng dẫn này cung cấp chi tiết về các lệnh UDP mà bảng hỗ trợ và cách viết code Python trên máy tính để giao tiếp với bảng LED.


Yêu cầu

Phần cứng

  • Bảng LED LDNAM.
  • Máy tính: Có kết nối mạng (WiFi hoặc Ethernet) để giao tiếp với bảng LED.
  • Mạng: Bảng LED và máy tính phải nằm trong cùng một mạng (LAN).

Phần mềm

  • Python 3.x: Cài đặt Python trên máy tính.
  • Thư viện Python:
    • socket: Để gửi/nhận gói tin UDP (có sẵn trong Python).
    • (Tùy chọn) time: Để thêm độ trễ giữa các lệnh.
  • Thông tin mạng của bảng LED:
    • WiFi IP: Địa chỉ IP của bảng khi kết nối WiFi (mặc định DHCP hoặc tĩnh, ví dụ: 192.168.1.100).
    • Ethernet IP: Địa chỉ IP của bảng khi kết nối Ethernet (mặc định DHCP hoặc tĩnh, ví dụ: 192.168.1.100).
    • Cổng UDP:
      • WiFi: Mặc định cổng 80 (DHCP) hoặc cổng tĩnh được lưu trong bộ nhớ (kiểm tra qua GET_WIFI_CONFIG).
      • Ethernet: Mặc định cổng 80 (DHCP) hoặc cổng tĩnh được lưu trong bộ nhớ (kiểm tra qua GET_ETH_CONFIG).

Các lệnh UDP được hỗ trợ

Bảng LED nhận và phản hồi các gói tin UDP với các lệnh sau:

LệnhMô tảĐịnh dạngPhản hồi
READ_SCORELấy điểm số hiện tại đang hiển thị trên bảng LED.READ_SCOREChuỗi số (ví dụ: “123”) hoặc không phản hồi nếu lỗi.
SET_SCORE:<số>Đặt điểm số mới để hiển thị trên bảng LED.SET_SCORE:123“OK” nếu thành công, “ERROR” nếu số không hợp lệ.
GET_WIFI_CONFIGLấy cấu hình mạng WiFi (IP, subnet, gateway, MAC).GET_WIFI_CONFIG“STATIC|<IP>|<Subnet>|<Gateway>|<MAC>” hoặc “DHCP|<IP>|<Subnet>|<Gateway>|<MAC>” hoặc “ERROR|||” nếu WiFi không kết nối.
GET_ETH_CONFIGLấy cấu hình mạng Ethernet (IP, subnet, gateway, MAC).GET_ETH_CONFIG“STATIC|<IP>|<Subnet>|<Gateway>|<MAC>” hoặc “DHCP|<IP>|<Subnet>|<Gateway>|<MAC>” hoặc “ERROR|||” nếu Ethernet không kết nối.
SET_WIFI_IP:<mode>Đặt cấu hình IP cho WiFi (tĩnh hoặc DHCP).– Tĩnh: SET_WIFI_IP:STATIC|IP:<ip>|MASK:<mask>|GATEWAY:<gateway>|PORT:<port>
– DHCP: SET_WIFI_IP:DHCP
“OK” nếu thành công, “ERROR” nếu định dạng không hợp lệ.
SET_ETH_IP:<mode>Đặt cấu hình IP cho Ethernet (tĩnh hoặc DHCP).– Tĩnh: SET_ETH_IP:STATIC|IP:<ip>|MASK:<mask>|GATEWAY:<gateway>|PORT:<port>
– DHCP: SET_ETH_IP:DHCP
“OK” nếu thành công, “ERROR” nếu định dạng không hợp lệ.
SET_MAC:<mac>Đặt địa chỉ MAC cho Ethernet.SET_MAC:DE:AD:BE:EF:FE:ED“OK” nếu MAC hợp lệ, “ERROR” nếu không hợp lệ.
RESETKhởi động lại bảng LED.RESET“OK” trước khi reset.

Lưu ý:

  • <số>: Một số nguyên dương (ví dụ: 123).
  • <ip>, <mask>, <gateway>: Địa chỉ IPv4 hợp lệ (ví dụ: 192.168.1.100).
  • <port>: Số cổng UDP (ví dụ: 80).
  • <mac>: Địa chỉ MAC dạng XX:XX:XX:XX:XX:XX (hexadecimal, 6 byte).
  • Các lệnh gửi qua UDP phải là chuỗi ký tự (text) và kết thúc bằng ký tự null (\0).

Viết code Python để giao tiếp

Dưới đây là các ví dụ Python sử dụng thư viện socket để gửi và nhận gói tin UDP từ bảng LED. Các ví dụ giả định bảng LED có địa chỉ IP là 192.168.1.100 và cổng UDP là 80.

1. Gửi điểm số tới bảng LED

Gửi lệnh SET_SCORE:123 để hiển thị số 123 trên bảng LED.

import socket

# Thông tin bảng LED
LED_IP = "192.168.1.100"  # Thay bằng IP thực tế của bảng
LED_PORT = 80             # Thay bằng cổng thực tế

# Tạo socket UDP
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# Lệnh gửi điểm số
score = 123
command = f"SET_SCORE:{score}"
sock.sendto(command.encode(), (LED_IP, LED_PORT))

# Nhận phản hồi
sock.settimeout(2.0)  # Đợi tối đa 2 giây
try:
    data, addr = sock.recvfrom(1024)
    print(f"Phản hồi từ bảng LED: {data.decode()}")
except socket.timeout:
    print("Không nhận được phản hồi")

sock.close()

Giải thích:

  • Tạo socket UDP và gửi lệnh SET_SCORE:123 tới IP và cổng của bảng LED.
  • Đợi phản hồi (“OK” hoặc “ERROR”) trong 2 giây.
  • In phản hồi hoặc thông báo lỗi nếu không nhận được phản hồi.

2. Đọc điểm số hiện tại

Gửi lệnh READ_SCORE để lấy điểm số hiện tại từ bảng LED.

import socket

# Thông tin bảng LED
LED_IP = "192.168.1.100"
LED_PORT = 80

# Tạo socket UDP
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# Gửi lệnh đọc điểm số
command = "READ_SCORE"
sock.sendto(command.encode(), (LED_IP, LED_PORT))

# Nhận phản hồi
sock.settimeout(2.0)
try:
    data, addr = sock.recvfrom(1024)
    print(f"Điểm số hiện tại: {data.decode()}")
except socket.timeout:
    print("Không nhận được phản hồi")

sock.close()

Giải thích:

  • Gửi lệnh READ_SCORE và đợi phản hồi chứa điểm số (chuỗi số, ví dụ: “123”).
  • Nếu không nhận được phản hồi trong 2 giây, in thông báo lỗi.

3. Cấu hình IP tĩnh cho WiFi

Gửi lệnh SET_WIFI_IP:STATIC|IP:192.168.1.101|MASK:255.255.255.0|GATEWAY:192.168.1.1|PORT:80 để đặt IP tĩnh cho WiFi.

import socket

# Thông tin bảng LED
LED_IP = "192.168.1.100"
LED_PORT = 80

# Tạo socket UDP
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# Lệnh đặt IP tĩnh cho WiFi
command = "SET_WIFI_IP:STATIC|IP:192.168.1.101|MASK:255.255.255.0|GATEWAY:192.168.1.1|PORT:80"
sock.sendto(command.encode(), (LED_IP, LED_PORT))

# Nhận phản hồi
sock.settimeout(2.0)
try:
    data, addr = sock.recvfrom(1024)
    print(f"Phản hồi từ bảng LED: {data.decode()}")
except socket.timeout:
    print("Không nhận được phản hồi")

sock.close()

Giải thích:

  • Gửi lệnh cấu hình IP tĩnh với các thông số IP, subnet mask, gateway, và cổng.
  • Phản hồi sẽ là “OK” nếu thành công hoặc “ERROR” nếu định dạng không hợp lệ.
  • Sau khi đặt IP tĩnh, bạn cần cập nhật LED_IP và LED_PORT trong code Python để tiếp tục giao tiếp.

4. Cấu hình IP tĩnh cho Ethernet

Gửi lệnh SET_ETH_IP:STATIC|IP:192.168.1.102|MASK:255.255.255.0|GATEWAY:192.168.1.1|PORT:80 để đặt IP tĩnh cho Ethernet.

import socket

# Thông tin bảng LED
LED_IP = "192.168.1.100"
LED_PORT = 80

# Tạo socket UDP
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# Lệnh đặt IP tĩnh cho Ethernet
command = "SET_ETH_IP:STATIC|IP:192.168.1.102|MASK:255.255.255.0|GATEWAY:192.168.1.1|PORT:80"
sock.sendto(command.encode(), (LED_IP, LED_PORT))

# Nhận phản hồi
sock.settimeout(2.0)
try:
    data, addr = sock.recvfrom(1024)
    print(f"Phản hồi từ bảng LED: {data.decode()}")
except socket.timeout:
    print("Không nhận được phản hồi")

sock.close()

Giải thích:

  • Tương tự lệnh SET_WIFI_IP, nhưng áp dụng cho Ethernet.
  • Phản hồi sẽ là “OK” hoặc “ERROR”.
  • Cần cập nhật LED_IP và LED_PORT nếu IP/cổng thay đổi sau khi cấu hình.

5. Đặt địa chỉ MAC cho Ethernet

Gửi lệnh SET_MAC:AA:BB:CC:DD:EE:FF để đặt địa chỉ MAC cho Ethernet.

import socket

# Thông tin bảng LED
LED_IP = "192.168.1.100"
LED_PORT = 80

# Tạo socket UDP
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# Lệnh đặt MAC
command = "SET_MAC:AA:BB:CC:DD:EE:FF"
sock.sendto(command.encode(), (LED_IP, LED_PORT))

# Nhận phản hồi
sock.settimeout(2.0)
try:
    data, addr = sock.recvfrom(1024)
    print(f"Phản hồi từ bảng LED: {data.decode()}")
except socket.timeout:
    print("Không nhận được phản hồi")

sock.close()

Giải thích:

  • Gửi địa chỉ MAC (6 byte, dạng XX:XX:XX:XX:XX:XX) để cập nhật cho Ethernet.
  • Phản hồi là “OK” nếu MAC hợp lệ, hoặc “ERROR” nếu không hợp lệ.

6. Lấy cấu hình mạng

Gửi lệnh GET_WIFI_CONFIG hoặc GET_ETH_CONFIG để lấy thông tin mạng.

import socket

# Thông tin bảng LED
LED_IP = "192.168.1.100"
LED_PORT = 80

# Tạo socket UDP
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# Gửi lệnh lấy cấu hình WiFi
command = "GET_WIFI_CONFIG"
sock.sendto(command.encode(), (LED_IP, LED_PORT))

# Nhận phản hồi
sock.settimeout(2.0)
try:
    data, addr = sock.recvfrom(1024)
    print(f"Cấu hình WiFi: {data.decode()}")
except socket.timeout:
    print("Không nhận được phản hồi")

# Gửi lệnh lấy cấu hình Ethernet
command = "GET_ETH_CONFIG"
sock.sendto(command.encode(), (LED_IP, LED_PORT))

# Nhận phản hồi
try:
    data, addr = sock.recvfrom(1024)
    print(f"Cấu hình Ethernet: {data.decode()}")
except socket.timeout:
    print("Không nhận được phản hồi")

sock.close()

Giải thích:

  • Phản hồi có dạng “STATIC|<IP>|<Subnet>|<Gateway>|<MAC>” hoặc “DHCP|<IP>|<Subnet>|<Gateway>|<MAC>”.
  • Nếu không kết nối, phản hồi là “ERROR|||”.

7. Reset bảng LED

Gửi lệnh RESET để khởi động lại bảng LED.

import socket

# Thông tin bảng LED
LED_IP = "192.168.1.100"
LED_PORT = 80

# Tạo socket UDP
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# Gửi lệnh reset
command = "RESET"
sock.sendto(command.encode(), (LED_IP, LED_PORT))

# Nhận phản hồi
sock.settimeout(2.0)
try:
    data, addr = sock.recvfrom(1024)
    print(f"Phản hồi từ bảng LED: {data.decode()}")
except socket.timeout:
    print("Không nhận được phản hồi")

sock.close()

Giải thích:

  • Gửi lệnh RESET để khởi động lại bảng LED.
  • Phản hồi là “OK” trước khi bảng reset.

Lưu ý khi lập trình

  1. Tìm IP và cổng của bảng LED:
    • Nếu bảng sử dụng DHCP, kiểm tra IP được cấp qua Serial Monitor hoặc gửi lệnh GET_WIFI_CONFIG/GET_ETH_CONFIG.
    • Nếu sử dụng IP tĩnh, kiểm tra cấu Vulnerabilities:
    • Nếu WiFi hoặc Ethernet không kết nối, bảng LED sẽ không phản hồi các lệnh UDP. Hãy đảm bảo thiết bị được kết nối mạng trước khi gửi lệnh.
    • Nếu bạn không biết IP, có thể sử dụng công cụ quét mạng (như nmap) hoặc kiểm tra trên router để tìm IP của bảng.
  2. Xử lý lỗi:
    • Luôn đặt sock.settimeout() để tránh chương trình treo khi không nhận được phản hồi.
    • Kiểm tra định dạng lệnh trước khi gửi (ví dụ: số trong SET_SCORE phải là số nguyên dương, IP/MAC phải đúng định dạng).
  3. Hiệu suất:
    • Gửi các lệnh cách nhau ít nhất 100ms để tránh quá tải bảng LED.
    • Đảm bảo máy tính và bảng LED nằm trong cùng subnet để giao tiếp UDP hoạt động.
  4. Debugging:
    • Kết nối bảng LED với máy tính qua cổng Serial (115200 baud) để xem log chi tiết (IP, trạng thái kết nối, lỗi).
    • Serial Monitor sẽ hiển thị các thông báo như “WiFi connected”, “Ethernet connected”, hoặc “Received packet via WiFi/Ethernet”.
  5. Tùy chỉnh hiển thị:
    • Hàm displayScore (trong file hien_thi.h) xử lý việc hiển thị số trên LED. Đảm bảo phần cứng LED được cấu hình đúng để hiển thị số chính xác.

Ví dụ tích hợp (Giao diện điều khiển điểm số)

Dưới đây là một chương trình Python tích hợp, cho phép người dùng nhập điểm số và gửi tới bảng LED:

import socket
import time

# Thông tin bảng LED
LED_IP = "192.168.1.100"
LED_PORT = 80

def send_udp_command(command):
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.sendto(command.encode(), (LED_IP, LED_PORT))
    sock.settimeout(2.0)
    try:
        data, addr = sock.recvfrom(1024)
        print(f"Phản hồi: {data.decode()}")
        return data.decode()
    except socket.timeout:
        print("Không nhận được phản hồi")
        return None
    finally:
        sock.close()

# Menu điều khiển
while True:
    print("\n=== Điều khiển bảng LED ===")
    print("1. Gửi điểm số")
    print("2. Đọc điểm số hiện tại")
    print("3. Reset bảng LED")
    print("4. Thoát")
    choice = input("Chọn (1-4): ")

    if choice == "1":
        score = input("Nhập điểm số: ")
        if score.isdigit():
            send_udp_command(f"SET_SCORE:{score}")
        else:
            print("Vui lòng nhập số nguyên dương")
    elif choice == "2":
        send_udp_command("READ_SCORE")
    elif choice == "3":
        send_udp_command("RESET")
    elif choice == "4":
        break
    else:
        print("Lựa chọn không hợp lệ")
    time.sleep(0.1)  # Tránh gửi lệnh quá nhanh

Giải thích:

  • Cung cấp menu để người dùng chọn gửi điểm số, đọc điểm số, hoặc reset.
  • Kiểm tra đầu vào để đảm bảo điểm số là số nguyên dương.
  • Thêm độ trễ 100ms giữa các lệnh để tránh quá tải.

Xử lý sự cố

  • Không kết nối được với bảng LED:
    • Kiểm tra IP và cổng có đúng không (dùng GET_WIFI_CONFIG hoặc GET_ETH_CONFIG).
    • Đảm bảo máy tính và bảng LED trong cùng mạng LAN.
    • Kiểm tra trạng thái kết nối qua Serial Monitor.
  • Không hiển thị điểm số:
    • Kiểm tra kết nối phần cứng LED (chân TX/RX, IC quét LED).
    • Xác minh hàm displayScore hoạt động đúng trong hien_thi.h.
  • Phản hồi “ERROR”:
    • Kiểm tra định dạng lệnh (ví dụ: số trong SET_SCORE, IP/MAC hợp lệ).
    • Đảm bảo bảng LED đang chạy và kết nối mạng ổn định.

Kết luận

Bảng LED của bạn là một hệ thống mạnh mẽ, hỗ trợ giao tiếp qua WiFi và Ethernet bằng UDP. Với các ví dụ Python trên, bạn có thể dễ dàng tích hợp bảng LED vào ứng dụng hoặc hệ thống điều khiển từ xa. Nếu cần thêm tính năng (ví dụ: gửi nhiều số, giao diện đồ họa), hãy mở rộng code Python bằng các thư viện như tkinter (cho GUI) hoặc thêm logic xử lý nâng cao.

Nếu bạn gặp vấn đề hoặc cần hỗ trợ thêm, hãy cung cấp log từ Serial Monitor hoặc mô tả chi tiết lỗi để được hỗ trợ!

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *