SerialPort не получает никаких данных - PullRequest
10 голосов
/ 18 января 2012

Я разрабатываю программу, которая должна взаимодействовать с COM-портами.

Извлекая уроки из этого Q & A: .NET SerialPort DataReceived, событие не запускается , я делаю свой код таким образом.

namespace ConsoleApplication1
{
 class Program
 {
    static SerialPort ComPort;        

    public static void OnSerialDataReceived(object sender, SerialDataReceivedEventArgs args)
    {
        string data = ComPort.ReadExisting();
        Console.Write(data.Replace("\r", "\n"));
    }

    static void Main(string[] args)
    {
        string port = "COM4";
        int baud = 9600;
        if (args.Length >= 1)
        {
            port = args[0];
        }
        if (args.Length >= 2)
        {
            baud = int.Parse(args[1]);
        }

        InitializeComPort(port, baud);

        string text;
        do
        {
            String[] mystring = System.IO.Ports.SerialPort.GetPortNames();

            text = Console.ReadLine();
            int STX = 0x2;
            int ETX = 0x3;
            ComPort.Write(Char.ConvertFromUtf32(STX) + text + Char.ConvertFromUtf32(ETX));
        } while (text.ToLower() != "q");
    }

    private static void InitializeComPort(string port, int baud)
    {
        ComPort = new SerialPort(port, baud);
        ComPort.PortName = port;
        ComPort.BaudRate = baud;
        ComPort.Parity = Parity.None;
        ComPort.StopBits = StopBits.One;
        ComPort.DataBits = 8;
        ComPort.ReceivedBytesThreshold = 9;
        ComPort.RtsEnable = true;
        ComPort.DtrEnable = true;
        ComPort.Handshake = System.IO.Ports.Handshake.XOnXOff;
        ComPort.DataReceived += OnSerialDataReceived;            
        OpenPort(ComPort);            
    }

    public static void OpenPort(SerialPort ComPort)
    {   
        try
        {   
            if (!ComPort.IsOpen)
            {
                ComPort.Open();                    
            }
        }
        catch (Exception e)
        {
            throw e;
        }
    }
}
}

Моя проблема в том, что событие DataReceived никогда не запускается.

Спецификации моей программы:

  1. Просто .net программирование консоли
  2. Я использую VSPEс http://www.eterlogic.com
  3. Мой компьютер уже имеет порты COM1 и COM2.
  4. Я создал COM2 и COM4 с помощью VSPE.
  5. Я получаю результат вывода из массива mystring (COM1,COM2, COM3, COM4)

Но я до сих пор не знаю, почему событие DataReceived не запускается.


Обновлено

К сожалению, яЯ все еще не мог вызвать событие DataReceived.

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

В этом новом проекте [просто консольприложение], я создал класс ...

public class MyTest
{
    public SerialPort SPCOM4;

    public MyTest()
    {

        SPCOM4 = new SerialPort();
        if(this.SerialPortOpen(SPCOM4, "4"))
        {
            this.SendToPort(SPCOM4, "com test...");
        }

    }

    private bool SerialPortOpen(System.IO.Ports.SerialPort objCom, string portName)
    {
        bool blnOpenStatus = false;
        try
        {
            objCom.PortName = "COM" + portName;
            objCom.BaudRate = 9600;
            objCom.DataBits = 8;

            int SerParity = 2;
            int SerStop = 0;

            switch (SerParity)
            {
                case 0:
                    objCom.Parity = System.IO.Ports.Parity.Even;
                    break;
                case 1:
                    objCom.Parity = System.IO.Ports.Parity.Odd;
                    break;
                case 2:
                    objCom.Parity = System.IO.Ports.Parity.None;
                    break;
                case 3:
                    objCom.Parity = System.IO.Ports.Parity.Mark;
                    break;
            }

            switch (SerStop)
            {
                case 0:
                    objCom.StopBits = System.IO.Ports.StopBits.One;
                    break;
                case 1:
                    objCom.StopBits = System.IO.Ports.StopBits.Two;
                    break;
            }

            objCom.RtsEnable = false;
            objCom.DtrEnable = false;
            objCom.Handshake = System.IO.Ports.Handshake.XOnXOff;
            objCom.Open();
            blnOpenStatus = true;

        }
        catch (Exception ex)
        {
            throw ex;
        }
        return blnOpenStatus;
    }

    private bool SendToPort(System.IO.Ports.SerialPort objCom, string strText)
    {
        try
        {
            int STX = 0x2;
            int ETX = 0x3;

            if (objCom.IsOpen && strText != "")
            {
                objCom.Write(Char.ConvertFromUtf32(STX) + strText + Char.ConvertFromUtf32(ETX));
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
        return true;
    }
}

Я не уверен, что мне грозит удача или неудача, потому что этоновый класс может вызвать событие fire DataReceived, которое происходит от более старого консольного приложения, которое все еще работает.Для меня это чудо, что я понятия не имею, как это происходит.

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

  1. Наконец я создал 2консольные проекты.
  2. Первый проект - это класс, который я опубликовал вчера как вопрос.
  3. Второй проект - это класс с именем MyTest, который может вызвать событие DataReceived из первого проекта.время, когда запущено два проекта.

Может ли кто-нибудь дать мне советы о том, как можно объединить эти два проекта в один проект?

Ответы [ 3 ]

19 голосов
/ 18 января 2012
    ComPort.Handshake = Handshake.None;

Проблема не в том, что событие DataReceived не запускается, а в том, что последовательный порт не получает никаких данных.Очень, очень мало последовательных устройств, которые вообще не используют рукопожатие.Если вы установите None, драйвер не будет включать сигналы DTR (Data Terminal Ready) и RTS (Request To Send).Устройство последовательного порта интерпретируется как «машина выключена (DTR)» или «машина не готова к приему данных (RTS)».Таким образом, оно ничего не отправит, и ваше событие DataReceived не сработает.

Если вы действительно хотите None, установите для свойств DTREnable и RTSEnable значение true.Но, скорее всего, вам нужен HandShake.RequestToSend, так как устройство, похоже, обращает внимание на сигналы рукопожатия.

Если у вас все еще есть проблемы, тогда используйте другую программу последовательного порта, такую ​​как Putty или HyperTerminal, чтобы обеспечить соединение и параметры связи.хороши и устройство отзывчиво.Утилита SysInternals PortMon дает низкоуровневое представление о взаимодействии драйверов, так что вы можете сравнить хорошее и плохое.

0 голосов
/ 08 июня 2012

У меня была довольно похожая проблема. В графическом приложении (C # win form) у меня был класс, который инкапсулирует компонент SerialPort. Событие DataReceived срабатывало только один раз, но затем все последующие полученные данные не вызывали событие. Я решил проблему, вызвав метод Close в своей основной функции Closed. Понятия не имею, почему это что-то меняет, но теперь оно работает.

0 голосов
/ 18 января 2012

Я никогда не работал с VSPE, поэтому не уверен, вызывает ли это проблему. Я работал с COM-портом раньше, и я посмотрел свой код. Единственное главное отличие - это способ объявления события. У вас есть:

ComPort.DataReceived += OnSerialDataReceived;

У меня это так:

ComPort.DataReceived += new SerialDataReceivedEventHandler(OnSerialDataReceived);

OnSerialDataReceived - ваш обработчик событий. Я не уверен, будет ли это иметь какое-либо значение, но вы можете попробовать это. Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...