Страница 1 из 3

Автоконнект с контроллерным устройством по COM порту

Добавлено: Сб мар 17, 2012 23:35:04
shads
Кому интересно?
Часто бывает неудобно вводить номер COM порта для связи с устройством, а если используеш адаптер USB-COM, то при переключении адаптера в другой USB разъем, номер виртуального COM порта тоже поменяется, в общем неудобства сплошные.
Вот я и оформил автоконнект WIN приложения с контроллерным устройством по COM порту на примере простенького терморегистратора.
Исходники можно скачать тут: http://asis-kbr.ru/forum/viewtopic.php?f=9&t=115
В исходнике для CPP BUILDER6 много комментов, легко можно подправить под свои нужды, для любой схемки.
connecting.jpg
(124.33 КБ) 425 скачиваний
автоматически определяется номер COM порта устройства
прога.jpg
(26.08 КБ) 437 скачиваний

Re: Автоконнект с контроллерным устройством по COM порту

Добавлено: Вс мар 18, 2012 15:17:11
koyodza
А можно в двух словах, в чём суть работы алгоритма? Открываются доступные порты и туда отправляется запрос? Или как-то иначе?

Re: Автоконнект с контроллерным устройством по COM порту

Добавлено: Вс мар 18, 2012 16:29:49
Flasher
Именно так. :)
В этом отношении мне FTDI нравится.

Re: Автоконнект с контроллерным устройством по COM порту

Добавлено: Вс мар 18, 2012 17:05:32
shads
koyodza писал(а):А можно в двух словах, в чём суть работы алгоритма? Открываются доступные порты и туда отправляется запрос? Или как-то иначе?
Открываются по очереди порты от 1 до 255, в те которые доступны и открываются, посылается запрос (ну типа пороля, просто символьная строка с названием устройства), если ответа в течение определенного времени нет (ну предположим 0,1 сек), идем дальше, а если ответ поступил, порт остается открытым и с ним работаем дальше.

Re: Автоконнект с контроллерным устройством по COM порту

Добавлено: Вс мар 18, 2012 17:49:09
Flasher
В реестре можно получить список доступных com портов в системе. И их потом дергать. А так- напоминает колхоз...

Re: Автоконнект с контроллерным устройством по COM порту

Добавлено: Вс мар 18, 2012 18:04:33
Мурик
USB девайсы намного удобнее.
Можно конектиться по уникальным идентификаторам PID, VID и VN без перебора всех портов.
И работать с USB не сложнее чем с COM портом.

Re: Автоконнект с контроллерным устройством по COM порту

Добавлено: Вс мар 18, 2012 20:54:58
YS
Соломоново решение - FTDI. Можно искать по VID/PID/настраиваемому идентификатору, и в использовании - COM.

Re: Автоконнект с контроллерным устройством по COM порту

Добавлено: Вс мар 18, 2012 22:10:37
shads
Flasher писал(а):В реестре можно получить список доступных com портов в системе. И их потом дергать. А так- напоминает колхоз...
Согласен. Но это моя ПЕРВАЯ работа по программированию в С++ Builder (вообще с С дела раньше не имел, вот приспичело и что-то сообразил), т.е. я просто не знаю еще как работать с реестром. ПОМОГИТЕ! (ну а так вообще что задумал - работает).
Мурик писал(а):USB девайсы намного удобнее.
Можно конектиться по уникальным идентификаторам PID, VID и VN без перебора всех портов.
И работать с USB не сложнее чем с COM портом.
А что за USB девайсы вы имеете ввиду?
Вот например у меня устройство на тиньке, как я могу работать через USB?
В моем случае, я использую USB-COM переходник, вроде все понятно - тинька работает по программному UART-у, переходник делает в винде виртуальный COM порт, и мы с ним работаем.
А вы как предлагаете организовать работу через USB?

Re: Автоконнект с контроллерным устройством по COM порту

Добавлено: Вс мар 18, 2012 22:24:11
shads
YS писал(а):Соломоново решение - FTDI. Можно искать по VID/PID/настраиваемому идентификатору, и в использовании - COM.
А можно на какойнить материальчик указать, где это описано?

Как я понял FTDI (по сути ту же функцию выполняет что и USB-COM переходник?), имеет какие то зашитые с завода идентификаторы?
Но даже если я в программе конфигурации, по идентификаторам определю, что на USB висит FTDI, мне же все равно придется опросить мое устройство? Оно это или нет? Я правильно понимаю?

Re: Автоконнект с контроллерным устройством по COM порту

Добавлено: Вс мар 18, 2012 22:39:03
Мурик
shads писал(а):А что за USB девайсы вы имеете ввиду?
Из несложных создании в работе с ними, например USB HID. Недавно обсуждалось, посмотрите. http://www.radiokot.ru/forum/viewtopic.php?f=24&t=66562
shads писал(а):Вот например у меня устройство на тиньке
Смотря какое.
Вполне возможно что на нем можно поднять программный USB.
Вот к примеру USB девайс на тиньке.

Re: Автоконнект с контроллерным устройством по COM порту

Добавлено: Вс мар 18, 2012 23:06:16
YS
А можно на какойнить материальчик указать, где это описано?
Read This Fine Manual :)

FT_OpenEx() поддерживает поиск по строковому идентификатору.
ту же функцию выполняет что и USB-COM переходник?
Это и есть одна из микросхем переходников USB->COM.
имеет какие то зашитые с завода идентификаторы?
Которые можно поменять. И по ним опознать устройство. Тупо по названию. Назовите его, например, MyLed, и пишите

Код: Выделить всё

...

ftStatus = FT_OpenEx("MyLed",FT_OPEN_BY_DESCRIPTION,&ftHandle1); 

if (ftStatus == FT_OK)
{ 
  // success - device with device description "MyLed" is open 
} 
else 
{ 
  // failure 
}

...

Re: Автоконнект с контроллерным устройством по COM порту

Добавлено: Вс мар 18, 2012 23:22:08
Flasher
//Получаем из реестра список существующих в системе последовательных портов и выводим в Combobox
TRegistry* Reg = new TRegistry(KEY_READ);
TStringList *List = new TStringList;
unsigned int i;

Reg->RootKey = HKEY_LOCAL_MACHINE;
Reg->OpenKey("HARDWARE\\DEVICEMAP\\SERIALCOMM", false);
Reg->GetValueNames(List);
for (i = 0; i< List->Count; i++)
{
AnsiString w = Reg->ReadString(List->Strings).SetLength(3);
if (w.SetLength(3) == "COM")
Form4->ComboBox1->Items->Add(Reg->ReadString(List->Strings));
}
List->Free();
Reg->CloseKey();
Reg->Free();
Form4->ComboBox1->ItemIndex = 0;

Re: Автоконнект с контроллерным устройством по COM порту

Добавлено: Вс мар 18, 2012 23:31:24
shads
УУУУУУууууууу.......!
Всем ОГРОМНОЕ спасибо.
Теперь надо бы время найти, чтобы со всем этим разобраться!
Если так быстро откликаться будут, то думаю дело пойдет!

Re: Автоконнект с контроллерным устройством по COM порту

Добавлено: Пн мар 19, 2012 00:08:14
Flasher
Кстати, а искать девайс с ком-портом подключенный напрямую или через любой гипотетический переходник можно только дерганьем доступных портов.

Re: Автоконнект с контроллерным устройством по COM порту

Добавлено: Пн мар 19, 2012 13:32:05
YS
Flasher, если подключить интересующий девайс к конкретному переходнику на FT232 с заданным идентификатором, то можно искать через FTDI API.

Re: Автоконнект с контроллерным устройством по COM порту

Добавлено: Пн мар 19, 2012 20:10:12
Flasher
YS, еще раз пересмотрите внимательнее мои сообщения.

Re: Автоконнект с контроллерным устройством по COM порту

Добавлено: Вт мар 20, 2012 17:30:10
YS
Пересмотрел. Не совсем понял, но на вский случай признаю, что неправ. :)

Re: Автоконнект с контроллерным устройством по COM порту

Добавлено: Вт мар 20, 2012 22:11:59
Flasher
Спасибо, Вашу вежливость оценил. :)

Re: Автоконнект с контроллерным устройством по COM порту

Добавлено: Ср мар 21, 2012 00:14:05
DX168B
А нафига за портами лезть в реестр?
Можно и так:

Код: Выделить всё

#define MAX_WIN_PORT 255

struct Port
{
	unsigned char Id;	
	bool Availbl;
};

struct PortInfo
{
	Port p[MAX_WIN_PORT];
	unsigned char koll;
};
Метод класса:

Код: Выделить всё

extern "C" __declspec (dllexport) void DXCOM::GetPortsInfo(PortInfo* pi)
{
  DWORD  Ports_MemSize = 0;
  DWORD  Ports_Count   = 0;
  BYTE*  lpPorts       = NULL;
  //Getting Ports_MemSize value...
  EnumPorts(NULL,
            1,
            lpPorts,
            0,
            &Ports_MemSize,
            &Ports_Count);
  //Getting lpPorts...
  lpPorts = new BYTE[Ports_MemSize];
  EnumPorts(NULL,
            1,
            lpPorts,
            Ports_MemSize,
            &Ports_MemSize,
            &Ports_Count);
  //Forming List Of Ports...
  DWORD dw;
  TCHAR str[8];
  char temp[4];
  int port = -1;
  PORT_INFO_1 *pPortInfo;
  pPortInfo = (PORT_INFO_1 *)lpPorts;
  int counter = 0;
  bool av = false;
  for (dw = 0; dw < Ports_Count; dw++)
  {
    lstrcpyn(str, pPortInfo->pName, 4);
    str[4] = 0;
    if (lstrcmpi(str, "com") == 0)
    {    
		//printf("%s\n", pPortInfo->pName);	
		memset(temp, '\0', sizeof(temp));
		temp[0] = pPortInfo->pName[3];
		if(pPortInfo->pName[4]!= ':' && pPortInfo->pName[4]!= '\0')
			temp[1] = pPortInfo->pName[4];
		if(pPortInfo->pName[5]!= ':' && pPortInfo->pName[5]!= '\0')
			temp[2] = pPortInfo->pName[5];		
		port = atoi(temp);
		//printf("%d\n", port);
		char COM_string[20];
		sprintf(COM_string,"\\\\.\\COM%d", port);
		HANDLE h = CreateFile(COM_string, GENERIC_READ|GENERIC_WRITE, 0, NULL,						
		OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL);
		if(h == INVALID_HANDLE_VALUE)
		{				
			//return false;
			av = false;
		}
		else
		{
			av = true;
			CloseHandle(h);
		}
		pi->p[counter].Id      = port;
		pi->p[counter].Availbl = av;
		counter++;
    }
    pPortInfo++;
  }
  pi->koll = counter;
  delete [] lpPorts;
}
И пример использования в консольном приложении:

Код: Выделить всё

PortInfo xd;

	display(" Поиск имеющихся COM портов в системе. Ждите...");
	dx.GetPortsInfo(&xd);

	system("cls");

	printf(" COM ports available: %d\n\n", xd.koll);

	for(int i = 0; i < xd.koll; i++)
	{
		if(xd.p[i].Availbl){printf(" COM%d - free\n", xd.p[i].Id);}
		else{printf(" COM%d - inaccessible\n", xd.p[i].Id);}
	}

Re: Автоконнект с контроллерным устройством по COM порту

Добавлено: Ср мар 21, 2012 01:04:21
Flasher
Понятие "говноалгоритм" существует?