Работа через COM-порт

Тема в разделе "Arduino & Shields", создана пользователем last1971, 22 апр 2014.

  1. last1971

    last1971 Нерд

    Вопрос как быстро узнать на каком порту висит ARDUINO.
    Я сделал следующим образом, получаю список портов, пишу в них поочередно, получаю ответ, если ответ соответствует тому что должна написать Arduino на запрос, то оставляю именно этот порт для дальнейшей работы. Но приходится делать задержку, а так же есть порты блютуса, один из которых долго думает на открытие, другому пришлось прописать WriteTimeout, который как оказалось по умолчанию бесконечен. Вообще может есть какое-то более быстрое и изящное решение.
     
  2. Airbus

    Airbus Радиохулиган Модератор

    Заходим в диспетчер устройств (в разных Виндах по разному у меня ХР)и там всё будет написано.Если СОМ овская Ардуина то порт СОМ1 как правило
     
  3. last1971

    last1971 Нерд

    Хочется по принципу: "включил-работает", т.е. сейчас в конечной программе я предлагаю выбрать, понятно что его можно выбрать посмотрев порты в диспетчере устройств, или тыкая во все подряд. Но задача стоит в другом, что бы программа быстро (сейчас это может занимать до 5 секунд из-за портов блютуса о которых писал выше) определяла на каком порту висит ардуино.
     
  4. Mitrandir

    Mitrandir Гуру

    Создать н потоков, каждый поток опоашивает свой ком порт. Как только ардуино откликнется, убиваем все лишние потоки
     
  5. last1971

    last1971 Нерд

    Спасибо. Попробую
     
  6. Unixon

    Unixon Оракул Модератор

    Еще вариант - попросить у системы список устройств и по VID / PID найти ардуиновский порт.
     
  7. last1971

    last1971 Нерд

    А VID / PID для всех Arduino одинаковый или отличается?
     
  8. Unixon

    Unixon Оракул Модератор

    Для одинаковых ардуин должен совпадать. Но отделить ардуиновские порты от всех остальных это уже пол дела. Потом можно смелее опрашивать, зная, что левому устройству ненужные данные не уйдут.
     
  9. Alex19

    Alex19 Гуру

    Можно и так.

    Если на Windows и .Net (Код на C#)
    Можно так

    Код (Text):

    using System.Management;

    private void FillPortComboBox()
    {
        // Чистим комбо бокс
        port_combobox.Items.Clear();

        // TODO: Надо разобраться с ManagementScope
        ManagementScope connectionScope = new ManagementScope();
     
        //SelectQuery serialQuery = new SelectQuery("SELECT * FROM Win32_SerialPort WHERE Caption LIKE '%Arduino%'");
        SelectQuery serialQuery = new SelectQuery("SELECT * FROM Win32_SerialPort WHERE Description LIKE '%Arduino%'");
        ManagementObjectSearcher searcher = new ManagementObjectSearcher(connectionScope, serialQuery);

        // Пробегаемся, по выбранным портам
        foreach (ManagementObject item in searcher.Get())
        {
            // Получаем, имя порта
            string portName = item["DeviceID"].ToString();

            // Инициализируем Serial порт
            SerialPort tempSerialPort = new SerialPort(portName);
            try
            {
                // Пытаемся открыть порт, вдруг занят
                tempSerialPort.Open();

                // Проверяем, открылся ли
                if (tempSerialPort.IsOpen)
                {
                    // Если открылся, добавляем в комбобокс
                    port_combobox.Items.Add(portName);

                    // Закрываем соединения
                    tempSerialPort.Close();
                }
            }
            catch { }
        }

        // Добавляем в начало комбобокса пояснительный текст
        port_combobox.Items.Insert(0, "Укажите Serial порт");

        // Задаем индекс комбобокса
        port_combobox.SelectedIndex = 0;
    }
     
    Еще не разобрался с классом ManagementScope. Но уже проверил, работает.

    Нашел тута
    http://stackoverflow.com/questions/3293889/how-to-auto-detect-arduino-com-port

    Еще пример, сделанный немного по другому
    http://playground.arduino.cc/Csharp/SerialCommsCSharp
    Тут перебираются порты и отправляется команда и ожидается ответ.
    Плюс в том, что если 2 и более ардуины, можно определить, какая для каких операций, отправляя разные ответы.
     
  10. last1971

    last1971 Нерд

    Увы ManagementScope - похоже не реализован в с++
    У меня что-то похожее на второй пример. Но обратите внимание на задержку в 1 секунду по Вашей ссылке. Я у себя проставил по 0,1. Плюс если не проставить arduino->WriteTimeout=500; то все радостно виснет при попытке писать в третий ком, на котором сидит блютуз.
    Вообщем идея с потоками кажется наиболее перспективной, но опять же посмотрев как оно реализовано в с++, решил пока отложить переписывание, ибо из-за банальной проблемы коннекта получается целый огород.
     
  11. Alex19

    Alex19 Гуру

    Понятно, значит у Вас не .Net Framwork.

    Тогда гляньте WMI (Windows Management Instrumentation) в С++, в windows есть. На С++ не пишу, но посмотрите в инте, думаю найдете.

    Может это
    http://win32easy.blogspot.com/2011/03/wmi-in-c-query-everyting-from-your-os.html
    http://www.codeproject.com/Articles/10539/Making-WMI-Queries-In-C

    Минусы использования WMI, только Windows. Но это просто один из вариантов получить описания устройства. Возможно сделать это по другом в других ОС.

    Это была по сути реализация предложения Unixon, просто смотрится не VIN/PID.
    Да обратил внимание на нее, не люблю лишние задержки.

    Дело вкуса.

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