C#扫描COM端口以获取特定输入

时间:2016-01-09 05:40:14

标签: c# visual-studio arduino serial-port

我正在制作一个可以通过C#控制Arduino板的程序。 以下是该计划需要采取的步骤:

  1. 扫描COM端口
  2. 接收来自设备的输入
  3. 当输入具有特定短语,例如" connectAlready",
  4. 关闭所有端口并在收到短语的端口上创建一个新端口。
  5. 现在程序知道Arduino所在的COM端口,它可以继续执行任务并通过SerialPorts发送命令。
  6. 以下是我目前为connect()方法编写的代码。

    public void connect()
        {
            string[] ports = SerialPort.GetPortNames();
            SerialPort[] serialport = new SerialPort[ports.Length];
            foreach(string p in ports)
            {
                int i = Array.IndexOf(ports, p);
                serialport[i].PortName = p;
                serialport[i].BaudRate = 9600;
                serialport[i].Open();
                //Scan inputs for "connectAlready"
            }
    

    我不知道,并且我一直得到一个" System.NullReferenceException"在serialport [i] .PortName = p;

    如何让这个程序运作?感谢您的所有帮助

2 个答案:

答案 0 :(得分:2)

此点

SerialPort[] serialport = new SerialPort[ports.Length];

您正在此处初始化阵列。 但是在for循环的这一点上,

serialport[i].PortName = p;

该位置的SerialPort对象未初始化。因此,空引用异常

因此,在将任何内容分配给串行端口

之前,请尝试在for循环中添加它
serialport[i]=new SerialPort()

使用你需要的任何构造函数。

答案 1 :(得分:2)

首先,您需要为您创建的每个串行端口声明新的串行端口对象:

    string[] ports = SerialPort.GetPortNames();
    SerialPort[] serialport = new SerialPort[ports.Length];
    foreach(string p in ports)
    {
        int i = Array.IndexOf(ports, p);
        serialport[i] = new SerialPort(); //note this line, otherwise you have no serial port declared, only array reference which can contains real SerialPort object
        serialport[i].PortName = p; 
        serialport[i].BaudRate = 9600;
        serialport[i].Open();
        //Scan inputs for "connectAlready"
    }

然后,您至少需要处理四件事情并处理您的数据:

  1. 串行端口DataReceived的事件处理程序

    serialport[i].DataReceived += serialPort_DataReceived; //This is to add event handler delegate when data is received by the port
    
    private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { //This is to handle the data when it comes
        //Do something on data received
    }
    
  2. 从端口的基础流中获取数据。

    private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) {
        SerialPort serialPort1 = sender as SerialPort; 
        byte[] data = new byte[serialPort1.BytesToRead]; //this is to provide the data buffer
        Stream portStream = serialPort1.BaseStream;
        portStream.Read(data, 0, data.Length); //You get your data from serial port as byte[]
        //Do something on your data
    }
    
  3. Encoding.UTF8.GetString将输入数据从byte[]转换为ASCII个字符(编辑:考虑更改/跳过此步骤,如果收到的数据不是{{,请考虑步骤2 1}}但是byte[]

    ASCII
  4. 检查数据private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { SerialPort serialPort1 = sender as SerialPort; byte[] data = new byte[serialPort1.BytesToRead]; //this is to provide the data buffer Stream portStream = serialPort1.BaseStream; portStream.Read(data, 0, data.Length); //You get your data from serial port as byte[] string dataString = Encoding.UTF8.GetString(data); //here is your data in string //Do something on your data } 是否包含您想要的数据

    string
  5. 作为最后一点,请注意串口中的数据不会聚集在一起(例如" conne"然后" ctAlready")。在这种情况下,您需要先在全局缓冲区中复制接收的数据,然后进行其他检查(使用bool hasData = dataString.Contains("connectAlready"); //this is to check if your data has this, if it doesn't do something

    Buffer.BlockCopy