2010-06-01 28 views
5

Tôi đã thiết lập một SerialDataReceivedEventHandler, với một biểu mẫu dựa trên chương trình trong VS2008 express. cổng nối tiếp của tôi được thiết lập như sau:C# .Net Serial DataReceived Phản hồi sự kiện quá chậm đối với dữ liệu tốc độ cao

115200, 8N1

DTR và RTS kích hoạt

ReceivedBytesThreshold = 1

Tôi có một thiết bị Tôi interfacing với hơn một BlueTooth, USB để nối tiếp . Thiết bị đầu cuối siêu nhận dữ liệu tốt ở bất kỳ tốc độ dữ liệu nào. Dữ liệu được gửi thường xuyên trong các gói dài 22 byte. Thiết bị này có tốc độ điều chỉnh dữ liệu được gửi. Ở tốc độ dữ liệu thấp, 10-20Hz, mã bên dưới hoạt động rất tốt, không có vấn đề gì. Tuy nhiên, khi tôi tăng tốc độ dữ liệu qua 25Hz, có bắt đầu nhận được các gói mulitple trên một cuộc gọi. Những gì tôi có nghĩa là bằng cách này là phải có một sự kiện kích hoạt cho mỗi gói tin đến. Với tốc độ đầu ra cao hơn, tôi đã kiểm tra kích thước bộ đệm (lệnh BytesToRead) ngay lập tức khi sự kiện được gọi và có nhiều gói trong bộ đệm sau đó. Tôi nghĩ rằng sự kiện cháy chậm và vào thời điểm nó đạt đến mã, nhiều gói hơn đã đạt đến bộ đệm. Một thử nghiệm tôi làm là xem có bao nhiêu thời gian sự kiện được kích hoạt mỗi giây. Tại 10Hz, tôi nhận được 10 trình kích hoạt sự kiện, tuyệt vời. Tại 100Hz, tôi nhận được một cái gì đó giống như 40 sự kiện gây nên, không tốt. Mục tiêu của tôi cho tốc độ dữ liệu là 100HZ là chấp nhận được, ưu tiên 200Hz và tối ưu 300Hz. Điều này sẽ làm việc bởi vì ngay cả ở 300Hz, đó là chỉ 52800bps, ít hơn một nửa của tốc độ truyền 115200 thiết lập. Bất cứ điều gì tôi đang tìm kiếm?

public Form1() 
    { 
     InitializeComponent(); 
     serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);    
    } 


    private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) 
    { 
     this.Invoke(new EventHandler(Display_Results)); 
    } 


    private void Display_Results(object s, EventArgs e) 
    { 
     serialPort1.Read(IMU, 0, serial_Port1.BytesToRead); 
    } 

Trả lời

3

Tại sao bạn gọi() cuộc gọi đến DisplayResults?

Điều này sẽ đẩy nó vào MessageLoop, một sự chậm trễ không cần thiết.

Sẽ tốt hơn nếu DataReceived() đẩy dữ liệu lên hàng đợi (chủ đề an toàn) để xử lý tách rời.

Tôi cũng nghĩ rằng bạn có thể gặp sự cố với các gói bị tách.

+0

Tôi đã thử xóa cuộc gọi Invoke() và đọc dữ liệu trực tiếp trong sự kiện DataReceived() với cùng kết quả. Xin lỗi là một chút ngây thơ, nhưng bạn có thể cho tôi biết thêm về cách bạn thực hiện hàng đợi và tại sao nó hoạt động nhanh hơn. Cảm ơn đã giúp đỡ. – Matthew

1

Bạn thể thử thiết ReceivedBytesThreshold = 22, mà sẽ dẫn đến sự kiện này được kích hoạt khi có ít nhất 22 byte để đọc. Lưu ý rằng nó sẽ là ít nhất 22. Có thể có nhiều hơn.

Tôi không nghĩ mình sẽ làm điều này, bởi vì điều gì sẽ xảy ra nếu kích thước gói của bạn thay đổi trong tương lai, ví dụ 12 byte? Bạn sẽ kết thúc với 12 byte trong bộ đệm nhưng không kích hoạt sự kiện nào cả.

Tốt hơn là đặt nó thành 1, sẽ kích hoạt sự kiện khi ít nhất 1 byte khả dụng. Sau đó đẩy tất cả các byte đã nhận vào danh sách hoặc một hàng đợi như Henk đã đăng.

Lưu ý rằng DataReceivedEvent không có kiến ​​thức về những gì bạn xem xét một gói dữ liệu là tất nhiên. Nó chỉ cháy khi có sẵn byte. Nhà phát triển có thể tập hợp các byte này thành một thông báo hay gói tin có ý nghĩa.

4

Bạn đã thử khắc phục thời gian trễ trên bộ chuyển đổi nối tiếp USB chưa? Tôi đã có cùng một vấn đề với một FTDI USB để chuyển đổi nối tiếp. Tôi sử dụng một dao động để xem dữ liệu IN và OUT của tôi xuất phát từ thiết bị và tôi có thể thấy rằng máy tính luôn phản hồi chậm. Theo mặc định, thời gian chờ trên thiết bị được đặt thành 16 mili giây. Tôi đã thay đổi nó thành 2 ms và nó tạo ra sự khác biệt lớn. Chuyển đến Bộ chuyển đổi nối tiếp USB của bạn trong Trình quản lý thiết bị và trong cài đặt nâng cao, hãy thay đổi thời gian chờ thành 2 ms. Nó sẽ hoạt động.Thử nó.

+1

Bất kỳ ý tưởng nào tại sao độ trễ "16ms" chuyển thành hàng trăm mili giây giữa các nhóm dữ liệu nhận được? – supercat

0

Sự cố nằm trong trình xử lý dữ liệu đã nhận.

Tôi đã chạy một chuỗi riêng biệt với một vòng lặp while(true)serial.ReadLine(), tất cả đều hoạt động hoàn hảo.

using System.Threading; 

Thread readThread = new Thread(Read); 
readThread.Start(); 

Hy vọng người khác không cần phải bỏ ra 3 giờ để sửa lỗi này.

Các vấn đề liên quan