На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! user posted image
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.

Соблюдайте общие правила форума

Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как запустить программу/файл? (и дождаться ее завершения)
5. Как перехватить API-функции, поставить hook? (перехват сообщений от мыши, клавиатуры - внедрение в удаленное адресное прстранство)
... (продолжение следует) ...

Внимание:
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки - бан.
Мат в разделе - бан на три месяца...

Полезные ссылки:
user posted image MSDN Library user posted image FAQ раздела user posted image Поиск по разделу user posted image Как правильно задавать вопросы


Выразить свое отношение к модераторам раздела можно здесь: user posted image Rouse_, user posted image Krid

Модераторы: Rouse_, Krid
  
> COM-порт+модем , Порядок работы
    Здравствуйте. Не знаю, как правильно организовать передачу АТ-команд и приём ответов от модема. Как с этими СОМ-портами работать правильно?
    Открываю порт через СreateFile. Отправляю команду ATH через writefile. В ответ (readfie) вместо Ok получаю только один байт - $13.
    В общем, кто разобрался с СОМ и с модемами, отзовитесь.
      19 Connect 38400 Установлена связь на скорости 38400бит/с
      С модемом не работал, но игрался с ком мышью. Собственно ошибок не вижу.

      Решил поработать с модемом. Тав возращается не один байт, а несколько.
      Сообщение отредактировано: Pavia -
        Цитата
        Открываю порт через СreateFile. Отправляю команду ATH через writefile. В ответ (readfie) вместо Ok получаю только один байт - $13.

        Попробуй отправлять просто команду 'AT#13#10', не помню точно, но вроде на ATH модем ответ не дает. Также можешь воспользоваться моим компонентом KlientServComConnect - он как раз предназначен для работы с модемом и COM-портом.
          zubr прав, все AT команды должны заканчиваться парой CR/LF.
          Сразу предупрежу, что желательно использовать апаратный контроль потока данных. И перед каждым чтением проверять наличие байта в приемном буфере. Иначе функции чтения будут виснуть, и даже с использованием оверлеев, пока функция чтения не вернется, писать в порт нельзя.

          Добавлено
          Конкретно с модемом я не работал, зато много работал с собственными устройствами по RS232 (COM).
            Цитата
            Попробуй отправлять просто команду 'AT#13#10', не помню точно, но вроде на ATH модем ответ не дает. Также можешь воспользоваться моим компонентом KlientServComConnect - он как раз предназначен для работы с модемом и COM-портом.

            Цитата
            zubr прав, все AT команды должны заканчиваться парой CR/LF.
            Сразу предупрежу, что желательно использовать апаратный контроль потока данных. И перед каждым чтением проверять наличие байта в приемном буфере. Иначе функции чтения будут виснуть, и даже с использованием оверлеев, пока функция чтения не вернется, писать в порт нельзя.

            Так и передаю, вместе с #13#10. В ответ модем должен выдавать строку #13#10 OK #13#10, а я получаю только #13.
            А что такое аппаратный контроль данных. Как это реализовывается? Про оверлеи я почитал(на англ.), но не очень понял, куда их тулить. Пока понял так, что если оверлеи не используются, то команды чтения не "заканчиваются" до тех пор, пока не будет принят хотя-бы один символ. Это правильно?
            У меня так и происходит, то Wait, то Read виснут.
            В общем, нет у меня чёткого представления, как должен быть реализован обмен, что-то не учитываю.
            Я делаю так:
            write - команда
            wait - в буфер принят символ
            read - ответ.
            Ненадёжно работает. Первую команду отправляю, получаю один байт #13, на последующие вроде нормальную строку получаю. Чувствую, чего-то я не догоняю, как обмен происходит, там ведь еще всякие сигнал есть: DSR,CTS...
            Я могу и код представить. Только позориться не хочется. Пока только эксперименты.
            Конечная цель - дозвониться до абонента и передать голосовое сообщение(голосовой модем).
            zubr, а где взять KlientServComConnect? Поддерживает ли он голосовые функции? Если не получится ручками, придется, конечно, готовыми компонентами пользоваться.
            Сообщение отредактировано: Prince -
              Взять можно здесь: Klientservcomconnect. Голосовые функции не поддерживает, есть полный Help + примеры работы с ним.
                Вот результаты "исследований".
                Для обмена с модемом используется вот такая функция
                ExpandedWrap disabled
                  function SendCommand(const command:string):string;
                  var writed,readed:dword;
                      buffer:array[1..64]of byte;
                      i:byte;
                      c:string;
                      evtmask,mask:dword;
                  begin
                  result:='';
                  c:=command+char($0d)+char($0a);
                  for i:=1 to length(c) do buffer[i]:=byte(c[i]);
                  PurgeComm(COMPort,PURGE_TXCLEAR or PURGE_RXCLEAR);
                  if s<>'' then
                  if not writefile(COMPort,buffer,length(c),writed,nil) then begin
                                                                             exit;
                                                                             end;
                  mask:=EV_RXCHAR;
                  setcommmask(COMPort,mask);
                  if not WaitCommEvent(COMPort,mask,nil) then begin
                                                                 exit
                                                                 end;
                  sleep(100);
                  if not readfile(COMPort,buffer,64,readed,nil) then begin
                                                                 exit;
                                                                 end;
                  if readed=0 then begin
                                   exit;
                                   end;
                   
                  for i:=1 to readed do
                  result:=result+char(buffer[i]);
                  end;


                Дальше передаю команды

                ExpandedWrap disabled
                  s:='AT#CLS=8 #VSR=8000 #VBS=4';
                  r:=sendcommand(s);
                  form1.memo1.Lines.Add(s);
                  form1.memo1.Lines.Add(r);
                  s:='ATD80973595377';
                  r:=sendcommand(s);
                  form1.memo1.Lines.Add(s);
                  form1.memo1.Lines.Add(r);
                   
                  sleep(5000);
                   
                  s:='AT#VTX';
                  r:=sendcommand(s);
                  form1.memo1.Lines.Add(s);
                  form1.memo1.Lines.Add(r);
                   
                  for i:=1 to 5 do begin
                  s:='';
                  r:=sendcommand(s);
                  form1.memo1.Lines.Add(s);
                  form1.memo1.Lines.Add(r);
                                    end;
                   
                  s:=char($10)+char($18);
                  r:=sendcommand(s);
                  form1.memo1.Lines.Add(s);
                  form1.memo1.Lines.Add(r);
                  s:='ATH0';
                  r:=sendcommand(s);
                  form1.memo1.Lines.Add(s);
                  form1.memo1.Lines.Add(r);


                в результате имею вот такой диалог
                ExpandedWrap disabled
                  AT#CLS=8 #VSR=8000 #VBS=4
                   
                  OK
                   
                  ATD80973595377
                   
                  VCON
                   
                  AT#VTX
                   
                  CONNECT
                   
                   
                  d
                   
                  d
                   
                  d
                   
                  d
                   
                  d
                   
                  d
                  
                   
                  VCON
                   
                  ATH0
                   
                  OK

                Квадратики - это $10.
                Т.е., модем дозванивается, переключается в режим передачи данных. А вот дальше какая-то загадка. Если ничего не передавать, то модем через некоторое время выдает вот эти самые строки - $10d$10, что-то в этом роде.
                Если передаю небольшой буфер, модем вроде "квакает" что-то. Если передаю большой буфер, например 10000 байт, функция writefile виснет.
                В общем, буду благодарен, если кто-нибудь знает, как передавать голосовые данные модему.
                  Prince
                  Вопрос:"А голосовые данные откуда берешь???"
                  Цитата Prince @
                  Если передаю небольшой буфер, модем вроде "квакает" что-то. Если передаю большой буфер, например 10000 байт, функция writefile виснет.

                  А чтобы не было зависаний перейди на асинхронный режим работы с портом и периодически проверяй Overlap.Event,которая привязана к writefile, только Event с ручным сбросом. После того как модем выдаст тебе CONNECT
                  проверяй событие порта EV_RLSD (связь модемов установлена), и только при наступлении этого события можно начинать работу с данными, ну а какой будет протокол решать тебе. :rolleyes:
                    Так у меня ведь связь не с модемом, а с телефоном устанавливается. Или без разницы? С асинхронным режимом я пока не разобрался. Мне бы пока хоть с синхронным. А данные пытаюсь передавать из wav файла. Протокол(формат) 8000 Гц 4 бита ADPCM(вроде бы). Но как их передавать, эти данные. Есть там, видимо, какой-то секрет, а какой?
                      Prince
                      Цитата Prince @
                      Так у меня ведь связь не с модемом, а с телефоном устанавливается. Или без разницы?

                      Так бы и сказал. Разница есть, даже очень. Большая проблема узнать момент снятия трубки на том конце.
                      И сразу вопрос
                      Цитата Prince @
                      А данные пытаюсь передавать из wav файла.

                      А на том конце у человека звуковуха в ухе, что ли???? Или ты пытаешьсяпроиграть данные в линию со звуковухи. Это вообще то совсем другой коленкор
                        Цитата
                        Или ты пытаешьсяпроиграть данные в линию со звуковухи. Это вообще то совсем другой коленкор

                        Ну да, пытаюсь. Только не со звуковухи, а из файла. А как по другому это сделать?
                        Сообщение отредактировано: Prince -
                          Цитата Prince @
                          Ну да, пытаюсь. Только не со звуковухи, а из файла

                          Поясни как ты файл звука превратишь в аналог <_< Что то я не догнал
                            Это модем занимается переводом в аналог. Я ему передаю команду AT#VTX, и он переходит в режим передачи голосовых данных, возвращая СONNECT. Дальше, по идее, я ему сливаю звуковой поток, а кодек модема(модем голосовой) переводит этот поток в аналог. Вот с этим и проблема. В конце звукового потока я передаю модему 2 байта - $10 $18. Модем снова переходит в командный режим и в ответ выдаёт VCON(см. лог выше). Вот примерно так. Ну а дальше снова можно испоьлзовать обычные AT-команды.
                            Сообщение отредактировано: Prince -
                              PrinceИзвини уж неугомонного, но:
                              Цитата Prince @
                              я ему сливаю звуковой поток, а кодек модема(модем голосовой) переводит этот поток в аналог. Вот с этим и проблема.

                              Сливаешь ему просто Wav файл???Или же чистые данные???

                              Цитата Prince @
                              Протокол(формат) 8000 Гц 4 бита ADPCM(вроде бы). Но как их передавать, эти данные

                              Вроде бы тут не прокатит
                              А ты пробовал Wav файл проиграть на чем нибудь с таким форматом??? :wacko:

                              ExpandedWrap disabled
                                сжатие ADPCM:
                                (Частота выборки) предлагаются следующие значения:
                                 
                                5 кГц - приемлем только для речи;
                                11 кГц - самое низкое рекомендуемое качество для короткого музыкального фрагмента; четверть стандартного значения качества CD (компакт-диска);

                              Что то непонятка какая-то с протоколами сжатия:wacko: :wacko:
                                Сливаю чистые данные формата ADPCM, моно, 8000 Гц, 4 бита без заголовка, естественно.

                                Этот формат поддерживается модемом. Кроие того, он поддерживает частоты 7200Гц и 11025 Гц. И еще 2 и 8 бит.
                                Вообще модемы могут поддерживать PCM, ADPCM, и GSM6.10 в зависимости от производителя и модели.

                                Проиграть файл можно хотя бы универсальным проигрывателем или медиа-плеером.

                                У меня проблема с передачей звуковых данных. Есть много ньюансов. Оказывается, есть там всякие управляющие коды и нужен аппаратный контроль данных, чтобы не было переполнения буфера(вот только-только прочитал). Как организовать аппаратный контроль данных?

                                А, вот ещё какая штука. Оказывается, строки $10 d , которые модем возвращал, это признак обнаружения сигнала КПВ(контроль посылки вызова). Видел несколько тем, люди справшивали, как определить, когда на удаленном конце сняли трубку. Ну вот видимо, таким способом можно.
                                Сообщение отредактировано: Prince -
                                  Цитата Prince @
                                  Как организовать аппаратный контроль данных?

                                  Ты работаешь с Сом портом через TDCВ???Если да, то в DCB.Flags проверь биты установки режима HandShake для fDTRControl,FDsrSensitivity,fRTSControl.И обязательно должен быть включен fOutCTSFlow. Какие биты я не помню,но в нете по Flags полно инфы. Да кстати по поводу снятия трубки на другом конце. Года 2 назад я эту проблему решил путем подключения дополнительного девайса на МК51 к компу. Если интересно, могу поподробнее.
                                    Что такое TDCВ? Я пример приводил, как я с портом работаю.
                                      Аппаратный контроль данных - работа с линиями RTS/CTS. Они включаются модемом или компом, когда их буфер приема заполнен полностью.
                                      Есть еще DTR/DSR. Они устанавливаются когда приемный буфер заполнен на 3/4. (тоно насчет доли не уверен)

                                      Добавлено
                                      Это нужно в первую очередь для модема, иначе он может не успеть обработать твои данные и освободить буфер.

                                      Добавлено
                                      Цитата medved_68 @
                                      Года 2 назад я эту проблему решил путем подключения дополнительного девайса на МК51 к компу. Если интересно, могу поподробнее.

                                      Интересно. Особенно схематика подключения к линии.
                                        Prince
                                        Цитата Prince @
                                        Что такое TDCВ? Я пример приводил, как я с портом работаю.

                                        Ты с портом работаешь через WriteFile, readFile. Это я понял. Но как ты его настраиваешь перед работой, после того как открыл CreateFile???? Откуда он у тебя знает с какой скоростью работать, какие таймауты и т.д. Поэтому я и спрашиваю:
                                        Цитата medved_68 @
                                        Ты работаешь с Сом портом через TDCВ???

                                        Цитата Prince @
                                        Что такое TDCВ?

                                        Обволакивающий класс для структуры DCВ, в которой должны быть прописаны настройки компорта при его открытии. После открытия порта выполняется команда SetCommState (Handle,lpDCB)(за синтаксис не ручаюсь),которая настроит порт согласно тем данным, которые ты занес в структуру DCВ, а если в дельфях то TDCВ.Flags. И после этого только можно с ним работать. :yes: Может у тебя все в норме в проге и просто порт не настроен, судя по твоему последнему письму??? <_<
                                        Testudo
                                        Цитата Testudo @
                                        Интересно. Особенно схематика подключения к линии.

                                        Сегодня пороюсь в архивах.Там только был небольшой нюанс - вероятность определения 50-70%, а на блокированных линиях вообще грустно где то 10-20%, но у нас сейчас почти их не осталось, хотя кто его знает. Помню только, что сама линия заводилась на устройство через обычный диодный мост на КЦ407. Тогда меня порадовало одно-отсутствие ложных срабатываний, типа когда никто трубку не снял, а датчик сработал. И еще не сделал в свое время усреднение в зависимости от АТС к кому подключаешься, там несильно, но были различия во времени ответа станции. Но шел путем АОНа на ВМ80 + АОНа на Z80 это я точно помню.
                                          Цитата
                                          Аппаратный контроль данных - работа с линиями RTS/CTS. Они включаются модемом или компом, когда их буфер приема заполнен полностью.
                                          Есть еще DTR/DSR. Они устанавливаются когда приемный буфер заполнен на 3/4. (тоно насчет доли не уверен)

                                          А как именно с ними работать?
                                          Вот я отправляю какой-то буфер командой writefile. Как узнать, какой размер данных можно отправить за раз?
                                          И когда можно отправлять новую порцию данных?

                                          Добавлено
                                          Цитата
                                          После открытия порта выполняется команда SetCommState (Handle,lpDCB)(за синтаксис не ручаюсь),которая настроит порт согласно тем данным, которые ты занес в структуру DCВ, а если в дельфях то TDCВ.Flags. И после этого только можно с ним работать. Может у тебя все в норме в проге и просто порт не настроен, судя по твоему последнему письму???

                                          А, понял. Да, через DCB. Ну я посмотрел вначале настройки через GetCommState, а что именно и как нужно настроить для передачи голосовых данных, не знаю. Работает - и работает. Хотя вот уже знаю, что должен быть включён аппаратный контроль данных. Буду пробовать.
                                            Цитата Prince @
                                            А как именно с ними работать?
                                            Вот я отправляю какой-то буфер командой writefile. Как узнать, какой размер данных можно отправить за раз?
                                            И когда можно отправлять новую порцию данных?

                                            ты можешь отправить сразу хоть все данные только при работе в синхроне writefile тебе не вернет управление пока все не отправит. А если в этот момент случится авария на линии то все зависнет, причем наглухо. Я же тебе говорю: "переходи на асинхрон". Тогда структура Overlap тебе вернет количество реально переданных в линию байт, даже если случится внезапный Break. А момент когда можно отправить очередную порцию отслеживается наблюдением за событием EV_TXEMPTY (из буфера передачи послан последний символ). В это же время и произойдет установка события Overlap.Event, привязанного к записи.
                                              Если в синхроне, то отправлять данные модему желательно по одному байту, при этом проверяя сигнал CTS. Если он установлен - писать можно. Если нет - нужно подождать.
                                                Testudo
                                                Цитата Testudo @
                                                Если в синхроне, то отправлять данные модему желательно по одному байту, при этом проверяя сигнал CTS

                                                Почему???
                                                Если настроен аппаратный контроль, то драйвер сам будет приостанавливать передачу по сбросу CTS и ждать пока пока модем его выставит.
                                                  Другими словами, нужно просто включить аппаратный контроль и забыть про этот самый контроль? Драйвер всё сделает сам? А мне остаётся только написать команду writefile и ждать, пока она не выполнится?
                                                  Цитата
                                                  ты можешь отправить сразу хоть все данные только при работе в синхроне writefile тебе не вернет управление пока все не отправит. А если в этот момент случится авария на линии то все зависнет, причем наглухо.

                                                  А можно ли избежать зависания, выставив таймауты?
                                                    Цитата medved_68 @
                                                    Если настроен аппаратный контроль, то драйвер сам будет приостанавливать передачу по сбросу CTS и ждать пока пока модем его выставит.
                                                    За модем не отвечаю.
                                                    Я же сказал, что работал с самодельными устройствами. У них делал все как положено, но аппаратный контроль ничего не проперал.
                                                      Цитата Prince @
                                                      Другими словами, нужно просто включить аппаратный контроль и забыть про этот самый контроль? Драйвер всё сделает сам? А мне остаётся только написать команду writefile и ждать, пока она не выполнится?

                                                      Да,если ты правильно настроишь TDCB.Flags. Надо ожидать завершения writefile и анализировать сколько байт передано, хотя она все равно не вернет управление пока все заявленное не передаст,если не выставлен таймаут по времени записи. Но его надо устанавливать при каждой операции, если передаешь блоки разной длинны, или на время передачи самого длинного блока, тогда нужен анализ, сколько байт передано, если меньше чем нужно, то повторить writefile с передачей того что не допередал.
                                                      Цитата Prince @
                                                      А можно ли избежать зависания, выставив таймауты?

                                                      Именно для этого они и придуманы!!!!
                                                      Testudo
                                                      Цитата Testudo @
                                                      Я же сказал, что работал с самодельными устройствами. У них делал все как положено, но аппаратный контроль ничего не проперал.

                                                      Значит неправильно настроил порт на аппаратный контроль. По умолчанию плевать он хотел на все управляющие сигналы. :D :lool:
                                                      А по самопалу могу сказать, что я по прерыванию от порта на микроконтроллере сразу выставляю CTS, затем считываю байт из регистра приемника, обрабатываю его, и только потом снимаю CTS. Т.е. делаю как ты говорил, но только со стороны самопала, со стороны компа это все уже продумали за меня.
                                                        Цитата medved_68 @
                                                        Значит неправильно настроил порт на аппаратный контроль. По умолчанию плевать он хотел на все управляющие сигналы.
                                                        А по самопалу могу сказать, что я по прерыванию от порта на микроконтроллере сразу выставляю CTS, затем считываю байт из регистра приемника, обрабатываю его, и только потом снимаю CTS. Т.е. делаю как ты говорил, но только со стороны самопала, со стороны компа это все уже продумали за меня.
                                                        И плохо, что думать не хочешь.
                                                          Testudo
                                                          Цитата Testudo @
                                                          И плохо, что думать не хочешь.

                                                          Изобретать велосипед конечно полезно, но зачем??? :wacko:
                                                            Цитата
                                                            Да,если ты правильно настроишь TDCB.Flags

                                                            А как правильно настроить?
                                                              ExpandedWrap disabled
                                                                А как правильно настроить?

                                                              Просто обнули DCB.Flags и хлопни нужные маски Or. Файл в аттаче. :rolleyes:
                                                              Прикреплённый файлПрикреплённый файлflags_дсв.doc (22 Кбайт, скачиваний: 218)
                                                                чё-то файл не скачивается
                                                                  Цитата medved_68 @
                                                                  Просто обнули DCB.Flags и хлопни нужные маски Or.
                                                                  flags
                                                                  dword fbinary: // режим проверки символа eof - включение данного режима windows
                                                                  // не поддерживает ( по крайней мере сейчас). Маска $01
                                                                  dword fparity: //Контроль четности Маска $02 - включение контроля четности
                                                                  dword foutxctsflow: // Маска $04 - Включение контроля сигнала cts при выводе байтов.
                                                                  dword foutxdsrflow: // Маска $08 - Включение контроля сигнала dsr при выводе байтов.
                                                                  dword fdtrcontrol: // Маска $30 - Тип контроля сигнала dtr: значения
                                                                  dtr_control_disable деактивация сигнала.
                                                                  dtr_control_enable конкретное значение сигнала можно задавать через
                                                                  вызов escapecommfunction.
                                                                  dtr_control_handshake Автоматическое управление сигналом.
                                                                  dword fdsrsensitivity: // Маска $40 - Включение контроля сигнала dsr.
                                                                  dword ftxcontinueonxoff:1; // xoff continues tx
                                                                  dword foutx: // Маска $100. Включение режима работы по xon xoff при передаче
                                                                  dword finx: // Маска $200 -//- при приеме
                                                                  dword ferrorchar: // Маска $400. Разрешение замещения при ошибочном приеме
                                                                  // (несовпадение четности) принятого байта на член структуры errorchar.
                                                                  dword fnull: // Маска $800 enable null stripping - пропускать при приеме символы null
                                                                  dword frtscontrol: // Маска $3000. Тип контроля:
                                                                  rts_control_disable
                                                                  rts_control_enable
                                                                  rts_control_handshake Аналогично сигналу dtr
                                                                  rts_control_toggle - Высокий уровень пока, есть данные для передачи.

                                                                  dword fabortonerror // Маска $4000. Прекращение операций
                                                                  // чтения - записи при возникновении ошибок
                                                                  dword fdummy2:17; // Не используются


                                                                  Это все что он содержит, не знаю почему у тебя не качает <_< Я это взял прям из аттача. :yes:
                                                                  Важные моменты:
                                                                  ExpandedWrap disabled
                                                                    dword foutxctsflow: // Маска $04 - Включение контроля сигнала cts при выводе байтов.
                                                                    dword foutxdsrflow: // Маска $08 - Включение контроля сигнала dsr при выводе байтов.
                                                                    dword fdtrcontrol: // Маска $30 - Тип контроля сигнала dtr: значения
                                                                    dtr_control_handshake Автоматическое управление сигналом.
                                                                    dword frtscontrol: // Маска $3000. Тип контроля:
                                                                    rts_control_handshake Аналогично сигналу dtr
                                                                    dword fabortonerror // Маска $4000. Прекращение операций
                                                                    // чтения - записи при возникновении ошибок
                                                                  Сообщение отредактировано: medved_68 -
                                                                  1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                                                  0 пользователей:


                                                                  Рейтинг@Mail.ru
                                                                  [ Script execution time: 0,1052 ]   [ 15 queries used ]   [ Generated: 18.07.25, 01:11 GMT ]