Thông báo

Collapse
No announcement yet.

Làm sao để C# nhận đủ dữ liệu từ Vi xử lý lên cổng COM?

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • Làm sao để C# nhận đủ dữ liệu từ Vi xử lý lên cổng COM?

    Tình hình là em đã truyền dât từ vi xử lý lên C# được rồi nhưng không hiểu sao mà khi nhấn nút đọc kết quả thì có lúc nó nhận đủ data có khi nó nhận không đủ data đã gửi. Ví dụ dưới vi xử lý gửi là 13523 mà trên C# có khi nhận đủ 13523 cũng có khi nó chỉ nhận là 3 hoặc là 23 hoặc là 523 có khi không có gì. Em đã tìm nhiều cách rồi mà không làm sao cho C# nhận đủ data hết. Mong các Pro giúp em với.
    Code:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    using System.IO.Ports;
    using System.Xml;
    
    namespace Giao_tiep
    {
        public partial class Form1 : Form
        {
    
            SerialPort P = new SerialPort(); // Khai báo 1 Object SerialPort mới.
            string InputData = String.Empty; // Khai báo string buff dùng cho hiển thị dữ liệu sau này.
            delegate void SetTextCallback(string text); // Khai bao delegate SetTextCallBack voi tham so string
            public Form1()
            {
                InitializeComponent();
                string[] ports = SerialPort.GetPortNames();
                // Thêm toàn bộ các COM đã tìm được vào combox cbCom
                cbCom.Items.AddRange(ports); // Sử dụng AddRange thay vì dùng foreach
                P.ReadTimeout = 500;
            }
    
            private void panel1_Paint(object sender, PaintEventArgs e)
            {
    
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
    
            }
    
            private void ngat_Click(object sender, EventArgs e)
            {
                P.Close();
                status.Text = "Đã Ngắt Kết Nối                        ";
                cbCom.Enabled = true;
                ngat.Visible = false;
                ketnoi.Visible = true;
                dockq.Visible = false;
                thoat.Visible = true;
                timer2.Stop();
                data = "";
                kq.Text = "- - - - - ";
            }
    
            private void ketnoi_Click(object sender, EventArgs e)
            {
                try
                {
                    P.BaudRate = 9600;
                    P.DataBits = 8;
                    P.Parity = Parity.None;
                    P.StopBits = StopBits.One;
                    P.Handshake = Handshake.None;
                    ngat.Visible = true;
                    ketnoi.Visible = false;
                    cbCom.Enabled = false;
                    dockq.Visible = true;
                    P.Open();
                    status.Text = "Đang kết nối với cổng " + cbCom.SelectedItem.ToString() + ".";
                    status.ForeColor = Color.Black;
                }
                catch (Exception ex)
                {
                    thoat.Visible = true;
                    dockq.Visible = false;
                    ketnoi.Visible = true;
                    ngat.Visible = false;
                    cbCom.Enabled = true;
                    MessageBox.Show("Không kết nối được.", "Thử lại", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
    
            private void thoat_Click(object sender, EventArgs e)
            {
                this.Close();
            }
    
            private void cbCom_SelectedIndexChanged(object sender, EventArgs e)
            {
                if (P.IsOpen)
                {
                    P.Close(); // Nếu đang mở Port thì phải đóng lại
                }
                P.PortName = cbCom.SelectedItem.ToString(); // Gán PortName bằng COM đã chọn
            }
    
            
            private void dockq_Click(object sender, EventArgs e)
            {
                timer2.Interval = 500;
                timer2.Enabled = true;
                timer2.Start();
            }
    
            private void kq_Click(object sender, EventArgs e)
            {
    
            }
    
            private void timer1_Tick(object sender, EventArgs e)
            {
                thoigian.Text= DateTime.Now.ToString("hh:mm:ss");
            }
    
            private void label1_Click(object sender, EventArgs e)
            {
    
            }
    
            private void statusStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
            {
    
            }
    
            private void thoigian_Click(object sender, EventArgs e)
            {
                
            }
    
            string data;
            private void timer2_Tick(object sender, EventArgs e)
            {
                data = P.ReadExisting();
                thoat.Visible = false;
                if (data != String.Empty)
                {
                    kq.Text = data;
                }
            }            
        }
    }

  • #2
    Trước khi truyền hay nhận dữ liệu, chúng ta có nhiều cách để chắc chẵn rằng:
    - Dữ liệu đó đã truyền/nhận đủ
    - Dữ liệu đó đẫ truyền/nhận sai

    Muốn vậy, cách đơn giản mà tôi chỉ cho bạn đó là:

    Mã mở đầu + Nội dụng + mã kết thúc.

    Ví dụ: @+12345 + 0x1F
    Nếu nhận được mã @ đúng là dữ liệu của mình cần thì nhận cho đến khi nào gặp 0x1F thì dừng, như vậy đảm bảo luôn luôn nhận đủ và nhận đúng

    Comment


    • #3
      Nguyên văn bởi eKhanhHoa Xem bài viết
      Trước khi truyền hay nhận dữ liệu, chúng ta có nhiều cách để chắc chẵn rằng:
      - Dữ liệu đó đã truyền/nhận đủ
      - Dữ liệu đó đẫ truyền/nhận sai

      Muốn vậy, cách đơn giản mà tôi chỉ cho bạn đó là:

      Mã mở đầu + Nội dụng + mã kết thúc.

      Ví dụ: @+12345 + 0x1F
      Nếu nhận được mã @ đúng là dữ liệu của mình cần thì nhận cho đến khi nào gặp 0x1F thì dừng, như vậy đảm bảo luôn luôn nhận đủ và nhận đúng
      Nhưng mà khi truyền lên C# thì làm sao nó loại bỏ được @ và 0x1F để lấy được data anh?

      Comment


      • #4
        giúp em với

        Comment


        • #5
          Em cũng bị cái lỗi giống bác welcomto97. Chỉ đơn thuần là nhận là lưu vào 1 file trên máy tính. Em dùng 1 biến tầm 6kbyte lưu dữ liệu. Sau khi nhận đủ mới lưu vô file. Em dùng vb.net. Việc đóng khung dữ liệu rồi tính checksum khi gửi theo em chỉ giúp nhận chính xác dữ liệu, với những khung bị mất 1 vài byte sẽ loại bỏ không xử lý. Mà đôi khi ta lại quan trọng việc nhận đủ dữ liệu. Để giảm tác động của dây dẫn em đã giảm tốc độ truyền và giảm chiều dài dây dẫn xuống 9600 và 1 m nhưng vẫn không khắc phục hết. Vẫn lỗi nhiều. Bác nào có cao kiến xin chỉ giúp.

          Giải pháp điện tử của bạn

          Comment


          • #6
            Nguyên văn bởi welcometo97 Xem bài viết
            Nhưng mà khi truyền lên C# thì làm sao nó loại bỏ được @ và 0x1F để lấy được data anh?
            Để tách lấy thông tin bác cứ làm như với vi điều khiển. Set thông số để chỉ cần 1 byte trong bộ đệm nhận là phát sinh sự kiện (như kiểu ngắt). Rồi kiểm tra, nếu ok tiến hành nhận, tương tự như với ký tự kết thúc. Chú ý ký tự bắt đầu và kết thúc không được xuất hiện trong dữ liệu. Như em hay làm thì thường chỉ kiểm tra điều kiện bắt đầu khung, rồi áp dụng cách đóng khung kiểm tra dữ liệu như modbus. Điều kiện bắt đầu khung càng đặc biệt càng tốt, ví dụ 0xFF,0xFF. Bác thử theo cách đó xem.

            Giải pháp điện tử của bạn

            Comment


            • #7
              Nguyên văn bởi vuxuansyhut Xem bài viết
              Để tách lấy thông tin bác cứ làm như với vi điều khiển. Set thông số để chỉ cần 1 byte trong bộ đệm nhận là phát sinh sự kiện (như kiểu ngắt). Rồi kiểm tra, nếu ok tiến hành nhận, tương tự như với ký tự kết thúc. Chú ý ký tự bắt đầu và kết thúc không được xuất hiện trong dữ liệu. Như em hay làm thì thường chỉ kiểm tra điều kiện bắt đầu khung, rồi áp dụng cách đóng khung kiểm tra dữ liệu như modbus. Điều kiện bắt đầu khung càng đặc biệt càng tốt, ví dụ 0xFF,0xFF. Bác thử theo cách đó xem.
              Cảm ơn bạn để mình thử xem.
              Ah mà bạn dùng ngắt nào để nhận dữ liệu từ cổng COM? Timer hay serial port

              Comment


              • #8
                Nguyên văn bởi welcometo97 Xem bài viết
                Cảm ơn bạn để mình thử xem.
                Ah mà bạn dùng ngắt nào để nhận dữ liệu từ cổng COM? Timer hay serial port
                Em viết bằng vb.net. Nếu dùng điều khiển mscomm thì là sự kiện oncomm còn nếu dùng serial port thì là sự kiện data recv

                Giải pháp điện tử của bạn

                Comment


                • #9
                  Nguyên văn bởi vuxuansyhut Xem bài viết
                  Em viết bằng vb.net. Nếu dùng điều khiển mscomm thì là sự kiện oncomm còn nếu dùng serial port thì là sự kiện data recv
                  Ah còn cái này nữa.
                  Khi nhận dự liệu Vd: @12345#@12345#@12345# bạn có thuật toán nào để loại bỏ @ và # để lấy 12345 không?

                  Comment


                  • #10
                    Cái này giống trên mà bác. Khi nhận được @ bác bắt đầu lưu, khi nhận được # bác kết thúc lưu. Chuỗi lưu của bác là chuỗi cần lấy.

                    Giải pháp điện tử của bạn

                    Comment


                    • #11
                      chào bạn welcometo97

                      Mình đã gặp phải lỗi như bạn và đã biết cách khắc phục, mình đọc đoạn code của bạn không hiểu tại sao câu lệnh kq.Text = data; trong khối time2 sao không gặp lỗi vì nó bị xung đột dữ liệu, đây là đoạn code của mình bạn tham khảo nhé, project của mình là hiển thị nhiệt độ lên pc băng C#

                      private void timer2_Tick(object sender, EventArgs e)
                      {
                      if (serialPort1.IsOpen)
                      {
                      string s;
                      s = serialPort1.ReadExisting();

                      if (s != "")
                      {
                      Display(s); // ham nay se mo ta sau
                      }
                      // khong the gan box_sent = s duoc vi se bao loi
                      }
                      }
                      private delegate void DlDisplay(string s);
                      private void Display(string abc)
                      {
                      if (name.InvokeRequired)
                      {
                      DlDisplay sd = new DlDisplay(Display);
                      name.Invoke(sd, new object[] { abc });
                      }
                      else
                      {

                      name.Text = abc;
                      }

                      }
                      nếu vẫn nhận thiểu dữ liệu thì bạn đổi time2 thay vì 100ms thành 200ms nhé, còn 1 điều nữa là khi nhận dữ liệu có thế nó sẽ xống dòng hay nó hiện 2 lần j đó thì cái name.text là bạn cho button nhé điều chỉnh cái button đó để đúng theo khuân mẫu mà mình hiển thị thôi, nếu bạn vẫn chưa làm được thì bạn liên hệ với mình qua mail: tdtruong91@gmail.com nhé.

                      Comment

                      Về tác giả

                      Collapse

                      welcometo97 Tìm hiểu thêm về welcometo97

                      Bài viết mới nhất

                      Collapse

                      • tuyennhan
                        Trả lời cho Tiếng Anh cho người Việt
                        bởi tuyennhan
                        Cái thư sai ngay câu chào Dear sir mới đúng Hi chỉ dùng cho người quen , các vấn đề về kỹ thuật nó không trả lời hoặc nói loanh quanh tránh ảnh hưởng đến công ty .
                        Giup1 người cần không giúp người không cần với lại văn mình vợ người nha đừng quên .
                        Hôm qua, 07:44
                      • vi van pham
                        Trả lời cho Tiếng Anh cho người Việt
                        bởi vi van pham
                        Cám ơn những lời chúc tốt đẹp của em.

                        Việc em làm giống như chê sếp dốt, chẳng những không có miếng xôi nào để ăn mà còn chịu nhiều trù dập lên bờ , xuống ruộng.

                        Hãy tránh vết xe đổ của tui đi. Dành thời gian lo cho gia đình....
                        Hôm qua, 02:00
                      • nhathung1101
                        Trả lời cho Tiếng Anh cho người Việt
                        bởi nhathung1101
                        Ngoại ngữ là không thể thiếu, nhất là làm việc với công nghệ.

                        Nhưng học để tán gái hay để đọc datasheet, manual là chuyện cần quan tâm.

                        Và đọc ở nguồn nào đáng tin cậy, chứ cứ lên tictok hay facebook học lỏm thì...
                        22-02-2025, 22:18
                      • dinhthuong80
                        Trả lời cho Tiếng Anh cho người Việt
                        bởi dinhthuong80
                        Bác nói rất khách quan và chính xác. Ngoại ngữ là chìa khóa thăng tiến dù làm gì. Chả thế mà nay nước mình dạy tiếng Anh từ tiểu học.

                        Nhớ hồi năm 2006 em ra Hải Phòng, Hải Dương tìm việc, thời đó ở Bình Dương lương công...
                        22-02-2025, 14:51
                      • dinhthuong80
                        Trả lời cho Tiếng Anh cho người Việt
                        bởi dinhthuong80
                        Cảm ơn bạn, ĐT cũng có ý nghĩ như vậy.

                        Thực ra, lỗi của hãng đó ( gọi là hãng vì không chỉ một model sản phẩm) là về phần cứng, ĐT tuy không biết về lập trình phần mềm nhưng cũng thấy rằng sẽ chẳng khó khăn gì đáng...
                        22-02-2025, 14:39
                      • dinhthuong80
                        Trả lời cho Tiếng Anh cho người Việt
                        bởi dinhthuong80
                        Dạ, bác bảy mấy tuổi đời rồi cũng không kém bố cháu bao nhiêu. Tuổi nghề thì bác cũng đáng tuổi cha chú.

                        Nhưng 2 điều trên thì chưa hẳn đã đáng quí và đáng tôn trọng bằng việc bác rất nhiệt tình chia sẻ kinh nghiệm chuyên...
                        22-02-2025, 14:28
                      • bqviet
                        Trả lời cho Tiếng Anh cho người Việt
                        bởi bqviet
                        Đúng, nếu chú tâm thì chỉ cần mỗi tiếng Việt là đã khá đủ để làm đa số công việc thông thường, ở thời đại ngày nay khi tài liệu sách vở phương tiện thông tin liên lạc đã nhiều. Nhưng cũng chính ở thời nay giao lưu các nước nhiều...
                        21-02-2025, 20:26
                      • mèomướp
                        Trả lời cho Tiếng Anh cho người Việt
                        bởi mèomướp
                        Dạ cháu nghĩ chú dinh... cứ mạnh dạn gửi thư đi ạ, chú có thể gửi bằng văn bản in chuyển phát nhanh sẽ có giá trị hơn. Vấn đề chưa hẳn là cần hãng làm gì đó, mà chỉ đơn giản là mình cảm thấy nhẹ lòng vì đã làm những việc bản...
                        21-02-2025, 12:32
                      • vi van pham
                        Trả lời cho Tiếng Anh cho người Việt
                        bởi vi van pham
                        Những lần hắt hơi sổ mũi làm tôi mệt lã, phải dùng rượu uống để ngũ. Tôi cũng đang uống rượu 1 mình, viết vài dòng này cho em ( có lẽ dt chỉ bằng tuổi em tôi).

                        Dinh thuong dang đi vào vết xe đổ của tôi. Càng chứng minh, có...
                        20-02-2025, 21:31
                      • bqviet
                        Trả lời cho Hỏi về cách hàn linh kiện ( giúp tớ với )
                        bởi bqviet
                        Thiết nghĩ thi thoảng bác lên đây chia xẻ ít kinh nghiệm cũng vui rồi. Còn chuyện con người sinh lão bệnh tử là thường, sống cùng với quy luật đó thôi. Bqv nhớ trước đây bác từng kể về chuyện rang chì ô-xít bằng chảo để phục hồi bình điện, đấy cũng là thành quả đáng nể phục ở thời kỳ thiếu thốn đó.
                        20-02-2025, 17:22
                      Đang tải...
                      X