Member 13430184 Ответов: 3

Чтение последовательного порта в C#


Привет,

I am trying to talk to an Aglient device via C# through a RS232 connection on my PC with XP OS and I am having trouble. I can send a command, such has a query (*IDN?), and I never get a response in my GUI. However, if I open hyperterminal the device IDN shows up in hyperterminal like it should have showed up in my GUI. From my C# GUI, I can sent a cammand to the device to change voltage level and the device changes voltage level as I can see it on the device display. However, when I send a query to the device, I expect to see data in the input buffer that was sent by the device, but the input buffer is always empty. I have connect more than one device and I have yet to read any data from the input buffer. I can write to the output buffer and read the correct reponse from the input buffer using hyperterminal and Labview. I can send the query via my C# GUI and read the correct response from the input buffer using hyperterminal and Labview. Is there a bug when reading the input buffer using C#?

Что я уже пробовал:

это мой код.:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        // Set the COM1 serial port to speed = 4800 baud, parity = odd,
        // data bits = 8, stop bits = 1.
        SerialPort port = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);

        public Form1()
        {
            InitializeComponent();
            this.sendRead.Text = "Enter Commands or queries here";

            // set read time out to 2 seconds
            port.ReadTimeout = 2000;

            // open serial port
            port.Open();

            //Enable Event Handler
            port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
        }

        private void sendRead_TextChanged(object sender, EventArgs e)
        {
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                //write line to serial port
                port.WriteLine(sendRead.Text);

                //clear the text box
                sendRead.Text = "";
            }

            catch (System.Exception ex)
            {
                sendRead.Text = ex.Message;
            }
        }

        private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            int intBuffer;
            intBuffer = port.BytesToRead;
            byte[] byteBuffer = new byte[intBuffer];
            port.Read(byteBuffer, 0, intBuffer);
            this.Invoke(new EventHandler(DoUpDate));
        }

        private void DoUpDate(object s, EventArgs e)
        {
            sendRead.Text = port.ReadLine();
        }

        private void Form1_FromClosing(object sender, EventArgs e)
        {
            port.Close();
        }
    }
}

3 Ответов

Рейтинг:
19

CPallini

Цитата:
частная port_DataReceived недействительным(объект отправителя, SerialDataReceivedEventArgs е)
{
инт intBuffer;
intBuffer = порт.BytesToRead;
byte[] byteBuffer = новый байт[intBuffer];
port.Read(byteBuffer, 0, intBuffer); //<--- Вы читаете (и отбрасываете) данные здесь
этот.Invoke(new EventHandler(DoUpDate));
}

private void DoUpDate(объект s, EventArgs e)
{
sendRead.Text = port.ReadLine(); //<--- вы пытаетесь прочитать снова
}


Проблема в том, что Вы читаете, а затем отбрасываете прочитанные данные внутри устройства. DataReceived обработчик. Вы должны передать прочитанные данные в DoUpdate метод.


Member 13430184

он все равно не работает, я получаю ошибку в устройстве(запрос прерван
Была получена команда, которая отправляет данные в выходной буфер, но
выходной буфер содержал данные из предыдущей команды (предыдущие данные не являются
перезаписанный). Выходной буфер очищается при выключенном питании или после первого включения питания.
команда (сброс) была выполнена. ) в устройстве

Рейтинг:
1

Patrice T

// Set the COM1 serial port to speed = 4800 baud, parity = odd,
// data bits = 8, stop bits = 1.
SerialPort port = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);

Комментарий и код расходятся во мнениях о скорости и четности, какой из них правильный ?
Цитата:
Однако, если я открою hyperterminal, IDN устройства появится в hyperterminal так же, как он должен был появиться в моем графическом интерфейсе.

Используя Hyper terminal, вы можете проверить, правильно ли ваше графическое приложение отправляет команду на устройство.


Member 13430184

комментарий не правильный, моя проблема в том, что я не могу получить весь ответ, я получаю только конец ответа, я думаю, что кабель rs232 медленно получает весь ответ, может быть, у вас есть решение этой проблемы ??

Рейтинг:
0

OriginalGriff

Попробуйте установить DtrEnable[^] и RtsEnable[^] свойства для true: возможно, устройство ожидает аппаратного квитирования, которое HyperTerminal устанавливает высоко.

Но также попробуйте добавить данные с вашего устройства в строку в вашем методе DoUpDate:

private void DoUpDate(object s, EventArgs e)
        {
            sendRead.Text += port.ReadLine();
        }
Последовательные порты - это медленные устройства-9600 бод меньше 1000 символов в секунду, поэтому вы, скорее всего, получите отдельное событие DataReceived для каждого символа. Если последний из них является пробелом или непечатаемым, вы можете не увидеть ничего полезного в своем текстовом поле.


Member 13430184

большое вам спасибо, теперь я получаю значения, но они не совпадают со значениями, отображаемыми на экране, например, значение на дисплее равно 5 В, и я получаю в своей программе 400E:00

OriginalGriff

Для этого вам нужно прочитать руководство: то, что вы получаете, вероятно, является "сырым" значением AtoD-конвертера, которое должно быть "масштабировано" до экранного значения.

Member 13430184

Я думаю, что последовательный порт работает медленно, есть ли какое-то решение этой проблемы?