Lập trình truyền thông nối tiếp Serial Communication với C#

Giới thiệu

Truyền thông nối tiếp (Serial Communication) giữa các máy tính được xem như là một giao tiếp truyền thông đơn giản nhất và là khởi đầu để các bạn học lập trình giao tiếp mạng công nghiệp. Trong giao tiếp này, các máy tính được kết nối với nhau thông qua cổng COM với cáp truyền dẫn RS232. Ở các máy tính hiện đại ngày nay, cổng COM không được trang bị sẵn trên máy tính. Tuy nhiên, chúng ta có thể dễ dàng mở rộng thêm cổng COM cho máy tính thông qua các cáp chuyển đổi từ cổng USB sang cổng COM thông dụng trên thị trường. Khi đã lập trình làm quen với cổng COM và giao tiếp nối tiếp Serial thì sẽ tạo nền tảng cho các bạn học lập trình cho các giao tiếp nâng các khác sử dụng cổng COM này trong những bài sau (ví dụ: Modbus RTU…)

Trong bài viết này, itudong.com sẽ hướng dẫn các bạn cách truyền và nhận dữ liệu giữa các thiết bị sử dụng cổng nối tiếp trong C# và .Net. Sở dĩ chúng ta chọn C# và .Net là do ngôn ngữ này khá thông dụng và dễ hiểu. Thư viện .Net cũng được Microsoft tích hợp sẵn rất nhiều thư viện chuẩn do đó việc lập trình sử dụng nền tảng này sẽ rất nhanh chóng và trực quan. Do bài viết này là sử dụng C# và .Net để lập trình ứng dụng cho công nghiệp nên các thao tác cơ bản cũng như các cấu trúc lệnh thông dụng của ngôn ngữ này mình sẽ không trình bày nữa nhé. Các bạn có thể tra cứu hoặc học các hàm của C# thông qua các tài liệu hoặc sách có trên thị trường.

Cấu hình giả lập 2 thiết bị kết nối qua Serial Port

Thông thường, để có kết nối truyền thông Serial Port thông qua cổng COM thì các bạn sẽ cần 2 máy tính được trang bị cổng COM. Sau đó các bạn sẽ dùng cáp Serial để kết nối 2 máy tính này lại với nhau để chúng truyền dữ liệu. Tuy nhiên nếu các bạn không có sẵn 2 thiết bị thì các bạn có thể dễ dàng giả lập kết nối này thông qua các chương trình giả lập để tạo kết nối giữa 2 cổng COM trên 1 máy tính duy nhất.

Với chương trình giả lập này, máy tính sẽ tạo ra 2 cổng COM ảo, sau đó sẽ kết nối giữa 2 cổng COM này thông qua cáp Serial (ảo) trên máy tính.

Lập trình chương trình truyền dữ liệu

Khai báo cổng COM port

Chúng ta sẽ sử dụng thư viện COM Port để khởi tạo các thông tin liên quan đến cổng COM.

using System.IO.Ports;

Với thư viện này, khởi tạo một biến _sp toàn cục để đại diện cho cổng Serial Port sẽ giao tiếp

SerialPort _sp = new SerialPort();

Sau đó, trong đoạn khởi tạo chương trình, sử dụng phương thức GetPortNames để quét tất cả các cổng COM đang có trên máy tính và hiển thị trên khung danh sách cổng COM để người dùng lựa chọn cổng COM cần sử dụng.

            string[] ports = SerialPort.GetPortNames();
            foreach(string port in ports)
            {
                cboComport.Items.Add(port);
            }

Sau khi người dùng chọn cổng COM cần truyền thông, chúng ta lập trình cho nút Open để mở cổng COM Port tương ứng để bắt đầu quá trình giao tiếp. Trong đoạn lệnh, truyền các tham số của cổng Serial Port vào biến _sp và tiến hành mở cổng. Đoạn lệnh chi tiết như sau:

        private void btnOpen_Click(object sender, EventArgs e)
        {
            if (_sp.IsOpen) _sp.Close();
            try
            {
                _sp.PortName = cboComport.Text;
                _sp.BaudRate = 9600;
                _sp.DataBits = 8;
                _sp.StopBits = StopBits.One;
                _sp.Parity = Parity.None;
                _sp.Open();
            }
            catch ( Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

Nếu muốn linh hoạt hơn, thì chúng ta có thể tạo khung để người dùng có thể tuỳ ý lựa chọn các thông số của cổng truyền thông này.

Truyền dữ liệu qua cổng Serial Port

Sau khi đã tạo cổng Serial Port và đã mở cổng, chúng ta tạo khung để người dùng nhập dữ liệu cần truyền và nút lệnh để truyền dữ liệu.

Trong giao thức truyền nối tiếp Serial, hệ thống sẽ tạo một bộ nhớ đệm buffer để chứa dữ liệu cần truyền và chuyển nó đến thiết bị đọc. Do đó, để dữ liệu được truyền qua cổng Serial, chúng ta chỉ cần làm việc đơn giản là ghi dữ liệu cần truyền thông qua phương thức .Write(data). Lúc này Data sẽ được ghi vào bộ nhớ đệm của giao thức Serial và chỉ cần thiết bị đầu nhận thực hiện nhận dữ liệu này và hiển thị ra là xong.

        private void btnSend_Click(object sender, EventArgs e)
        {
            if (_sp.IsOpen)
                _sp.Write(tbDataSend.Text);
        }

Đọc dữ liệu từ cổng Serial Port

Sau khi dữ liệu cần truyền đã được gửi vào bộ nhớ buffer, trên thiết bị đọc sẽ dùng phương thức đọc ReadExisting() hoặc ReadByte() để đọc dữ liệu đang chứa trong bộ nhớ buffer.

Đối với phương thức ReadExisting, dữ liệu sẽ được đọc dưới dạng ký tự ASCII. Trong khi với các lệnh đọc ReadByte thì dữ liệu sẽ được đọc lần lượt theo từng Byte tương ứng.

Sau khi đã có phương thức để đọc dữ liệu cần truyền, chúng ta sẽ dựa vào nhu cầu của ứng dụng mà đưa vào sự kiện tương ứng để đọc. Có thể các bạn tạo nút nhấn để đọc dữ liệu, hoặc dùng bộ định thì timer để đọc dữ liệu định kỳ mỗi một giây… Ngoài ra, thư viện .Net còn có hỗ trợ sự kiện DataReceived để nhận biết mỗi khi có dữ liệu được truyền qua cổng Serial Port.

Các sự kiện đọc gói tin từ cổng Serial như sau: (chọn 1 trong 3)

Nhấn nút nhấn để đọc dữ liệu:

        private void btnRead_Click(object sender, EventArgs e)
        {
            if (_sp.IsOpen)
            {
                if (_sp.BytesToRead > 0)
                    tbDataRead.Text += _sp.ReadExisting();
            }
        }

Dùng sự kiện DataReceived để đọc dữ liệu

        private void Form1_Load(object sender, EventArgs e)
        {
            //.......
            _sp.DataReceived += SerialPort_DataReceived;
        }
        private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            // Handle received data
            string data = _sp.ReadExisting();
            tbDataRead.Text += data;
        }

Hoặc chúng ta có thể tạo một timer để định kỳ đọc dữ liệu mỗi chu kỳ 1s:

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (_sp.IsOpen)
            {
                if (_sp.BytesToRead > 0)
                    tbDataRead.Text += _sp.ReadExisting();
            }
        }

Để dữ liệu được trình bày rõ ràng cũng như có thêm giá trị thời gian đọc gói tin, chúng ta bổ sung thêm trong nội dung hiểu thị như sau:

tbDataRead.Text += System.DateTime.Now + ":  " + data + "\n";

Chạy và kiểm tra chương trình

Sau khi đã lập trình xong chương trình, chúng ta tiến hành chạy chương trình và thực hiện gửi nhận gói tin. Đầu tiên, chúng ta cần kiểm tra xem trong máy tính đã có 2 cổng COM ảo hay chưa. Nếu chưa thì các bạn tiến hành cấu hình tạo cổng COM như đã hướng dẫn ở bước trên. Do giao tiếp cần 2 thiết bị nên chúng ta sẽ chạy cùng lúc 2 chương trình. Một chương trình đóng vai trò gửi và một chương trình sẽ đóng vai trò nhận.

Tiến hành nhập dữ liệu và thực hiện lệnh gửi để kiểm tra quá trình trao đổi dữ liệu giữa 2 thiết bị.

Tổng kết

Như vậy là chúng ta đã lập trình một chương trình đơn giản có thể gửi và nhận dữ liệu thông qua giao tiếp nối tiếp Serial Port. Giao tiếp này được xem như là cơ bản và là nền tảng để các bạn làm quen với C# cũng như để lập trình cho các giao thức truyền thông khác.

(itudong.com – Kiến thức Tự động hoá)

Admin
Admin
Hi, I am Trong Nhan, and I'm an Automation engineer who specializes in PLC and SCADA. I've spent many years doing PLC development, installing, design SCADA, and troubleshooting. I hope to make this blog both a personal journal for my professional growth as well as a valuable information resource for others.

Related Articles

BÌNH LUẬN

Please enter your comment!
Please enter your name here

Stay Connected

1,839Thành viênThích
972Người theo dõiTheo dõi
1,750Người theo dõiĐăng Ký

Latest Articles