Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
| | | | |
У меня вообще команда не доходит чтоли??? 04.11.03 00:14 Число просмотров: 1515
Автор: Killer{R} <Dmitry> Статус: Elderman
|
> WriteFile(hCOM,"ATDT111111\xD",13,0,0); "ATDT111111\xD"
-это 11 символов \xD это один символ с кодом 13 - переволд строки. Для модема означает конец команды. Надо так
WriteFile(hCOM,"ATDT111111\xD",11,0,0);
|
<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
|
|
|
|