Работа с модемом через API

Для неординарных вопросов. Если вы опытный программист, попавший в трудную ситуацию, — вам сюда.

Модератор: gaidar

Правила форума
Этот раздел не предназначен для того, чтобы вы адресовали свою проблему профессионалам.
Этот раздел предназначен для профессионалов, которые столкнулись с проблемой и не могут решить ее самостоятельно.
Если вы считаете себя профессионалом, а свою проблему сложной — вам сюда.
Если модератор посчитает, что вы ошиблись, то на первый раз он перенесет ваше сообщение в основной раздел без последствий для автора. Во второй раз тема будет закрыта, а автору будет выписано нарушение. В третий раз автор будет забанен.
Kostyan
Постоялец
Постоялец
 
Сообщения: 439
Зарегистрирован: 20.09.2002 (Пт) 4:14
Откуда: Россия, Уссурийск

Работа с модемом через API

Сообщение Kostyan » 17.03.2007 (Сб) 7:18

Здравствуйте.
Написал программу для обмена с модемом AT-командами. Решил не пользоваться mscomm32.ocx, а работать напрямую с портом через WriteFile/ReadFile. Вот упрощенный код моей программы:
Код: Выделить всё
Private Sub Form_Load()
hModem = CreateFile("COM1", GENERIC_READ Or GENERIC_WRITE, 0, Security, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
If hModem <> -1 Then
    DCB_Param.DCBlength = Len(DCB_Param)
    Call GetCommState(hModem, DCB_Param)
    DCB_Param.DCBlength = 28
    DCB_Param.BaudRate = 9600
    DCB_Param.fBitFields = 16529
    DCB_Param.XonLim = 256
    DCB_Param.XoffLim = 256
    DCB_Param.ByteSize = 8
    DCB_Param.Parity = NOPARITY
    DCB_Param.StopBits = ONESTOPBIT
    If SetCommState(hModem, DCB_Param) <> 0 Then
        Call GetCommTimeouts(hModem, ComTimeOut)
        ComTimeOut.ReadIntervalTimeout = -1
        ComTimeOut.ReadTotalTimeoutMultiplier = 0
        ComTimeOut.ReadTotalTimeoutConstant = 0
        ComTimeOut.WriteTotalTimeoutMultiplier = 0
        ComTimeOut.WriteTotalTimeoutConstant = 5000
        If SetCommTimeouts(hModem, ComTimeOut) <> 0 Then
            Call PurgeComm(hModem, PURGE_RXCLEAR Or PURGE_TXCLEAR)
            Call SetupComm(hModem, 256, 256)
            outBuffer = "AT" & vbCrLf
            Me.Caption = WriteFile(hModem, ByVal outBuffer, Len(outBuffer), n, 0)
            Timer1.Enabled = True
        Else
            MsgBox "Не могу установить таймауты", vbCritical, "Ошибка"
        End If
    Else
        MsgBox "Не могу установить параметры устройства", vbCritical, "Ошибка"
    End If
Else
    MsgBox "Не могу открыть порт", vbCritical, "Ошибка"
End If
End Sub

Private Sub Form_Unload(Cancel As Integer)
Call CloseHandle(hModem)
End Sub

Private Sub Timer1_Timer()
inBuffer = String$(256, Chr$(0))
Me.Caption = ReadFile(hModem, ByVal inBuffer, 256, n, 0)
Me.Caption = Me.Caption & ", прочитано байт: " & n
Text1.Text = Text1.Text & Left$(inBuffer, n)
End Sub


У таймера интервал выставлен 500 мс.
Всё работает отлично, запись/считываение, обмн данными, но только в среде разработки. После компиляции перестает работать. Ничего не записывается в порт и ничего не считывается из него. Функции WriteFile и ReadFile возвращают 0 (ошибка). Работает только если берешь окно мышкой за заголовок и таскаешь его по экрану, как только отпускаешь заголовок всё становится на свои места, функции опять возвращяют ошибку. Никак не могу понять что за странное поведение программы.

Для наглядности прикладываю саму прогу (сильно урезанную), которая демонстрирует всю проблему.
Помогите разобраться, срочно нужно, заказчик ждет.
Вложения
Project.zip
(3.52 Кб) Скачиваний: 297
Последний раз редактировалось Kostyan 17.03.2007 (Сб) 18:07, всего редактировалось 1 раз.
Нет ничего невозможного для человека с интеллектом.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Re: Работа с модемом через API

Сообщение tyomitch » 17.03.2007 (Сб) 12:03

Kostyan писал(а):Функции WriteFile и ReadFile возвращают 0 (ошибка).

Err.LastDllError не пробовал смотреть?
Изображение

Kostyan
Постоялец
Постоялец
 
Сообщения: 439
Зарегистрирован: 20.09.2002 (Пт) 4:14
Откуда: Россия, Уссурийск

Сообщение Kostyan » 17.03.2007 (Сб) 16:19

Пробовал, ошибка №6, ERROR_INVALID_HANDLE.
Только что именно не так всё-равно не понятно.
Не могу понять почмеу работает во время таскания окна, и перестает работать когда его отпускаешь... И причем тут неверный хэндл...
Нет ничего невозможного для человека с интеллектом.

BV
Thinker
Thinker
Аватара пользователя
 
Сообщения: 3987
Зарегистрирован: 12.09.2004 (Вс) 0:55
Откуда: Молдавия, г. Кишинёв

Сообщение BV » 17.03.2007 (Сб) 16:41

Гм. Не могу скачать аттач из первого поста.

Выбранное приложение больше не существует

404 File Not Found: The File files/project_134.zip does not exist.
const char *out = "|*0>78-,+<|"; size_t cc = char_traits<char>::length(out);
for (size_t i=0;i<cc;i++){cout<<static_cast<char>((out[i]^89));}cout<<endl;

Kostyan
Постоялец
Постоялец
 
Сообщения: 439
Зарегистрирован: 20.09.2002 (Пт) 4:14
Откуда: Россия, Уссурийск

Сообщение Kostyan » 17.03.2007 (Сб) 18:08

Перезалил, сейчас качается.
Выяснил что программа нормально работает когда заставляешь окно перерисовываться, например меняешь размер или таскаешь по экрану. В этот момент происходит считывание из COM порта всей накопившейся информации.
Я уже не знаю на что и думать...
Нет ничего невозможного для человека с интеллектом.

Kostyan
Постоялец
Постоялец
 
Сообщения: 439
Зарегистрирован: 20.09.2002 (Пт) 4:14
Откуда: Россия, Уссурийск

Сообщение Kostyan » 19.03.2007 (Пн) 17:15

Вобщем разобрался сам с проблемой. Если кому интересно или вдруг пригодится, для корректной работы открывать порт следует в режиме асинхронного доступа:

hModem = CreateFile("COM1", GENERIC_READ Or GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0)

Объявляем 2 переменных типа OVERLAPPED и создаем 2 события:

Public Overlaps(1) As OVERLAPPED
Overlaps(0).hEvent = CreateEvent(0, True, False, vbNullString)
Overlaps(1).hEvent = CreateEvent(0, True, False, vbNullString)

И во время записи/чтения не забываем передавать параметр lpOverlapped:

WriteFile(hModem, outBuffer, Len(outBuffer), n, Overlaps(1))
ReadFile(hModem, inBuffer, 256, n, Overlaps(0))

Всё остальное остаётся без изменений.
Нет ничего невозможного для человека с интеллектом.

Vladvil
Начинающий
Начинающий
 
Сообщения: 1
Зарегистрирован: 26.04.2007 (Чт) 5:59

Сообщение Vladvil » 26.04.2007 (Чт) 8:37

Столкнулся с такой же проблемой, только обошел ее выставив в опциях компилятора компилировать в P-Code...
to Kostyan
а можно примерчик реализации решения проблемы?

Kostyan
Постоялец
Постоялец
 
Сообщения: 439
Зарегистрирован: 20.09.2002 (Пт) 4:14
Откуда: Россия, Уссурийск

Сообщение Kostyan » 27.04.2007 (Пт) 12:19

Решение проблемы я описал выше, держи пример:
Вложения
Project.zip
(3.53 Кб) Скачиваний: 361
Нет ничего невозможного для человека с интеллектом.


Вернуться в Раздел для Профессионалов

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 10

    TopList