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

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

Вернуться   Форум программистов > Delphi программирование > Компоненты Delphi
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 03.11.2013, 14:06   #1
qZED
Пользователь
 
Регистрация: 13.05.2009
Сообщений: 26
По умолчанию Принимаем смс. TComPort.

Пишу программу приёма смс через GSM модем (Хуавей 173).
Вот ключевые процедуры:
Код:
procedure TGSMModule.ComPortOnRxChar(Sender: TObject; Count: Integer);
var
  c: char;
  i: Integer;
  Buffer: String;
  PStr: PChar;
begin
  SetLength(Buffer, Count);
  (Sender as TComport).ReadStr(buffer, Count);
  { process received data }
  for i := 1 to Length(Buffer) do
  begin
    c := Buffer[i];
    case c of
      #00:;
      #10:;
      #13:
        begin
          if Length(Trim(FMessageBuf)) > 0 then
          begin
            PStr := StrNew(PChar(FMessageBuf));
            PostMessage(frmMain.Handle, WM_HANDLEMESSAGE, Integer(PStr), IdGSMModule);
          end;
          FMessageBuf := '';
        end;
      else
      begin
        FMessageBuf := FMessageBuf + c;
      end;
    end;
    if (FMessageBuf = 'OK') and (FMessageBuf <> '') then
    begin
      PStr := StrNew(PChar(FMessageBuf));
      PostMessage(frmMain.Handle, WM_HANDLEMESSAGE, Integer(PStr), IdGSMModule);
      FMessageBuf := '';
    end;
  end;
end;

procedure TfrmMain.HandleMessage(var Msg: TOptionsHandleMessage);
var
  sMsg : string;
  IdGSMModule : Integer;
begin
  sMsg := Msg.Message;
  IdGSMModule := Msg.Length;
  StrDispose(Msg.Message);
  WriteLog(GSMModule[IdGSMModule].GSMModuleName, '[Rx] ' + sMsg);
  if GSMModule[IdGSMModule].CMD_Previous = '+CBM' then
  begin
    GSMModule[IdGSMModule].CMD_Previous := '';
  end
  else if Pos('+CBM', sMsg) > 0 then
  begin
      GSMModule[IdGSMModule].CMD_Previous := '+CBM';
  end
  else if Pos('^RSSI', sMsg) > 0 then
  begin
      //^RSSI:12
      GSMModule[IdGSMModule].CMD_RSSI := copy(sMsg, 7,2);
  end
  else if pos('^ORIG', sMsg) = 1 then
  begin
  end
  else if Pos('+CREG', sMsg) > 0 then
  begin

  end
  else if Pos('+CGREG', sMsg) > 0 then
  begin

  end
  else if Pos('^BOOT', sMsg) > 0 then
  begin

  end
  else if Pos('^MODE', sMsg) > 0 then
  begin

  end
  else if Pos('^SMMEMFULL', sMsg) = 1 then
  begin
    HandleSMMEMFULL(IdGSMModule, sMsg);
  end
  else if Pos('+CMTI', sMsg) = 1 then
  begin
    HandleCMTI(IdGSMModule, sMsg);
  end
  else if Pos('+CLIP', sMsg) = 1 then
  begin
    HandleCLIP(IdGSMModule, sMsg);
  end
  else if Pos('^CEND', sMsg) = 1 then
  begin
    HandleCEND(idGSMModule, sMsg);
  end
  else if Pos('^CONN', sMsg) = 1 then
  begin
    HandleCONN(idGSMModule, sMsg);
  end
  else if Pos('+COPS', sMsg) = 1 then
  begin
    HandleCOPS(idGSMModule, sMsg);
  end
  else if Pos('+CSCA', sMsg) = 1 then
  begin
    HandleCSCA(idGSMModule, sMsg);
  end
  else if Pos('^CVOICE', sMsg) = 1 then
  begin
    HandleCVOICE(idGSMModule, sMsg);
  end
  else if Pos('+CUSD', sMsg) = 1 then
  begin
    HandleCUSD(idGSMModule, sMsg);
  end
  else
  begin
    if GSMModule[IdGSMModule].FRxBuffer <> nil then
     GSMModule[IdGSMModule].FRxBuffer.Add(sMsg);
  end;
  GSMModule[IdGSMModule].FReceived := (CompareText('OK', sMsg) = 0) or (CompareText('ERROR', sMsg) = 0) or (CompareText('COMMAND NOT SUPPORT', sMsg) = 0);
  inherited;
end;
Проблема возникает следующая (привожу лог):
10:45:49 Downloading read messages
10:45:49 [Tx]AT+CPMS="SM"
10:45:49 [Rx] +CPMS: 5,5,5,5,5,5
10:45:49 [Rx] OK
10:45:49 [Tx]AT+CMGL=1
10:45:49 [Rx] OK
10:45:49 [Tx]AT+CPMS="ME"
10:45:49 [Rx] +CPMS: 0,23,5,5,5,5
10:45:49 [Rx] OK
10:45:49 [Rx] ^MODE:3,3
10:45:54 Timeout. Команда:AT+CPMS="ME"
Получается как я понимаю следующее: Послал я модему команду: AT+CPMS="ME". И тут что то пошло не так - и вышел тайм аут.
Код:
procedure TGSMModule.TxAndWait(Data: string);
var
  FMSec: Cardinal;
begin
  FReceived := False;
  FMessageBuf := '';
  FRxBuffer.Clear;
  if Not Connected then
  begin
    WriteLog(GSMModuleName, 'Модем не доступен. Порт: ' + Port);
    Exit;
  end;
  WriteLog(GSMModuleName, '[Tx]' + Data);
  { Send command }
  WriteStr(Data + #13); // Serial
  { Set timeout, max 5 seconds }
  FMSec := 5000;
  //if FMSec > 5000 then FMSec := 5000;
  FMSec := GetTickCount + FMSec;
  { Wait for response }
  while not FReceived and not Application.Terminated do
  begin
    WaitASec(10, True);
    if GetTickCount > FMSec then
      WriteLog(GSMModuleName, 'Timeout. Команда:' + Data);
      //raise EInOutError.Create('Timeout');
  end;
  if FReceived and (CompareText('ERROR',FRxBuffer[0]) = 0) then
    WriteLog(GSMModuleName, 'AT Error. Команда:' + Data);
    //raise EInOutError.Create('AT Error');
end;
TxAndWait('AT+CPMS="ME"');
TxAndWait('AT+CMGL=' + IntToStr(msgType));

Помогите разобраться с проблемой.
ПС: Свойства TComPort
SyncMethod := smWindowSync;
BaudRate := br115200;
Events := [evRxChar];

Последний раз редактировалось qZED; 04.11.2013 в 08:40.
qZED вне форума Ответить с цитированием
Старый 03.11.2013, 20:42   #2
raxp
Старожил
 
Регистрация: 29.09.2009
Сообщений: 9,713
По умолчанию

Цитата:
TxAndWait('AT+CPMS="ME"');
...а ежели данного типа Memory Storage нету? Неразумно так выгребать. Если нужно последнее, то достаточно AT+CMGR=Number или +CMGL=номер сообщения.

Параметр 'ME' в Memory Storage есть для телефонов Nokia, и то не гарантия. У вас данный телефон? А ежели реальный GSM-терминал, то вообще зачем.
Разработки и научно-технические публикации :: Видеоблог :: Твиттер
Radar systems engineer & Software developer of industrial automation
raxp вне форума Ответить с цитированием
Старый 03.11.2013, 21:03   #3
qZED
Пользователь
 
Регистрация: 13.05.2009
Сообщений: 26
По умолчанию

Модем же отвечает:
10:45:49 [Tx]AT+CPMS="ME"
10:45:49 [Rx] +CPMS: 0,23,5,5,5,5
10:45:49 [Rx] OK

Просто вот сейчас проанализировав логи - вижу что приходит смс, а программа ждала "ОК"
Вот здесь что то не так: HandleMessage. В TxAndWait я ожидаю ОК, а HandleMessage - приходят команды.
Кстати не подскажите что за команда от модема: ^BOOT ?

Вроде бы исправил, тайм ауты исчезли (10 минут полет нормальный)
Код:
 begin
    if GSMModule[IdGSMModule].FRxBuffer <> nil then
     GSMModule[IdGSMModule].FRxBuffer.Add(sMsg);
     GSMModule[IdGSMModule].FReceived := (CompareText('OK', sMsg) = 0) or (CompareText('ERROR', sMsg) = 0) or (CompareText('COMMAND NOT SUPPORT', sMsg) = 0);
  end;

Последний раз редактировалось qZED; 03.11.2013 в 21:07.
qZED вне форума Ответить с цитированием
Старый 03.11.2013, 21:13   #4
raxp
Старожил
 
Регистрация: 29.09.2009
Сообщений: 9,713
По умолчанию

...без понятия. Надо смотреть доки, а топик-стартер запамятовал видно, что название модема с доками у него есть, а в теме не обмолвился

Новые команды следует отсылать по выполнению предыдущих команд, для этого должен быть буфер для них.
Разработки и научно-технические публикации :: Видеоблог :: Твиттер
Radar systems engineer & Software developer of industrial automation
raxp вне форума Ответить с цитированием
Старый 03.12.2014, 10:04   #5
BraveSaw
Новичок
Джуниор
 
Регистрация: 03.12.2014
Сообщений: 2
Сообщение

Цитата:
Сообщение от raxp Посмотреть сообщение
...без понятия. Надо смотреть доки, а топик-стартер запамятовал видно, что название модема с доками у него есть, а в теме не обмолвился

Новые команды следует отсылать по выполнению предыдущих команд, для этого должен быть буфер для них.
Please i need to get the Download link for this example + source code if you don't mind of course ...
this is my Email :BraveSofts13@Gmail.com

Последний раз редактировалось BraveSaw; 03.12.2014 в 10:07.
BraveSaw вне форума Ответить с цитированием
Старый 03.12.2014, 14:08   #6
BraveSaw
Новичок
Джуниор
 
Регистрация: 03.12.2014
Сообщений: 2
По умолчанию

hello There :
-2 down vote favorite


i'm using delphi with TComport and i want to Enum just the Present Modems that Having a Gsm Card and Auto detect them(Modems) by thier card sim Operator,and attach one by one To My TComports that i have(Exactlly i have 3 Phones with 3 Different SP Card Sim), i have Make this Example and i would like to share it for all : [SourceCode here]<https://www.dropbox.com/s/zochzfi6kbsgujx/Auto%20Detecting%20Modems%20By%20th ier%20Card%20sim%20Operator.rar?dl= 0> and the link for the required libraries wich this Example is using them is [Required to Compile]<https://www.dropbox.com/s/gsrxl7ujk6fx841/Required%20library.zip?dl=0>because i can't Past all the Source Code but if you Download this Example please Reply me Here i want to Correct the Loop of MyTimer To Make the Comport Reading all Present Modems One by One,this the Functions i use:
procedure TFrmAutoDetect.ComPortDetectiveCTSC hange(Sender: TObject; OnOff: Boolean);
begin
CTsLabel.Caption:='event:OnCtsChang e: State: '+BoolToStr(OnOff,true)
end;
procedure TFrmAutoDetect.TimerDetectCardSimOp eratorsTimer(Sender: TObject);
var
I: Integer;
begin
with ComPortDetective do
for i:=0 to lvDevices.Items.Count-1 do
begin
if Not Connected then
begin
Port := 'COM'+lvDevices.Items[I].SubItems.Strings[1];
Connected:=True;
WriteStr('ATE1'+#13#10);
WriteStr('ATE1+CSCA?'+#13#10);
TimerMobilisFind.Enabled:=true;
end;
end;
end;
best regards : brave

Последний раз редактировалось BraveSaw; 03.12.2014 в 14:10. Причина: Add Url
BraveSaw вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
ComPort: TComPort - ошибка при LoadSettings StudentProg Общие вопросы Delphi 8 17.05.2012 22:56
TComPort NewMember Компоненты Delphi 11 31.03.2012 09:32
Delphi 2009 - проблема с установкой компонента TComPort cadil Компоненты Delphi 8 05.09.2010 03:27
RS232, Библиотека Игоря Павлова TComPort xBugiman Компоненты Delphi 11 12.06.2010 13:41
Delphi 2009: проблема с работой компоненты TComPort cadil Компоненты Delphi 10 01.04.2010 10:55