Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.07.2013, 18:37   #1
220Volt
Форумчанин
 
Регистрация: 14.12.2012
Сообщений: 668
По умолчанию Работа с USB модемом через COM порт

Здравствуйте!
Есть у меня USB модем и я хочу управлять им из программы (отправлять СМС). В сети видел товарищей, которые делали что-то подобное. Третий день пытаюсь, но ничего не получается. Модем эмулирует COM порт, т.е. задача отсылать AT команды через него.
Скачал программу HyperTerminal, через него без проблем отсылаются команды и возвращаются ответы, успешна и отправка СМС. В общем, может у кого есть какой опыт, помогите пожалуйста понять что не так делаю.
В коде ниже я отсылаю команду модему и расчитываю получить ответ от него, но намертво зависаю в WaitCommEvent()
Код:
#include <Windows.h>
#include <string>

int main () 
{
	HANDLE port = CreateFileA("COM7", GENERIC_READ | GENERIC_WRITE, 0, 
						      NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if(port == INVALID_HANDLE_VALUE)				{ MessageBoxA(NULL, "Порт не открыт", "", MB_OK); return 0; }
	if( ! SetCommMask(port, EV_RXCHAR | EV_ERR) )   { MessageBoxA(NULL, "маска не установлена", "", MB_OK); return 0; }
	
	DCB dcb;
	if( ! GetCommState(port, &dcb) )   { MessageBoxA(NULL, "GCS error", "", MB_OK);; return 0; }
	dcb.DCBlength = sizeof(DCB);
	dcb.BaudRate = CBR_9600;
	dcb.fBinary = TRUE;
	dcb.fParity = FALSE;
	dcb.fOutxCtsFlow = FALSE;				// hardware flow control //
	dcb.fOutxDsrFlow = FALSE;				// hardware flow control //
	dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;	// hardware flow control
	dcb.fDsrSensitivity = FALSE;				// software flow control
	//dcb.fTXContinueOnXoff = ;				// software flow control
	dcb.fOutX = FALSE;					// software flow control  //
	dcb.fInX = FALSE;					// software flow control
	//dcb.fErrorChar = ;
	dcb.fNull = TRUE;
	dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;	// hardware flow control
	dcb.fAbortOnError = FALSE;  //
	//dcb.fDummy2 = ;
	dcb.wReserved = 0;
	//dcb.XonLim = ;						// software flow control
	//dcb.XoffLim = ;						// software flow control
	dcb.ByteSize = 8;
	dcb.Parity = NOPARITY;
	dcb.StopBits = ONESTOPBIT;
	//dcb.XonChar = ;					// software flow control
	//dcb.XoffChar = ;					// software flow control
	//dcb.ErrorChar = ;
	//dcb.EofChar = ;
	//dcb.EvtChar = ;
	//dcb.wReserved1 = ;
	if( ! SetCommState(port, &dcb) )   { MessageBoxA(NULL, "SCS error", "", MB_OK); return 0; }

	COMMTIMEOUTS timeouts;
	timeouts.ReadIntervalTimeout = MAXDWORD; 
	timeouts.ReadTotalTimeoutMultiplier = 0;
	timeouts.ReadTotalTimeoutConstant = 0;
	timeouts.WriteTotalTimeoutMultiplier = 0;
	timeouts.WriteTotalTimeoutConstant = 0;
	if (!SetCommTimeouts(port, &timeouts))	{ MessageBoxA(NULL, "Не удалось задать timout", "", MB_OK); return 0; }

	DWORD error;
	COMSTAT status;
	if( ! ClearCommError(port, &error, &status) )	{ MessageBoxA(NULL, "CME error", "", MB_OK); return 0; }

#define my_LEN(str)		strlen(str)
	DWORD written;
	char str[50] = "AT+CFUN=1\n";
	WriteFile(port, str, my_LEN(str), &written, NULL);
	if( ! WriteFile(port, str, my_LEN(str),		// Отсылаем AT команду модему
				  &written, NULL) )
		{ MessageBoxA(NULL, "WriteFile error", "", MB_OK); return 0; }
	

	DWORD event;
	if( WaitCommEvent(port, &event, NULL) )   // Ждем события порта и не получаем его. Программа виснет тут.
	{
		switch(event)
		{
		case EV_RXCHAR:
			break;
		case EV_ERR:
			break;
		default:
			MessageBoxA(NULL, "WCE error default", "", MB_OK); return 0;
		}
	}
	else   { MessageBoxA(NULL, "WCE error", "", MB_OK); return 0; }

	cout<<"ok\n";	// До этой точки мы не доходим
	int b; cin>>b;
	return 0;
}
220Volt вне форума Ответить с цитированием
Старый 09.07.2013, 19:02   #2
220Volt
Форумчанин
 
Регистрация: 14.12.2012
Сообщений: 668
По умолчанию

Наверное стоит уточнить - модем имеет сим-карту.
220Volt вне форума Ответить с цитированием
Старый 09.07.2013, 19:33   #3
raxp
Старожил
 
Регистрация: 29.09.2009
Сообщений: 9,713
По умолчанию

"AT+CFUN=1" - зачем вы вообще ее используете в данном случае? Она предназначена для включения отдельных моделей телефонов, иногда для перезапуска модемов (причем процесс длительный). Для работы с SMS сообщениями она не используется.

Рекомендую ознакомиться с 'AT Commands Interface Guide. - Wavecom', очень все доходчиво расписано.
Разработки и научно-технические публикации :: Видеоблог :: Твиттер
Radar systems engineer & Software developer of industrial automation
raxp вне форума Ответить с цитированием
Старый 09.07.2013, 19:43   #4
220Volt
Форумчанин
 
Регистрация: 14.12.2012
Сообщений: 668
По умолчанию

Спасибо за ссылку, обязательно ознакомлюсь, если получится законектится.

И еще вопрос: настройки в диспетчере устройство это что? Был случай – запросил настройки порта через GetCommState() и они отличались от тех, которые показываются в диспетчере устройств.

Почему HyperTerminal нормально работает с модемом при разных скоростях, например 1200 и 9600 бод? COM очень требователен к синхронности приемника и источника !?
220Volt вне форума Ответить с цитированием
Старый 09.07.2013, 19:46   #5
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Я бы начал с того, что сделал бы ReadIntervalTimeout = 0
waleri вне форума Ответить с цитированием
Старый 09.07.2013, 19:57   #6
220Volt
Форумчанин
 
Регистрация: 14.12.2012
Сообщений: 668
По умолчанию

Вроде все по msdn'у http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx
COMMTIMEOUTS заполнена так для возрата ReadFile() немедленно, даже если не прочитано ничего (в синхронном режиме).
220Volt вне форума Ответить с цитированием
Старый 09.07.2013, 20:09   #7
raxp
Старожил
 
Регистрация: 29.09.2009
Сообщений: 9,713
По умолчанию

Цитата:
И еще вопрос: настройки в диспетчере устройство это что? Был случай – запросил настройки порта через GetCommState() и они отличались от тех, которые показываются в диспетчере устройств.
при программной (вашей) конфигурации они не влияют.

Цитата:
Почему HyperTerminal нормально работает с модемом при разных скоростях, например 1200 и 9600 бод?
значит поддерживает и 1200. А 9600 по-дефолту у многих.

Цитата:
Спасибо за ссылку, обязательно ознакомлюсь, если получится законектится.
что значит получится. Гипертерминалом ведь идет, идет. Пошлите ему "AT?" программно и посмотрите ответ. И вы не ответили зачем CFUN влепили.
Разработки и научно-технические публикации :: Видеоблог :: Твиттер
Radar systems engineer & Software developer of industrial automation
raxp вне форума Ответить с цитированием
Старый 09.07.2013, 20:38   #8
220Volt
Форумчанин
 
Регистрация: 14.12.2012
Сообщений: 668
По умолчанию

Цитата:
Сообщение от raxp Посмотреть сообщение
что значит получится. Гипертерминалом ведь идет, идет. Пошлите ему "AT?" программно и посмотрите ответ. И вы не ответили зачем CFUN влепили.
Эту команду использую по неопытности. Видел у кого-то отправку СМС АТ командами, скопировал и вставил.
Код:
...
#define my_LEN(str)		strlen(str)
	DWORD written;
	char str[50] = "at\n";
	WriteFile(port, str, my_LEN(str), &written, NULL);
	if( ! WriteFile(port, str, my_LEN(str),		// Отсылаем AT команду модему
				  &written, NULL) )
		{ MessageBoxA(NULL, "WriteFile error", "", MB_OK); return 0; }
	

	DWORD event;
	if( WaitCommEvent(port, &event, NULL) )   // Ждем события порта и не получаем его. Программа виснет тут.
	{
		switch(event)
		{
		case EV_RXCHAR:
			break;
		case EV_ERR:
			break;
		default:
			MessageBoxA(NULL, "WCE error default", "", MB_OK); return 0;
		}
	}
	else   { MessageBoxA(NULL, "WCE error", "", MB_OK); return 0; }
В терминале при отправке ”AT” в ответ идет “OK”, в своем коде я зависаю в WaitCommEvent.
Т.е. я модему отослал (я так думаю), а он в обратку мне ничего не отправляет.
WaitCommEvent должна вернуть управление, когда во входном буфере появится что-то или произойдет ошибка, управление не возвращается - буфер пуст (это моя логика).

Последний раз редактировалось 220Volt; 09.07.2013 в 20:41.
220Volt вне форума Ответить с цитированием
Старый 09.07.2013, 20:46   #9
220Volt
Форумчанин
 
Регистрация: 14.12.2012
Сообщений: 668
По умолчанию

Цитата:
Сообщение от raxp Посмотреть сообщение

...И вы не ответили зачем CFUN влепили.
Я встретил это http://www.absolutebsd.ru/2011/01/zte-mf180-sms.html
220Volt вне форума Ответить с цитированием
Старый 09.07.2013, 23:03   #10
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

A еще я бы попробовал \r вместо \n
waleri вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Подключение миши через USB порт tito0000 Общие вопросы C/C++ 3 01.05.2013 09:54
удаленный доступ к USB модемам (Ноутбук с подключенным Билайн модемом, осуществить коннект к нему через Ha admin) ArtemSakh Компьютерное железо 8 18.01.2013 10:03
Работа с прибором через COM порт russervik C# (си шарп) 7 17.10.2012 09:25
Создание программы передавача данных через USB порт edmore Помощь студентам 4 10.11.2011 13:30
Как можно обратиться к устройству, которое подключено через USB порт Mikhail Bakurov Общие вопросы Delphi 8 17.11.2008 20:42