Легенда:
   новое сообщение
    закрытая нитка
    новое сообщение
    в закрытой нитке
    старое сообщение
         
		 | 
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
 - Новичкам также крайне полезно ознакомиться с данным документом.
   
  |   |   |   | 
А что за компанент?  03.11.03 23:30  Число просмотров: 1680
 Автор: CrazyPitbull Статус: Незарегистрированный пользователь
 | 
 
| 
Слушай я поискал этот компанент среди стандартных и не нашёл... Он стандартный или его качать надо?
 | 
 
| 
<programming>
 |  
 
[C++] Запись АТ команды в КОМ порт модема...  01.11.03 01:27  
 Автор: CrazyPitbull Статус: Незарегистрированный пользователь
 | 
 
  На Ком порте висит модем, нужно записать в него Ат команду и получить отклик от него, точнее результат выполнения этой команды,. Послать команту просто:
 HANDLE hCOM=CreateFile("COM1",GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
 
  if (hCOM!=INVALID_HANDLE_VALUE){
         ShowMessage("COM1  is open OK!");
 
         DWORD nb;
         OVERLAPPED ov;
 //записываем команду
         WriteFile(hCOM,"AT+CPBR=1",9,&nb,&ov);
 //читаем результатв ch - хотя я незнаю здесь ли нужно это делать
         char ch[10];
         ReadFile(hCOM,ch,10,&nb,0);
         ShowMessage(ch);
         CloseHandle(hCOM);
  }else
         ShowMessage("Error Open " + edPort->Text);
 Прошу поправить меня если я не прав, команды посылаются, а в ch пусто, что-то я делаю не так, а что??? Большое спасибо...
 | 
 
 
  | 
[C++] MSDN  02.11.03 14:49  
 Автор: amirul <Serge> Статус: The Elderman
 | 
 
> hCOM=CreateFile("COM1",GENERIC_WRITE,0,NULL,OPEN_EXISTING,F > ILE_ATTRIBUTE_NORMAL,NULL); Для использования OVERLAPPED файл надо открывать с FILE_FLAG_OVERLAPPED.
 
 
 >  if (hCOM!=INVALID_HANDLE_VALUE){ > 	ShowMessage("COM1  is open OK!"); >  > 	DWORD nb; > 	OVERLAPPED ov; > //записываем команду > 	WriteFile(hCOM,"AT+CPBR=1",9,&nb,&ov); А зачем вообще тут overlapped?
 
 > Прошу поправить меня если я не прав, команды посылаются, а > в ch пусто, что-то я делаю не так, а что??? Большое > спасибо... В общем смотри в сторону SetCommMask/WaitCommEvent в частности и Platform SDK: Communication Functions вообще. Кроме того, советую заглянуть в пример работы с ком-портом все в том же MSDN-е. Алгоритм примерно следующий:
 
 Записывается команда, ставится маска на EV_RXCHAR, ставится ожидание событий из порта, когда событие пришло - можно читать.
 | 
 
 
  |   | 
[C++] MSDN  03.11.03 00:43  
 Автор: CrazyPitbull Статус: Незарегистрированный пользователь
 | 
 
Ну смотри я сделал следующим образом, но как была строка пустой так и осталась... 
 HANDLE hCOM=CreateFile("COM1",GENERIC_WRITE | GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
 
  if(hCOM!=INVALID_HANDLE_VALUE){
         ShowMessage("COM1 is open OK!");
 
         DWORD nb = 0;
 
         WriteFile(hCOM,"ATI2",edPort->Text.Length(),&nb,0);
         if(WaitForSingleObject(hCOM,100) == WAIT_TIMEOUT){
                 ShowMessage("Время кончилось...");
                 return;
         }
         char ch[5];
         ch[0] = '\0';
         ReadFile(hCOM,ch,5,&nb,0);
 
         ShowMessage(ch);
         CloseHandle(hCOM);
  }else
         ShowMessage("Error Open COM1");
 Может я опять наглючил чтонибудь, хотя я непонял какого сообщания нужно ждать я просто ставлю время на WaitForSingleObject 100 мл сек если за это время объект не ответил, то выходим, а если всё нормально, то читам данные.
 ЭТО правильно?
 | 
 
 
  |   |   | 
[C++] SetCommMask/WaitCommEvent  03.11.03 11:09  
 Автор: amirul <Serge> Статус: The Elderman
 | 
 
> Ну смотри я сделал следующим образом, но как была строка > пустой так и осталась...  > HANDLE hCOM=CreateFile("COM1",GENERIC_WRITE | > GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL > ); Странный ты, ей богу. Теперь указал FILE_FLAG_OVERLAPPED, но не используешь его :-))
 
 > WriteFile(hCOM,"ATI2",edPort->Text.Length(),&nb,0); > 	if(WaitForSingleObject(hCOM,100) == WAIT_TIMEOUT){ > 		ShowMessage("Время кончилось..."); > 		return; > 	} Ладно. Не хочешь сам смотреть MSDN, покажу. Вот в точности пример оттуда:
 
 
HANDLE hCom;
OVERLAPPED o;
BOOL fSuccess;
DWORD dwEvtMask;
hCom = CreateFile( "COM1",
    GENERIC_READ | GENERIC_WRITE,
    0,    // exclusive access 
    NULL, // no security attributes 
    OPEN_EXISTING,
    FILE_FLAG_OVERLAPPED,
    NULL
    );
if (hCom == INVALID_HANDLE_VALUE) 
{
    // Handle the error. 
}
// Set the event mask. 
fSuccess = SetCommMask(hCom, EV_CTS | EV_DSR);
if (!fSuccess) 
{
    // Handle the error. 
}
// Create an event object for use in WaitCommEvent. 
o.hEvent = CreateEvent(
    NULL,   // no security attributes 
    FALSE,  // auto reset event 
    FALSE,  // not signaled 
    NULL    // no name 
    );
assert(o.hEvent);
if (WaitCommEvent(hCom, &dwEvtMask, &o)) 
{
    if (dwEvtMask & EV_DSR) 
    {
         // To do.
    }
    if (dwEvtMask & EV_CTS) 
    {
         // To do. 
    }
}
 ---
 
 Единственное, что тебе надо исправить это тип события (EV_RXCHAR в твоем случае). Кроме того, гораздо правильнее было бы поставить SetCommTimeouts и сделать ReadFile (а не ждать хендл, при работе с COM портом это вообще практически никогда не делается)
 
 > Может я опять наглючил чтонибудь, хотя я непонял какого > сообщания нужно ждать я просто ставлю время на > WaitForSingleObject 100 мл сек если за это время объект не > ответил, то выходим, а если всё нормально, то читам данные. > ЭТО правильно? Нет :-)))
 Почитай MSDN все таки :-)
 | 
 
 
  |   |   |   | 
У меня вообще команда не доходит чтоли???  03.11.03 23:36  
 Автор: CrazyPitbull Статус: Незарегистрированный пользователь
 | 
 
Странно, а может быть и нет... Я посылаю команду набрать номер, а мне модем фигу показывает, что не так???
 
 HANDLE hCOM=CreateFile("COM1",GENERIC_WRITE | GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
 
  if(hCOM!=INVALID_HANDLE_VALUE){
         DCB dcb;
         COMMTIMEOUTS CommTimeouts;
 
          //Получаем настройки порта
 	GetCommState(hCOM, &dcb);
 	
 	//Меняем часть настроек на свои
 	dcb.BaudRate = 57600;	//Скорости в бодах
 	dcb.ByteSize = 8; 	//Байты информации
 	dcb.Parity = NOPARITY;	//Четность
 	dcb.StopBits = ONESTOPBIT; //Кол-во стоп. битов
 
 	//Устанавливаем новые настройки
 	SetCommState(hCOM, &dcb);
 
 	/* Установка таймаутов. 
 	Служит, чтобы программа не висла
 	в ожидании ответа от модема */
 	GetCommTimeouts(hCOM,&CommTimeouts);
 
 	CommTimeouts.ReadIntervalTimeout = 50;
 	CommTimeouts.ReadTotalTimeoutMultiplier = 1;
 	CommTimeouts.ReadTotalTimeoutConstant = 50;
 	CommTimeouts.WriteTotalTimeoutMultiplier = 1;
 	CommTimeouts.WriteTotalTimeoutConstant = 50;
 
 	SetCommTimeouts(hCOM,&CommTimeouts);
 
         FlushFileBuffers(hCOM);
  
         WriteFile(hCOM,"ATDT111111\xD",13,0,0);
 
 Вроде всё, больше ничего не надо, а модем номар не набирает... Если есть где листинг посмотреть дайте пожалуйста, MSDN гонял, так и не нашёл...
 | 
 
 
  |   |   |   |   | 
А ты PortMonitor-ом от sysinternals.com глянь  04.11.03 11:04  
 Автор: amirul <Serge> Статус: The Elderman
 | 
 
> 	CommTimeouts.ReadIntervalTimeout = 50; > 	CommTimeouts.ReadTotalTimeoutMultiplier = 1; > 	CommTimeouts.ReadTotalTimeoutConstant = 50; > 	CommTimeouts.WriteTotalTimeoutMultiplier = 1; > 	CommTimeouts.WriteTotalTimeoutConstant = 50; >  > 	SetCommTimeouts(hCOM,&CommTimeouts); По моему таймауты маловаты
 
 А вообще глянь. Заодно и увидишь с каким статусом слетает IRP_MR_WRITE
 | 
 
 
  |   |   |   |   |   | 
Е где можно взять примеры терминалчиков?  04.11.03 14:24  
 Автор: CrazyPitbull Статус: Незарегистрированный пользователь
 | 
 
| 
 Может можно где посмотреть примеры терминала... Я посмотрел одной программкой, команды посылаются и выполняются. Но мне не сделать так, чтобы можно было послать программку (код уже показывал). Может где-нибудь можно посмотреть как это делается?
 | 
 
 
  |   |   |   |   |   |   | 
В MSDN-е полно примеров работы с портом  04.11.03 15:09  
 Автор: amirul <Serge> Статус: The Elderman
 | 
 
>  Может можно где посмотреть примеры терминала... Я > посмотрел одной программкой, команды посылаются и > выполняются. Но мне не сделать так, чтобы можно было > послать программку (код уже показывал). Может где-нибудь > можно посмотреть как это делается? Если не нравится MSDN, то наверное лучше воспользоваться билдеровской компонентой.
 
 Хотя общая идея работы с com-портом: практически все что делается, делается после ожидания событий. В принципе хорошим вариантом будет даже запустить поток, который будет постоянно ждать event-ы, а потом запускать колбяки на каждый из них.
 | 
 
 
  |   |   |   |   |   |   |   | 
И всётаки почему мой код на работает?  04.11.03 16:52  
 Автор: CrazyPitbull Статус: Незарегистрированный пользователь
 | 
 
| 
 | 
 
 
  |   |   |   |   |   |   |   |   | 
А ты выложи сюда логи PortMon-а  05.11.03 11:33  
 Автор: amirul <Serge> Статус: The Elderman
 | 
 
| 
Тогда и будем посмотреть. А так слишком много возможностей. Скорее всего что то с таймаутами
 | 
 
 
  |   |   |   |   | 
У меня вообще команда не доходит чтоли???  04.11.03 00:14  
 Автор: Killer{R} <Dmitry> Статус: Elderman
 | 
 
> 	WriteFile(hCOM,"ATDT111111\xD",13,0,0); "ATDT111111\xD"
 -это 11 символов \xD это один символ с кодом 13 - переволд строки. Для модема означает конец команды. Надо так
 WriteFile(hCOM,"ATDT111111\xD",11,0,0);
 
 | 
 
 
  |   |   |   |   |   | 
Может это смешно, но всёравно не работает...  04.11.03 01:17  
 Автор: CrazyPitbull Статус: Незарегистрированный пользователь
 | 
 
| 
 | 
 
 
  |   |   | 
После AT команд надо слать \xD  03.11.03 01:18  
 Автор: Killer{R} <Dmitry> Статус: Elderman Отредактировано 03.11.03 01:30  Количество правок: 2
 | 
 
WriteFile(hCOM,"ATI2",edPort->Text.Length(),&nb,0); 
 а надо
 WriteFile(hCOM,"ATI2\xD",5,&nb,0); 
 Вообще имхо если ты пишешь втебе  билдере то есть хороший компонент обертка вокруг ком порта - ComDrv32. Халявный и с сырцами. Недостаток в том что не умеет открывать порты больше 4го но это легко фиксится благодаря сырцам. Да и 100мсек имхо маловато. Например ATZ может выполняться до пары секунд на некоторых модемах.
 | 
 
 
  |   |   |   | 
А что за компанент?  03.11.03 23:30  
 Автор: CrazyPitbull Статус: Незарегистрированный пользователь
 | 
 
| 
Слушай я поискал этот компанент среди стандартных и не нашёл... Он стандартный или его качать надо?
 | 
 
 
  |   |   |   |   | 
Нестандартный.  04.11.03 00:12  
 Автор: Killer{R} <Dmitry> Статус: Elderman Отредактировано 04.11.03 00:54  Количество правок: 1
 | 
 
Линка внизу. Вот кстати мот тебе поможет... тут кусок одной моей проги - инициализация модема через CreateFile и потом инициализация этого ComDrv32 для работы если с модемом все ок.
 void __fastcall TForm1::reinit(int index)
 {
 flags[index]|=1;
 if(comms[index]->Connected())
 {
 sendcmd(index,postinit,0,300);
 comms[index]->Disconnect();
 }
 //else
 {
      AnsiString cp="\\\\.\\COM"+(AnsiString)(index+1);
      HANDLE f=CreateFile(cp.c_str(),GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
      if(f==INVALID_HANDLE_VALUE)
      {
      ListView1->Items->Item[index]->Checked=false;
      return;
      }
      CloseHandle(f);
      comms[index]->Connect();
      comms[index]->Disconnect();
 f=CreateFile(cp.c_str(),GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
 
 DWORD dw=0;
      COMMTIMEOUTS cmto,cmt;
      int er=GetCommTimeouts(f,&cmto);cmt=cmto;
      cmt.WriteTotalTimeoutMultiplier=10;
      cmt.WriteTotalTimeoutConstant=100;
      char xxx[32];dw=0;
      SetCommTimeouts(f,&cmt);
      int n=0,xcon=1;
      WriteFile(f,"\x0D",1,&dw,0);
      Sleep(200);
      ReadFile(f,xxx,32,&dw,0);
      do
      {
      DWORD tmx=GetTickCount()+3000;
      ZeroMemory(xxx,32);
      WriteFile(f,"atz\x0D",4,&dw,0);
      int x=0;
      do
      {
      ReadFile(f,xxx+x,32,&dw,0);
      }while((!strstr(xxx,"ERROR\x0D"))&&(!strstr(xxx,"OK\x0D"))&&(GetTickCount()<tmx));
      n++;
      }while((!strstr(xxx,"OK\x0D"))&&(n<2));
      if(!strstr(xxx,"OK\x0D"))xcon=0;
      else
      {
      n=0;
      do
      {
      ZeroMemory(xxx,32);
      DWORD tmx=GetTickCount()+3000;
      WriteFile(f,"ate0\x0D",5,&dw,0);
      do
      {
      ReadFile(f,xxx,32,&dw,0);
      }while((!strstr(xxx,"ERROR\x0D"))&&(!strstr(xxx,"OK\x0D"))&&(GetTickCount()<tmx));
      n++;
      }while((!strstr(xxx,"OK\x0D"))&&(n<4));
      };
      SetCommTimeouts(f,&cmto);
      CloseHandle(f);
      if(!xcon)
      {
      ListView1->Items->Item[index]->Checked=false;
 flags[index]&=~1;
      return;
      }
 dtmfs[index]=rets[index]="";
 rbacks[index]=0;
 switch(hwhandshake)
 {
 case 1:comms[index]->ComPortHwHandshaking=hhRTSCTS;break;
 default:comms[index]->ComPortHwHandshaking=hhNONE;
 }
 switch(swhandshake)
 {
 case 1:comms[index]->ComPortSwHandshaking=shXONXOFF;break;
 default:comms[index]->ComPortSwHandshaking=shNONE;
 }
 switch(portspeed)
 {
 case 0 :comms[index]->ComPortSpeed=br110;break;
 case 1 :comms[index]->ComPortSpeed=br300;break;
 case 2 :comms[index]->ComPortSpeed=br1200;break;
 case 3 :comms[index]->ComPortSpeed=br2400;break;
 case 4 :comms[index]->ComPortSpeed=br4800;break;
 case 5 :comms[index]->ComPortSpeed=br9600;break;
 case 6 :comms[index]->ComPortSpeed=br14400;break;
 case 7 :comms[index]->ComPortSpeed=br19200;break;
 case 8 :comms[index]->ComPortSpeed=br38400;break;
 case 9 :comms[index]->ComPortSpeed=br56000;break;
 case 10:comms[index]->ComPortSpeed=br57600;break;
 case 11:comms[index]->ComPortSpeed=br115200;break;
 default:comms[index]->ComPortSpeed=br115200;
 }
 
 comms[index]->Connect();
 sendcmd(index,preinit,0,100);
 }
 flags[index]&=~1;
 }
  http://www.delphi32.com/vcl/2045/
 | 
 
 
  | 
[C++] WriteFile и ReadFile асинхронные, используй WaitForSingleObject!  01.11.03 12:54  
 Автор: Zef <Alloo Zef> Статус: Elderman
 | 
 
| 
Иначе, пытаешься прочитать ответ раньше, чем уйдет запрос.
 | 
 
 
  |   | 
[C++] Это, кстати, зависит от флагов, указанных CreateFile-у  03.11.03 11:09  
 Автор: amirul <Serge> Статус: The Elderman
 | 
 
| 
 | 
 
 
  
 
 | 
 |