Конференция "WinAPI" » Как определить номер COM порта? [D7, WinXP]
 
  • KoTangens (27.06.09 00:40) [0]
    Есть усторйство, аппаратно формирующее COM. (Подключается на  USB). Со своим драйвером. Дальше работаю с COMom просто функциями API. Можно ли как то теми же API выяснить на какой порт оно село?
  • Германн © (27.06.09 01:47) [1]

    >
    > KoTangens   (27.06.09 00:40)
    >
    > Есть усторйство, аппаратно формирующее COM. (Подключается
    > на  USB). Со своим драйвером. Дальше работаю с COMom просто
    > функциями API. Можно ли как то теми же API выяснить на какой
    > порт оно село?
    >

    Имхо, в общем случае нет. И в том же "общем случае" больше проблем, чем ответов.
  • Цукор5 (30.06.09 00:27) [2]
    Можно получить список всех портов.
    А далее следующее : получаешь список до подключения и после.
    Естественно вариант от Лукавого...но все же ))
  • brother © (30.06.09 04:27) [3]
    вероятно возможно, я бы сделал так:
    1. получаю список всех портов или начинаю перебирать порты ну например от 1 до 23 ;)
    2.
    > Дальше работаю с COMom просто функциями API

    значит есть функция инициализации версии или чего подобного? (может что-то специфичное для данного железа) отправляем на порт и ждем результат...
    3. устройство отозвалось? значит это тот порт))))
  • KoTangens (01.07.09 01:34) [4]
    Спасибо за советы.

    Цукору: тоже об этом думала, но тогда есть обязательное условие - программу надо запустить перед тем как воткнуть устройство, а не после. А это плохо.

    брату: точно, есть. Надо попробовать. Правда где-то читала, что такой метод перебора медленно работает.
  • brother © (01.07.09 04:22) [5]
    >
    > брату: точно, есть. Надо попробовать. Правда где-то читала,
    > что такой метод перебора медленно работает.

    один раз определишь - создашь ini и все)
  • brother © (01.07.09 04:23) [6]
    > обязательное условие - программу надо запустить перед тем
    > как воткнуть устройство, а не после

    эээээ
    тогда только точно вручную знать номер порта... или запускать 1 раз для детекта, как я предложил...
  • Дмитрий (01.07.09 07:51) [7]
    Что за устройство хоть ? Имел опыт работы с 5-6 разновидностями устройств работающих по RS-232, есть конечно коленные самоделки, но ...
  • KoTangens (01.07.09 15:18) [8]
    Это некий мед прибор. Там лазеры стоят, я не сильно в курсе электроники - ее мой муж делал. Я пишу интерфейс - установка времени воздействия, частоты, лог. Сейчас сом надо вручную выбирать из списка дотупных. Но заказчик говорит, что врачам сложно - хотят чтобы включил и "оно само работало". Вот борюсь.
  • Anatoly Podgoretsky © (01.07.09 15:47) [9]
    > KoTangens  (01.07.2009 15:18:08)  [8]

    Сканировать все порты от 1 до 255 и пытаться использовать.
    Хоть слово и страшное, но на самом деле сканировать - это просто пытаться открыть и простая проверка, что на другой стороне сидит именно нужное устройство, а то вдруг с модемом попытаешься работать..
  • KoTangens (01.07.09 16:37) [10]
    спасибо, попробую сканировать.
  • Германн © (02.07.09 02:37) [11]

    > KoTangens   (01.07.09 15:18) [8]
    >
    > Это некий мед прибор. Там лазеры стоят, я не сильно в курсе
    > электроники - ее мой муж делал. Я пишу интерфейс - установка
    > времени воздействия, частоты, лог. Сейчас сом надо вручную
    > выбирать из списка дотупных. Но заказчик говорит, что врачам
    > сложно - хотят чтобы включил и "оно само работало". Вот
    > борюсь.

    С мужем?
    :)
  • vastani (02.07.09 10:54) [12]

    > Можно ли как то теми же API выяснить на какой порт оно село?

    Можно. Но не по API... Надо "нюхать" реестр, там все есть... и даже лишнее ;)
    Была проблема у меня с портами на плате PCI у которых номера ставились автоматом как "от фонаря"... да еще с дырками в нумерации...
    Короче надо ПРОмониторить реестр на предмет ДО и ПОСЛЕ появления порта как устройства и сделать анализ глазками, рассмотреть какие веточки и ключики содержат НУЖНЫЙ, правильный номер виртуального COM порта, далее юзать это дело в проге средствами (фунциями) работы с реестром. Я так "научил" программу менять FIFO буферы портов, чего никакой компонент работы с COMами не делает.
    Для этой изыскательской работы (и не только!) хорошо подходит "Ashampoo UnInstaller Platinum". Гуглится по варезным сайтам элементарно. Даже староватая версия сойдет.
    Принцип следующий.
    1. На машину где нет ЕЩЕ ВАШЕГО ДРАЙВЕРА(программы)(!) ставим прогу.
    2. Далее все элементарно и как прога велит "Установить приложение" в данном случае ВАШ ДРАЙВЕР, каким бы он не был, хоть EXE или INF файлом или "добавить оборудование" + CDROM... Главное тут дать проге СОХРАНИТЬ КОНФИГУРАЦИЮ МАШИНЫ ДО установки. Именно это она и делает штатно в самим начале.
    3. Сохраняем лог после установки и убеждаемся, затем что аппаратура работает правильно и на каком "COM n" сидит фактически
    4. Выбираем лог файл в проге и открываем его, затем "Инструменты"-> "Создать инсталляционные файлы"...
    5. Среди файлов будет классический REG файл всего того, ЧТО ПРЕВНЕСЕНО теперь в реестр в том числе по оборудованию и как оно обзывается и какой номер у него и настройки и параметры и буфера и текущая скорость... все там можно найти. Это несложно... как говорил один персонаж известнейшего советского фильма "...для человека с интеллектом" ;)
    Конечно в первую очередь ищем номер порта(имя+параметр в реестре), что проверен в работе и известен фактически.
    6. ЭТО лучше и грамотней чем все 256 портов ТУПО(!) открывать и закрывать... еще с непонятными последствиями и будет ли вообще работать.
    7. Вот еще что. Когда найдено искомое надо привязаться бы на всякий случай к строковому имени драйвера или устройства. Номер то номером, но надо точно знать и открывать именно USBшное хозяйство. Это суперКорректно будет, профессионально, наверняка.
  • Anatoly Podgoretsky © (02.07.09 11:05) [13]
    > vastani  (02.07.2009 10:54:12)  [12]

    Хацкер аднака
  • vastani (03.07.09 15:48) [14]
    Аднака да, приходится :) особенно когда нехоженные тропы....
    Что то вопрошающая KoTangens молчит... то ли непонятно, то ли сканирует и сканирует и сканирует своим медприбором комуЙто ЧёйТо там... ;)
    Короче порылся вот в сорцах своих, собсссно все (самое)нужное находится
    ТИПА ТАКС:

    .....
    .....
     if RegOpenKey(HKEY_LOCAL_MACHINE,PChar('HARDWARE\DEVICEMAP\SERIALCOMM'),HK)=0 then
     begin // попробуем определить сколько фактических портов в этом ключе
       if (RegQueryInfoKey( HK,0,0,0,@I,0,0,@dwTp,@K,0,0,0 ) = 0 ) and (dwTp > 0) then
         begin  // да, определённо там есть какие то параметры...
         Dec( dwTp );   // коррекция для дальнейшего удобства
         Inc( K ); // коррекция для дальнейшего удобства
         for I := 0 to dwTp do
            begin
            dwSz := K;
            SetLength( Val, dwSz );
            RegEnumValue( HK, I, @Val[1], dwSz, 0,0,0,0 );
           Val := RegKeyGetStr( HK, Val );  // имя COM порта
            if StrIsStartingFrom( PChar(Val), PChar('COM')) then
               begin
               // поскольку найден ещё один COM порт, учтём его в общем количестве
               Inc( NumPorts );
               TmpArrPorts[NumPorts] := Str2Int(Copy( Val, 4, 3 ));
               end;
            end;
         RegCloseKey( HK ); // всё просмотрено, закрываем этот ключ реестра
    ............
    ............
    ............
    if RegOpenKey(HKEY_LOCAL_MACHINE,('SYSTEM\CurrentControlSet\Services\serenum\Enum') ,HK) = 0 then
     begin
     // читаем сколько COM портов зарегистрировано в этой ветке реестра
     dwSz := 4;
     RegQueryValueEx( HK, PChar('Count'), 0, @dwTp, @I, @dwSz );
     if I > 0 then
        begin
        Dec( I );
         // циклично переберём все символьные номера портов
         // и вычитаем параметры нового пути для дальнейшего поиска...
        for N := 0 to I do
           begin
           Val := RegKeyGetStr( HK, Int2Str(N) );
           if Val > '' then TmpArrFIFO[N] := 'SYSTEM\CurrentControlSet\Enum\' + Val + '\Device Parameters';
           end;
        RegCloseKey( HK ); // вычитали всё, что смогли найти, закроем этот ключ реестра

    // теперь производим ещё раз сверку строковых имён портов, которые уже имеем,
    // и те, что в новой ветке реестра обнаруживаются.
    ..........
    ...........
    .............

  • Дмитрий (07.07.09 07:56) [15]
    14: Цикл из CreateFile(), WriteFile(), ReadFile(), CloseFile() по-вашему будет долгий ? Если в устройство заложена функция инициализации (запрос в виде команды -> ответ в виде сигнатуры или байта состояния) и если скорость работы устройства приличная (ребята, отвыкайте от 9600 :-) ) - усё будет тип-топ. И никакого хацкерства. Разработчик железа, сопрягаемого с ПК, должен быть прежде всего программистом, а потом уже электронщиком.
    ИМХО.
  • KoTangens (20.08.09 13:49) [16]
    С реестром показалось слишком сложно, сделала циклом. Работает отлично. Вот код. Может кому пригодится:

    var  buffer:string;
    DCB:TDCB;
    ...
    for i:=255 downto 1  do
    begin
       port_name:= 'com'+ inttostr(i);
       hCom:=CreateFile(PChar(port_name), GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
    if hCom<>INVALID_HANDLE_VALUE then
      begin
        SetupComm(hCom,1600,1600);
        GetCommState(hCom,DCB);
         //настроить нужным образом

           with DCB do begin                                BaudRate:=38400;
                       ByteSize:=8;
                       Parity:=1;
                       StopBits:=ONESTOPBIT;
                       end;

               if not SetCommState(hCom, DCB)
                         then  begin
                               showMessage ('Error setting port parameters');
                               CloseHandle(hCom);
                               end
                          else
                           if not PurgeComm(hCom, PURGE_TXCLEAR or PURGE_RXCLEAR)
                            then   begin
                                    showMessage ('Error purging port');
                                    CloseHandle(hCom);
                                   end
                            else
                            begin
                              clearCommError(hCom,Errors,@TheStruct);
                                 if TheStruct.cbInQue>0 then
                                                         begin                 //что-то пришло
                                      SetLength(buffer,TheStruct.cbInQue);
                                      readport;
      ....
                                                             end
                                                               else begin
                                                                  CloseHandle(hCom);
                                                                  showMessage ('no data');
                                                                 end;
                                end;
       end ;   //if hcom
    end;   //for

  • Медвежонок Пятачок © (20.08.09 14:03) [17]
    Работает отлично
    Только до кома номер девять включительно. Потом абзац.
  • KoTangens (20.08.09 16:15) [18]
    А что висит на восьмом?
  • Медвежонок Пятачок © (20.08.09 16:20) [19]
    ничего не висит. речь про десятый и выше.

    To specify a COM port number greater than 9, use the following syntax: "\\.\COM10". This syntax works for all port numbers and hardware that allows COM port numbers to be specified.
 
Конференция "WinAPI" » Как определить номер COM порта? [D7, WinXP]
Есть новые Нет новых   [118241   +25][b:0][p:0.005]