🌱 Ứng dụng cổng COM Port trong các dự án hệ thống nhúng
Sử dụng cổng COM trong lập trình nhúng?
Cổng COM (hay cổng nối tiếp) là một giao diện truyền thông tuần tự, được sử dụng rộng rãi để kết nối các thiết bị ngoại vi với máy tính hoặc các hệ thống nhúng. Trong lập trình nhúng, cổng COM đóng vai trò quan trọng trong việc giao tiếp giữa vi điều khiển và máy tính, cho phép truyền dữ liệu, lệnh điều khiển và nhận phản hồi, ...
Ví dụ giao tiếp Vi điều khiển (Arduino) với PC |
UART là giao thức truyền thông phổ biến trên Vi điều khiển, nhưng máy tính lại chỉ hỗ trợ giao thức USB. Vì vậy về mặt phần cứng, các dòng vi điều khiển muốn giao tiếp máy tính sẽ cần kết nối thông qua các chip chuyển đổi USB to UART, chẳng hạn như CP2102 (như trong hình), CH340, FT232, ...
Và để truyền dữ liệu qua cổng COM của máy tính theo khung dữ liệu của giao thức UART, chúng ta có thể sử dụng các công cụ phần mềm có sẵn như PuTTy, Hercules, Terminal, TeraTerm, RealTerm, ...
Nếu bạn muốn chủ động phát triển một phần mềm máy tính để giao tiếp với vi điều khiển qua giao thức UART, bạn có thể chủ động việc truyền / nhận dữ liệu cổng COM thông qua một số ngôn ngữ lập trình bậc cao (C#, Python, C++).
Một số phần mềm giao tiếp ComPort có sẵn
Có rất nhiều phần mềm có sẵn được phát triển để giao tiếp Com Port giữa máy tính và UART của vi điều khiển.
PuTTY
- Đặc điểm: PuTTY là một ứng dụng miễn phí, mã nguồn mở, nổi tiếng với khả năng kết nối đến nhiều loại máy chủ khác nhau, bao gồm cả kết nối tuần tự qua cổng COM.
- Tính năng:
- Cấu hình linh hoạt các thông số kết nối như baud rate, bit dữ liệu, parity, stop bit.
- Hỗ trợ nhiều giao thức khác như Telnet, SSH.
- Giao diện đơn giản, dễ sử dụng.
TeraTerm
- Đặc điểm: Tera Term là một phần mềm terminal emulator mã nguồn mở, tương tự như PuTTY.
- Tính năng:
- Hỗ trợ nhiều giao thức truyền thông khác nhau.
- Có thể tùy chỉnh giao diện và các tính năng.
- Hỗ trợ macro và script.
RealTerm
- Đặc điểm: RealTerm là một phần mềm terminal đơn giản, nhẹ nhàng nhưng rất hiệu quả.
- Tính năng:
- Giao diện trực quan, dễ sử dụng.
- Hỗ trợ nhiều loại mã hóa.
- Có thể lưu lại các cấu hình kết nối.
Hercules
Hercules là một phần mềm miễn phí, mã nguồn mở, được thiết kế đặc biệt để giao tiếp với các thiết bị qua cổng COM. Phần mềm này có giao diện đơn giản, dễ sử dụng và rất linh hoạt, phù hợp với nhiều ứng dụng khác nhau.
Tự phát triển một phần mềm giao tiếp Com Port
Các phần mềm có sẵn ở trên rất phù hợp để giao tiếp các dữ liệu qua cổng COM với UART của vi điều khiển. Tuy nhiên, nó chỉ phù hợp để truyền các data do người dùng chủ động điền vào, gửi theo chuỗi. Trong một số dự án, lập trình viên sẽ cần chủ động tạo ra một số khung truyền, một số phần mềm truyền data qua cổng COM theo cách chủ động hơn (ví dụ thêm phần giao diện, hoặc tự động hóa việc truyền nhận).
Ví dụ một số dự án có thể cần tự phát triển phần mềm giao tiếp ComPort:
- Giao tiếp ESP/module Bluetooth sử dụng AT Command.
- Ứng dụng hỗ trợ Bootloader - FOTA.
- Giả lập thiết bị UART (Một số sản phẩm sử dụng nhiều MCU giao tiếp nhau qua giao thức UART - có thể viết phần mềm để test độc lập các MCU)
Chọn ngôn ngữ lập trình
- C/C++: Hiệu năng cao, kiểm soát chặt chẽ phần cứng, thích hợp cho các ứng dụng đòi hỏi thời gian thực.
- Python: Dễ học, thư viện phong phú (PySerial), thích hợp cho các dự án nhanh và đơn giản.
- Các ngôn ngữ khác: C#, Java, ... tùy thuộc vào nền tảng và sở thích của bạn.
Lựa chọn thư viện
- PySerial (Python): Thư viện phổ biến, dễ sử dụng để giao tiếp với cổng COM.
- SerialPort (C#): Thư viện .NET Framework cho phép giao tiếp với các cổng nối tiếp.
- Thư viện hệ thống: Nếu bạn sử dụng C/C++, bạn có thể sử dụng các hàm hệ thống để điều khiển cổng COM trực tiếp.
Giao tiếp Comport sử dụng thư viện PySerial
Thư viện pyserial của Python cung cấp các API cần thiết để giao tiếp với cổng COM Port. Để sử dụng Pyserial, bạn cần cài đặt thư viện bằng lệnh:
pip install pyserial
pyserial cung cấp các API để kết nối Comport, check kết nối comport, đọc / ghi dữ liệu từ comport.
Một số API thường sử dụng của thư viện pyserial (Xem pyserial document)
- class serial.Serial, khởi tạo đối tượng Serial với các thông tin COM Port, Baudrate, timeout, byte size, stop bit, parity, ...
- open() và close() dùng để connect và disconnect cổng serial.
- read() và write() dùng để nhận và truyền dữ liệu qua cổng com.
Dưới đây là một ví dụ sử dụng kết nối cổng COM3 với baudrate = 9600, sau đó sử dụng các API như write(), readline() để truyền / nhận dữ liệu.
- import serial
- # Connect the Serial Port
- ser = serial.Serial('COM3', 9600)
- # Send Data via Comport
- ser.write(b'Hello, Embedded!')
- # Receive Data from Comport
- response = ser.readline()
- print(response.decode())
- # Disconnect the Serial Port
- ser.close()
➤ Tối ưu hóa việc sử dụng pyserial
Để tối ưu hóa việc sử dụng pyserial, tránh việc truyền nhận dữ liệu với dung lượng lớn bị gián đoạn và thất thoát dữ liệu, pyserial sử dụng "pyserial.thread", pyserial.thread là một cách tiếp cận để kết hợp thư viện PySerial với đa luồng trong Python. Việc này giúp tăng hiệu suất và khả năng phản hồi của ứng dụng khi giao tiếp với các thiết bị qua cổng serial, đặc biệt trong các trường hợp cần thực hiện nhiều tác vụ đồng thời như:
- Đọc dữ liệu liên tục: Đọc dữ liệu từ cổng serial trong một luồng riêng biệt, đảm bảo không bị gián đoạn bởi các tác vụ khác.
- Gửi dữ liệu theo định kỳ: Gửi các lệnh hoặc dữ liệu đến thiết bị theo chu kỳ nhất định.
- Xử lý sự kiện: Phản hồi nhanh chóng khi có sự kiện xảy ra trên cổng serial (ví dụ: nhận được một gói dữ liệu cụ thể).
Cách thực hiện
➢ Import các thư viện cần thiết
import serial
import threading
➢ Khởi tạo một đối tượng của lớp SerialThread
class SerialThread(threading.Thread):
def __init__(self, port, baudrate):
# ... Initialize class properties
def run(self):
# ... Code to read/write data on serial port
➢ Trong phương thức run của lớp SerialThread
- Mở cổng serial: Sử dụng
serial.Serial
để mở cổng. - Vòng lặp vô hạn:
- Đọc dữ liệu: Sử dụng
ser.readline()
hoặc các phương thức khác để đọc dữ liệu. - Xử lý dữ liệu: Phân tích và xử lý dữ liệu nhận được.
- Gửi dữ liệu: Sử dụng
ser.write()
để gửi dữ liệu. - Kiểm tra sự kiện: Kiểm tra các sự kiện khác (ví dụ: dừng luồng, thay đổi cấu hình).
Ở đây, mình đã tổ chức một file thư viện khá đầy đủ về Pyserial thread và có file test sử dụng.
Và dưới đây là một cách sử dụng:
Sử dụng thư viện Pyserial giao tiếp cổng COM |
- ### @Project: TaaR_SerialManager Test File ###################################################
- ### @File : SerialTest.py
- ###
- ### @Desp : This file to Use the TaaR_SerialManager Class and Test communicate with PC (Arduino)
- ### Author : Nghia Taarabt
- ### Created Time : 06/06/2023
- ### Link : https://github.com/nghia12a1-t-ara/Embedded_MyTools/tree/master/TaaR_SerialManager
- #################################################################################################
- '''
- Connect Arduino <-> PC (Open this tool)
- Arduino Code:
- void setup()
- {
- Serial.begin(115200);
- }
- void loop()
- {
- // send data only when you receive data
- if (Serial.available() > 0)
- {
- Serial.write(Serial.read());
- }
- }
- '''
- from TaaR_SerialManager import SerialManager
- import time
- def UART_RecvCallback(buffer):
- print("The receive character from Arduino = ", buffer)
- def main():
- UART = SerialManager(port="COM3", baudrate=115200)
- if UART.connect():
- print("Connect is done")
- else:
- print("Connect is fail")
- return 0
- # UART.SetRecvEndByte(0xBB) # default endByte = '\n'
- ######### Start Read Async ##########
- UART.read_async(callback=UART_RecvCallback)
- # Send data to Arduino 'A' - Expected Recving 'B' from Arduino
- UART.send_byte('AA')
- while True:
- character = input("Input the character to send to Arduino: ")
- UART.send_byte(str(character))
- time.sleep(2)
- character = input("Input the character to send to Arduino: ")
- UART.send_byte(str(character))
- time.sleep(2)
- ###############################################
- if __name__ == "__main__":
- main()
Thư viện hỗ trợ cấu hình hàm Callback khi nhận được dữ liệu từ UART và có thể nhận một frame truyền UART với byte kết thúc có thể cấu hình được, sử dụng các tham số của hàm ReadAsync(). Phần test trên sử dụng để giao tiếp giữa PC với Arduino.
Video Demo
>>>>>> Follow ngay <<<<<<<
Để nhận được những bài học miễn phí mới nhất nhé 😊
Chúc các bạn học tập tốt 😊