当前位置:  开发笔记 > 编程语言 > 正文

如何自动检测Arduino COM端口?

如何解决《如何自动检测ArduinoCOM端口?》经验,为你挑选了3个好方法。



1> Brandon..:

这一小段代码对此表现非常好(返回COM端口字符串,如果检测到Arduino则返回"COM12"):

private string AutodetectArduinoPort()
        {
            ManagementScope connectionScope = new ManagementScope();
            SelectQuery serialQuery = new SelectQuery("SELECT * FROM Win32_SerialPort");
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(connectionScope, serialQuery);

            try
            {
                foreach (ManagementObject item in searcher.Get())
                {
                    string desc = item["Description"].ToString();
                    string deviceId = item["DeviceID"].ToString();

                    if (desc.Contains("Arduino"))
                    {
                        return deviceId;
                    }
                }
            }
            catch (ManagementException e)
            {
                /* Do Nothing */
            }

            return null;
        }


请记住添加System.Management引用.
它显示为"USB串行端口"(并且deicimila也响应相同).对我来说,唯一真正的解决方案是打开每个COM端口,发送一个魔术字节并听取魔法响应,就像其他答案所暗示的那样.

2> SwDevMan81..:

    您可以使用SerialPort.GetPortNames()返回字符串COM端口名称的数组.

    我不认为你可以自动检测端口,你必须ping设备,以查看设备是否已连接.


这篇文章(http://stackoverflow.com/questions/195483/c-check-if-a-com-serial-port-is-already-open)讲述了如何查找端口是否正在使用中.基本上你需要尝试打开它们.如果你得到一个例外,那么它可能正在使用中.如果打开正常,您可以检查IsOpen属性以验证其已连接.我会从Arduino板上找到最小的消息或修订响应消息,以验证您实际上是连接到电路板而不是其他设备.

3> Apache..:

进一步采用WMI管理路径,我想出了一个包装类,它挂接到Win32_SerialPorts事件,并动态填充了Arduino和Digi International(X-Bee)设备的SerialPort列表,以及PortNames和BaudRates.

现在,我已经使用Win32_SerialPorts条目中的设备描述字段作为字典的键,但这很容易改变.

它已经通过Arduino UNO进行了有限的测试,看起来很稳定.

// -------------------------------------------------------------------------
//  
//      Copyright (c) ApacheTech Consultancy. All rights reserved.
//  
//  
//      This program is free software: you can redistribute it and/or modify
//      it under the terms of the GNU General Public License as published by
//      the Free Software Foundation, either version 3 of the License, or
//      (at your option) any later version.
// 
//      This program is distributed in the hope that it will be useful,
//      but WITHOUT ANY WARRANTY; without even the implied warranty of
//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//      GNU General Public License for more details.
// 
//      You should have received a copy of the GNU General Public License
//      along with this program. If not, see http://www.gnu.org/licenses
//  
// -------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO.Ports;
using System.Linq;
using System.Management;
using System.Runtime.CompilerServices;

// Automatically imported by Jetbeans Resharper
using ArduinoLibrary.Annotations;

namespace ArduinoLibrary
{
    /// 
    ///     Provides automated detection and initiation of Arduino devices. This class cannot be inherited.
    /// 
    public sealed class ArduinoDeviceManager : IDisposable, INotifyPropertyChanged
    {
        /// 
        ///     A System Watcher to hook events from the WMI tree.
        /// 
        private readonly ManagementEventWatcher _deviceWatcher = new ManagementEventWatcher(new WqlEventQuery(
            "SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2 OR EventType = 3"));

        /// 
        ///     A list of all dynamically found SerialPorts.
        /// 
        private Dictionary _serialPorts = new Dictionary();

        /// 
        ///     Initialises a new instance of the  class.
        /// 
        public ArduinoDeviceManager()
        {
            // Attach an event listener to the device watcher.
            _deviceWatcher.EventArrived += _deviceWatcher_EventArrived;

            // Start monitoring the WMI tree for changes in SerialPort devices.
            _deviceWatcher.Start();

            // Initially populate the devices list.
            DiscoverArduinoDevices();
        }

        /// 
        ///     Gets a list of all dynamically found SerialPorts.
        /// 
        /// A list of all dynamically found SerialPorts.
        public Dictionary SerialPorts
        {
            get { return _serialPorts; }
            private set
            {
                _serialPorts = value;
                OnPropertyChanged();
            }
        }

        /// 
        ///     Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// 
        public void Dispose()
        {
            // Stop the WMI monitors when this instance is disposed.
            _deviceWatcher.Stop();
        }

        /// 
        ///     Occurs when a property value changes.
        /// 
        public event PropertyChangedEventHandler PropertyChanged;

        /// 
        ///     Handles the EventArrived event of the _deviceWatcher control.
        /// 
        /// The source of the event.
        /// The  instance containing the event data.
        private void _deviceWatcher_EventArrived(object sender, EventArrivedEventArgs e)
        {
            DiscoverArduinoDevices();
        }

        /// 
        ///     Dynamically populates the SerialPorts property with relevant devices discovered from the WMI Win32_SerialPorts class.
        /// 
        private void DiscoverArduinoDevices()
        {
            // Create a temporary dictionary to superimpose onto the SerialPorts property.
            var dict = new Dictionary();

            try
            {
                // Scan through each SerialPort registered in the WMI.
                foreach (ManagementObject device in
                    new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_SerialPort").Get())
                {
                    // Ignore all devices that do not have a relevant VendorID.
                    if (!device["PNPDeviceID"].ToString().Contains("VID_2341") && // Arduino
                        !device["PNPDeviceID"].ToString().Contains("VID_04d0")) return; // Digi International (X-Bee)

                    // Create a SerialPort to add to the collection.
                    var port = new SerialPort();

                    // Gather related configuration details for the Arduino Device.
                    var config = device.GetRelated("Win32_SerialPortConfiguration")
                                       .Cast().ToList().FirstOrDefault();

                    // Set the SerialPort's PortName property.
                    port.PortName = device["DeviceID"].ToString();

                    // Set the SerialPort's BaudRate property. Use the devices maximum BaudRate as a fallback.
                    port.BaudRate = (config != null)
                                        ? int.Parse(config["BaudRate"].ToString())
                                        : int.Parse(device["MaxBaudRate"].ToString());

                    // Add the SerialPort to the dictionary. Key = Arduino device description.
                    dict.Add(device["Description"].ToString(), port);
                }

                // Return the dictionary.
                SerialPorts = dict;
            }
            catch (ManagementException mex)
            {
                // Send a message to debug.
                Debug.WriteLine(@"An error occurred while querying for WMI data: " + mex.Message);
            }
        }

        /// 
        ///     Called when a property is set.
        /// 
        /// Name of the property.
        [NotifyPropertyChangedInvocator]
        private void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

推荐阅读
爱唱歌的郭少文_
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有