Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Чтение из COM порта 
:(
    Опции темы
Nil
Дата 16.6.2007, 21:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 15.4.2007

Репутация: нет
Всего: нет



Здравствуйте.
Ответа именно на мои вопросы не нашел, поэтому все же решил создать новую тему.
Код

hPort=CreateFile(TEXT("\\\\.\\COM16"),GENERIC_WRITE|GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

Таким образом открываю порт для чтения/записи. 
Есть следующие проблемы:
1) Если сразу после записи в порт начаь читать из него, то получу только что записанную строку, что не очень удобно, как бороться ? Как правильно читать ?
2) Можете пояснить на счет структуры COMMTIMEOUTS - какое поле за что отвечает ?..
ReadTotalTimeoutMultiplier - сколько макс. ждем одного символа ?
ReadTotalTimeout               -  ? не совсем понял логику...
----------

Вообще требуется после того как записал в порт строку, ждать ответа в виде "ОК" максимально в течение 5 секунд, как это лучше реализовать ?..

PM MAIL WWW ICQ   Вверх
Static
  Дата 9.9.2009, 08:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 185
Регистрация: 6.11.2008

Репутация: нет
Всего: 2



Это, конечно, староватый топик, но наиболее подходящий...
Есть у меня задача - подключить электронные весы к компу. Пока весы фиг знает где стоят, решил потренироваться на чем-нить еще - никогда с com не работал. Нашел модем. И... я, наверно, делаю что-то не так.
Если с модемом связаться через гипертерминал, например, - все ок: пишем AT - получаем OK. Ну и т.п.
А вот прога, которую я наваял, получает только эхо :( Перерыл дофига всего - везде все (на первый взгляд) идентично, даже в исходниках другого терминала, который тоже работает нормально.
Мой код:
Код

#include <iostream>
#include <cstdio>
#include <windows.h>

using namespace std;

bool OpenComPort(const char* port_name, HANDLE &com_handle, COMSTAT &ComState)
{
COMMTIMEOUTS CommTimeOuts;
DCB dcb;

com_handle = CreateFile(port_name, GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_EXISTING, NULL, 0);
if (com_handle == INVALID_HANDLE_VALUE)
    {
    cout << "CreateFile failed" << endl;
    return false;
    }
GetCommState(&com_handle, &dcb);

dcb.BaudRate = 9600;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;

GetCommTimeouts(com_handle, &CommTimeOuts);
CommTimeOuts.ReadIntervalTimeout= 100;
CommTimeOuts.ReadTotalTimeoutMultiplier = 15;
CommTimeOuts.ReadTotalTimeoutConstant = 100;
CommTimeOuts.WriteTotalTimeoutMultiplier = 1;
CommTimeOuts.WriteTotalTimeoutConstant = 1000;
SetCommTimeouts(com_handle, &CommTimeOuts);
SetCommState(com_handle, &dcb);

DWORD temp = 0;
if (!ClearCommError(com_handle, &temp, &ComState))
    {
    cout << "ClearCommError failed" << endl;
    }
SetupComm(com_handle, 64, 64);
return true;
}

int main(int argc, char* argv[])
{
HANDLE com_handle;
COMSTAT ComState;

if (!OpenComPort("COM1", com_handle, ComState))
        {
        cout << "OpenComPort returned false :(" << endl;
        }
    else
        {
        cout << "Port was opened" << endl;
        }

DWORD numbytes_ok = 0;
unsigned char buf[62] = {0};
unsigned char outbuf[64] = {0};

while (true)
    {
    cin >> buf;
    if (!strcmp((char*)buf, "stop"))
        break;

    DWORD temp = 0;
    ClearCommError(com_handle, &temp, &ComState);
    if (!temp)
        {
        WriteFile(com_handle, buf, strlen((char*)buf), &numbytes_ok, NULL);
        }

    ClearCommError(com_handle, &temp, &ComState);
    if (!temp)
        {
        ReadFile(com_handle, outbuf, 64, &numbytes_ok, NULL);
        cout << "received " << numbytes_ok << " bytes: " << outbuf << endl;
        }

    memset(buf, 0, 64);
    memset(outbuf, 0, 64);
    }

CloseHandle(com_handle);

return 0;
}


Подозреваю, что-то элементарное забыл/не сделал/не знал. Подскажите, пожалуйста.
--------------------
Я не настолько безнадежен, как кажется...
PM MAIL   Вверх
GremlinProg
Дата 9.9.2009, 09:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



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

Цитата(Static @  9.9.2009,  10:42 Найти цитируемый пост)
Подозреваю, что-то элементарное забыл/не сделал

для AT-команд, думаю, это элементпрное - символ перевода строки в конце команды, т.е. "\r" или "\n" или "\r\n"


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Static
Дата 9.9.2009, 10:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 185
Регистрация: 6.11.2008

Репутация: нет
Всего: 2



да пробовал... было и вот так:
Код

WriteFile(com_handle, buf, strlen((char*)buf), &numbytes_ok, NULL);
WriteFile(com_handle, crlf, 2, &numbytes_ok, NULL); //crlf = "\r\n"


и вот так:
Код

buf[strlen((char*)buf)] = '\r';
buf[strlen((char*)buf)] = '\n';
WriteFile(com_handle, buf, strlen((char*)buf), &numbytes_ok, NULL);


никакой разницы. Может еще вариант подкинете?
--------------------
Я не настолько безнадежен, как кажется...
PM MAIL   Вверх
GremlinProg
Дата 9.9.2009, 10:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



так будет логичнее:
Код

int len = strlen((char*)buf);
buf[len++] = '\r';
buf[len++] = '\n';
buf[len++] = '\0';
WriteFile(com_handle, buf, len, &numbytes_ok, NULL);


Добавлено через 55 секунд
это можно не добавлять:
Код

buf[len++] = '\0';

это просто для красоты )


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Static
Дата 9.9.2009, 10:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 185
Регистрация: 6.11.2008

Репутация: нет
Всего: 2



ну, видать, не красота спасет мир... То же только в профиль.
Передается "AT\r\n" - это точно. А принимается только эхо. Т.е. точно то же, что и послали. Может я неправильно делаю ReadFile?
--------------------
Я не настолько безнадежен, как кажется...
PM MAIL   Вверх
GremlinProg
Дата 9.9.2009, 11:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



для теста сойдет,
а в гипертерминале то же самое?
или ОК все же приходит?

если и там не приходит, смотри документацию к модему,
тут может потребоваться перевод модема в командный режим "+++", вобщем, это уже специфка конкретного модема


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Static
Дата 9.9.2009, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 185
Регистрация: 6.11.2008

Репутация: нет
Всего: 2



Цитата(Static @  9.9.2009,  07:42 Найти цитируемый пост)
Если с модемом связаться через гипертерминал, например, - все ок: пишем AT - получаем OK. Ну и т.п.

Проблема где-то в моем коде...
--------------------
Я не настолько безнадежен, как кажется...
PM MAIL   Вверх
xvr
Дата 9.9.2009, 11:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



'ОК' придет, но позже - модем довольно медленное устройство, а уж COM порт и подавно  smile 
Стоит разобраться как работает модем с COM портом -
Когда в модем передают символы (те самые AT), он их отправляет назад (так же посимвольно) - таким образом получается эхо (сам по себе COM порт эхо НЕ ОБЕСПЕЧИВАЕТ!)
Когда модеи получает символ CR ('\r'), он начинает выполнять команду, ПОСЛЕ чего посылает ответ.

Рекомендую перед ReadFile поставить Sleep(500) - должно хватить для приема ответа


PM MAIL   Вверх
Static
Дата 9.9.2009, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 185
Регистрация: 6.11.2008

Репутация: нет
Всего: 2



Спасибо за подсказку... Сейчас попробую.
--------------------
Я не настолько безнадежен, как кажется...
PM MAIL   Вверх
GremlinProg
Дата 9.9.2009, 11:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



ну да, а может и Get/SetCommState возвращаются с ошибкой,
т.к. DCB инициирован неправильно, тут пропущена по крайнеймере установка длины структуры:
Код

dcb.DCBlength = sizeof(dcb);



--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Static
Дата 9.9.2009, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 185
Регистрация: 6.11.2008

Репутация: нет
Всего: 2



Нет... это не то. Да и в гипретерминале модем почти мгновенно отвечает.
Даже Sleep(5000) не решает.
Я правильно понимаю, что полученные данные никуда не деваются, а спокойно лежат в буфере? И ReadFile их просто оттуда достает?.. Может модем просто не понимает, что я ему команду отправил? Кодировка или еще что-нить может не совпадать?

Добавлено через 4 минуты и 40 секунд
Ошибок ни то, ни другое не возвращает. И, насколько я понимаю, получив структуру при помощи GetCommState, длину ей задавать уже не надо. В лбом случае - явное задание ничего не решает.
--------------------
Я не настолько безнадежен, как кажется...
PM MAIL   Вверх
GremlinProg
Дата 9.9.2009, 11:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(Static @  9.9.2009,  13:43 Найти цитируемый пост)
Может модем просто не понимает, что я ему команду отправил?

поставь  проверки на все вызовы, тогда возможно будет понятно где проблема


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Static
Дата 9.9.2009, 12:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 185
Регистрация: 6.11.2008

Репутация: нет
Всего: 2



ок. Только какие проверки? Единственный вызов write/read проверять?
--------------------
Я не настолько безнадежен, как кажется...
PM MAIL   Вверх
smoke_man
Дата 9.9.2009, 13:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 447
Регистрация: 25.1.2007
Где: Рязань

Репутация: 5
Всего: 17



Посмотри пример может поможет.


--------------------
0x2b|~0x2b
PM MAIL ICQ GTalk   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0923 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.