Cómo enviar un SMS desde cero ( II )

Continuado con el post anterior aquí tenéis cómo se inicializa el módem.



Para ello he puesto un Botón llamado "Conectar" dentro del Form con el siguiente procedimiento que lo que hace es:
Enviar un ATE0 para quitar el "eco" de los caracteres, después le decimos que queremos enviar un texto AT+CMGF=1,  y por último leemos varios parámetros:

- AT+CSQ (Potencia de la señal), posibles respuestas son:

0 113 dBm or menos
1 111 dBm
2...30 109... 53 dBm
31 51 dBm o más
99 desconocido o no detectable


ComandoPosibles respuestas
+CSQ+CSQ: , +CME ERROR: 
+CSQ=?+CSQ: (list of supporteds),(list of supporteds)

- AT+CMGF: Pone el módem en modo texto (=1)  o en modo PDU (=0), en nuestro caso será en texto.
- AT+CNMI : queremos preguntar al módem cómo serán tratados los nuevos SMS recibidos Su respuesta es: AT+CNMI=,,,,
=1 Descarga los códigos de resultado no solicitados cuando el link TA-TE está reservado.

=1 Devuelve los SMS.

=0 no hay indicaciones CBM para rutar al TE.
=0 no SMS-STATUS-REPORTs son rutados.
=0 El buffer del TA de códigos de resultado no solicitados definidos con este comando son borrados del TE.
- AT+CPMS Almacenamiento preferido del mensaje.
- AT+CSCA  Informa del número del Centro de Servicio


PROCEDURE TForm1.BitBtn1Click(Sender: TObject);
VAR i: integer;
BEGIN
  enviar('ATE0', Rdo, CodigoError);
  IF CodigoError <> 0 THEN
  BEGIN
    showmessage('Se ha producido el error: ' + Rdo)
  END
  ELSE
  BEGIN
    enviar('AT+CMGF=1', rdo, CodigoError);
  END;
  //muestra en un Grid, fila a fila, distintos parámetros del modem
  RellenarGrid(1, 'Calidad de señal', 'AT+CSQ');
  RellenarGrid(2, 'PDU/TEXTO', 'AT+CMGF=?');
  RellenarGrid(3, 'PDU/TEXTO Modo Activo', 'AT+CMGF?');
  RellenarGrid(4, 'CNMI', 'AT+CNMI?');
  RellenarGrid(5, 'CPMS', 'AT+CPMS?');
  //El Centro de Servicio viene dado por el operador de telefonía
  //Es el que se encargar de gestionar los envíos
  RellenarGrid(6, 'Centro de servicio', 'AT+CSCA?');
  Application.processmessages;
  label8.visible := false;
END;

PROCEDURE tform1.RellenarGrid(Fila: integer; Texto, ComandoAT: ansistring);
BEGIN
  Grid2.Cells[0, Fila] := Texto;
  enviar(ComandoAT, Rdo, CodigoError);
  IF CodigoError = 0 THEN
  BEGIN
    IF Ansipos(':', Rdo) > 0 THEN Rdo := Gettoken(Rdo, ':', 2);
    Rdo := stringReplace(Rdo, 'AT+', '', [rfreplaceAll]);
    Rdo := stringReplace(Rdo, OK, '', [rfreplaceAll]);
    Rdo := stringReplace(Rdo, chr(13) + chr(10) + 'OK', '', [rfreplaceAll]);
    Rdo := stringReplace(Rdo, chr(13), '', [rfreplaceAll]);
    Rdo := stringReplace(Rdo, chr(10), '', [rfreplaceAll]);
    Grid2.Cells[1, Fila] := Rdo;
  END
  ELSE Grid2.Cells[1, Fila] := 'Error';
END;

Procedimiento que envía el comando AT al módem

PROCEDURE tform1.enviar(at: ANSISTRING; VAR Rdo: ansistring; VAR CodigoError: integer);
BEGIN
  CodigoError := 0;
  Edit1.TExt := '';
  rdo := '';
  Terminado := False;
  Segundos := 0;
  IF (FStatusTrigger = 0) THEN
  BEGIN
    FStatusTrigger := ApdComPort1.AddStatusTrigger(stLine);
    ApdComPort1.SetStatusTrigger(FStatusTrigger,
      lsOverrun OR lsParity OR lsFraming OR lsBreak,
      True);
  END;
  memo1.Lines.add('>>' + at + chr(13));
  timer1.Enabled := true;
  ApdComPort1.OutPut := at + chr(13);
  REPEAT
    delay(2000)  
  UNTIL Terminado;
END;

Es un objeto tTimer que se encarga de comprobar si el módem ha respondido con un OK o con un ERROR


PROCEDURE TForm1.Timer1Timer(Sender: TObject);
BEGIN
  IF (ansipos(chr(13) + chr(10) + 'OK' + chr(13) + chr(10), Rdo) > 0)
    OR (Segundos > 15)
    OR (ansipos(chr(13) + chr(10) + 'ERROR' + chr(13) + chr(10), Rdo) > 0)
    OR (ansipos(chr(13) + chr(10) + '>', Rdo) > 0)
    THEN
  BEGIN
    IF Segundos > 15 THEN CodigoError := 1; //Timeout
    IF (ansipos(chr(13) + chr(10) + 'ERROR' + chr(13) + chr(10), Rdo) > 0)
      THEN CodigoError := 2; //Se ha producido un error
    terminado := true;
    timer1.Enabled := false;
  END
  ELSE inc(Segundos);

END;


Procedimiento del objeto ApdComPort1 que se dispara para recoger los caracteres del buffer del puerto serie

PROCEDURE TForm1.ApdComPort1TriggerAvail(CP: TObject; Count: Word);
  
VAR
  I: Word;
  C: Char;
  S, s1: STRING;
BEGIN
  FOR I := 1 TO Count DO BEGIN
    C := ApdComPort1.GetChar;
    s1 := c;
    Rdo := Rdo + s1;
  END;

  memo1.lines.add(Rdo);
  IF ansipos(chr(13) + chr(10) + 'OK' + chr(13) + chr(10), Rdo) > 0
    THEN
  BEGIN
    application.processmessages;
    edit1.Text := Rdo;
  END;
END;


Seguiremos con más procedimientos en próximos posts

Relacionados:
Cómo enviar un SMS desde cero ( I )

No hay comentarios:

Publicar un comentario