[Windows] Send sms using gsm modem Delphi/Lazarus
Posted on March 20th, 2009 by admin
In previous post i wrote small description how asynchronously work with com port, in this post i gave small list where we can use it.
Today i wanna explain how to send sms if you have GSM modem connected to Com Port using created class and AT commands.
The simpliest way if your GSM modem support text mode (i think you have spend some time to find modem that aint support text mode).
So to send sms we need:
- Open Com Port where modem plugged in
- Enable Text mode (write to port command “AT+CMGF=1″, if you you will receive error response that means that you modem does not support text mode)
- Send SMS:
- Send command: write to port AT+CMGS=”cell_number” (cell_number = destination number)
- Send sms text: after you send command AT+CMGS=”cell_number” you will receive response “>” then you need to write sms text to port
if you will receive response “OK”, congrats message was sent
here small class on delphi that sends sms (inherited from TThread):
unit SmsSender;
interface
uses
// Windows,
Classes, SysUtils, ComPort, messages, Windows;
const
Steps : array[0..3] of string = (
'ATZ',
'AT+CMGF=',
'>',
'+CMGS');
type
PMessageSet = ^TMessageSet;
TMessageSet = record
Number : string; //without any + symbols (example: 80993294258)
Text : string;
Unicode : boolean; //not implemented in this version
end;
TSmsSender = class(TThread)
private
FTerminate : boolean;
FToSend : TList;
FNextStep : TStringList;
FCurrent : string;
FIndex : Integer;
FComPort : TComPort;
public
Constructor Create(PortBoudRate : Integer; PortIndex : Integer);
Destructor Destroy; override;
Procedure SendSms(messageSet : TMessageSet);
Procedure Stop();
Procedure Execute; override;
end;
implementation
Constructor TSmsSender.Create(PortBoudRate : Integer; PortIndex : Integer);
begin
inherited Create(True);
FComPort := TComPort.Create(PortBoudRate, PortIndex);
Priority := tpNormal;
FreeOnTerminate := false;
FTerminate := false;
FToSend := TList.Create;
FNextStep := TStringList.Create;
FIndex := -1;
FCurrent := '';
if (not FComPort.Open()) then
raise Exception.Create('Cannot open Com Port');
Resume();
end;
Destructor TSmsSender.Destroy;
var
SmsItem : PMessageSet;
begin
while (FToSend.Count > 0) do
begin
SmsItem := FToSend[0];
Dispose(SmsItem);
FToSend.Delete(0);
end;
FToSend.Free;
FComPort.Close();
FComPort.Free;
FNextStep.Clear();
FNextStep.Free;
inherited Destroy;
end;
Procedure TSmsSender.SendSms(messageSet : TMessageSet);
var
SmsItem : PMessageSet;
begin
New(SmsItem);
SmsItem^.Number := messageSet.Number;
SmsItem^.Text := messageSet.Text;
SmsItem^.Unicode := false; //unicode not implemented
FToSend.Add(SmsItem);
end;
Procedure TSmsSender.Execute;
var
res, tmp : string;
x : Integer;
SmsItem : PMessageSet;
begin
res := '';
tmp := '';
while (not FTerminate) do
begin
if ((FToSend.Count = 0) and (FNextStep.Count = 0) and (FCurrent = '')) then
begin
Sleep(200);
end else
begin
tmp := FComPort.Read();
res := res + tmp;
if (res <> '') then
begin
x := Pos(#13#10 + 'OK', res);
if (x > 0) then
begin
if (Pos(FCurrent, res) > 0) then
begin
if (FNextStep.Count > 0) then
begin
Inc(FIndex);
FCurrent := Steps[FIndex];
tmp := FNextStep[0];
FNextStep.Delete(0);
FComPort.Write(tmp);
end else
begin
MessageBox(0, PChar('Message was sent'), PChar('Congratulations'), 0);
FCurrent := '';
FIndex := -1;
end;
end;
res := '';
end else
begin
x := Pos('ERROR', res);
if (x > 0) then
begin
MessageBox(0, PChar('Message was not sent'), PChar('Error'), 0);
FIndex := -1;
FCurrent := '';
res := '';
FNextStep.Clear();
end else
begin
if (Pos('>', res) > 0) then
begin
Inc(FIndex);
FCurrent := Steps[FIndex];
tmp := FNextStep[0];
FNextStep.Delete(0);
FComPort.Write(tmp);
res := '';
end;
end;
end;
end;
end;
if ((FNextStep.Count = 0) and (FCurrent = '') and (FToSend.Count > 0) and (not FTerminate)) then
begin
SmsItem := FToSend[0];
FIndex := 0;
FCurrent := Steps[FIndex];
FNextStep.Add('AT+CMGF=1' + #13#10);
FNextStep.Add('AT+CMGS="' + SmsItem^.Number + '"' + #13#10);
FNextStep.Add(SmsItem^.Text + #26);
Dispose(SmsItem);
FToSend.Delete(0);
FComPort.Write('ATZ' + #13#10);
Sleep(500);
end;
end;
end;
procedure TSmsSender.Stop();
begin
FTerminate := true;
end;
end.
Sources and Test application you can download here
Filed under: Programming
October 18th, 2010 at 10:25 pm
Hello. I tested the unit and is doing very well. Know any unit to receive messages?. Sorry for the English. I’m from Argentina and use the Google translator.
Thanks.
October 18th, 2010 at 10:37 pm
receiving even easier… there just couple AT commands and you receive sms, the problem that i dont use pascal any more… but i can share c# code or c++
October 20th, 2010 at 1:54 am
Hi! You can translate code to receiving SMS to pascal?
best regards.
October 20th, 2010 at 1:24 pm
i can, but i wont
January 8th, 2011 at 11:09 am
can u send me code for received sms?in c# or delphi…send to my email plzzz…thx
April 8th, 2011 at 7:23 pm
Hi,
please, could you help me to encode message with “accentuation” ?
if the message is ENGLISH no problem, but I’m using portuguese and
it’s require some letter with accentuation….
could you help ?
tks
Zemo