Utilizamos cookies propias y de terceros. [Más información sobre las cookies].
Política de cookies
Proyecto AjpdSoft

· Inicio
· Buscar
· Contactar
· Cookies
· Descargas
· Foros
· Historia
· Nosotros
· Temas
· Top 10
· Trucos
· Tutoriales
· Wiki

Redes: Cómo enviar SMS desde un PC usando un módem GSM con Visual Basic .Net
Visual Studio .NET


Explicamos paso a paso cómo desarrollar una aplicación informática para enviar un SMS (mensaje de texto por móvil) usando como lenguaje de programación Microsoft Visual Bascic .Net 2010, el componente SerialPort y un módem GSM conectado al PC mediante puerto serie (COM). Mostramos cómo enviar comandos AT (Hayes) y cómo obtener la respuesta del módem.



 

Conjunto de comandos Hayes, Comandos AT

El conjunto de comandos Hayes es un lenguaje desarrollado por la compañía Hayes Communications que prácticamente se convirtió en estándar abierto de comandos para configurar y parametrizar módems. Los caracteres "AT", que preceden a todos los comandos, significan "Atención", e hicieron que se conociera también a este conjunto de comandos como comandos AT. Midiendo la longitud de los bits se puede determinar en detalle la velocidad de transmisión.

Un aparato que implemente el conjunto de comandos Hayes se considera compatible Hayes. Parte del conjunto de comandos Hayes fue incluido por la ITU-T en el protocolo V.25ter, actual V.250. La adopción de este estándar hizo el desarrollo de controladores específicos para distintos módems.

A partir de la versión 3.x de Microsoft Windows el sistema operativo contaba con una implementación de controlador para módems compatibles con Hayes. Sin embargo, a partir de Microsoft Windows 95 se desarrollaron controladores específicos para cada módem, así que la compatibilidad con Hayes dejó de ser importante y por esta razón cada vez menos módems la implementaron. Esto dificultó su uso en otros sistemas operativos, pues no resulta frecuente que haya controladores disponibles.

La mayoría de los módems se controlan y responden a caracteres enviados a través del puerto serie. Estos comandos u órdenes hacen posible que el software de comunicación pueda comunicarse con el módem. El lenguaje más extendido de comandos para módems es el de los comandos Hayes o AT.

Los comandos Hayes se dividen en dos grandes tipos:

  1. De ejecución de acciones inmediatas: ATD marcación, ATA contestación, ATH desconexión, ...
  2. De configuración de algún parámetro del módem: ATV define cómo responde el módem tras la ejecución de un parámetro, ATE selecciona el eco local, ...

Como ya hemos comentado, la mayoría de los comandos Hayes empieza con la secuencia “AT”, con la excepción del comando “A/” que repite el último comando introducido y también la secuencia triple del carácter de escape. El resto de los comandos van a continuación de la secuencia AT, con las letras del alfabeto. Además, muchos de ellos necesitan a continuación un valor numérico, que en el caso de que no se introduzca se tomará como que dicho valor es cero. Por ejemplo, la función “ECO” permite que el módem envíe a la terminal el mismo carácter que recibe de ella. De esta forma el operador de la terminal puede visualizar en pantalla lo que le está enviando al módem. La secuencia ATE1 activa esta función y la ATE0 ó ATE (al no escribir el valor numérico el módem lo toma como que es cero) la desactiva.

A media que se fueron requiriendo más funciones en los módems se fueron agregando nuevos comandos AT. A estos comandos se los llama extendidos y tienen la forma AT&X donde “&” indica que el comando X es extendido. Así mismo cada fabricante introdujo otros comandos que no fueron estándares y cumplían funciones específicas para sus dispositivos.  Por lo tanto no todos los módems responden a estos comandos. En resumen, a los comandos Hayes se los puede dividir en 4 grupos:

  1. Básicos (AT...): estos comandos fueron los que inicialmente se definieron y cumplen funciones elementales.
  2. De registro (ATSi=, ó ATSi?): modifican los valores de los registros internos del módem ó solicitan sus valores.
  3. Extendidos (AT&...): comandos adicionales que se agregaron posteriormente a las definiciones de los comandos básicos. Generalmente cumplen funciones un poco más complejas que los básicos.
  4. Propietarios (AT/...): definidos por el fabricante del dispositivo.

Ante cualquier comando AT enviado al módem, éste responde con el resultado de la operación: “OK”, “ERROR”, CONNECT, etc. El operador de la terminal puede elegir que el resultado, en vez de aparecer en forma alfabética, aparezca de forma numérica donde cada número corresponde a una respuesta en particular. Por ejemplo “OK” tiene por valor cero. El comando para elegir la forma de la respuesta es ATV donde ATV1 activa la respuesta alfabética  y ATV0 la numérica.  Esta última forma es útil cuando es un programa y no un usuario el que está comunicándose con el módem y necesita de un valor numérico para comparar y tomar una acción determinada según el resultado.

Algunos comandos Hayes ó AT y su significado, normalmente usados en módem GSM con tarjeta SIM para envío y recepción de SMS:

  • AT: devuelve "OK" si se ha encontrado un módem en el puerto establecido.
  • AT+CREG?: devuelve un valor que indica si el módem GSM tiene activa la red de telefonía. Si tiene red devolverá 0,1.
  • AT+CSQ: devuelve un valor que indica la intensidad de la señal en el dispositivo GSM, el máximo es 31,99.
  • AT+CGSN: devuelve el ID del dispositivo (IMEI).
  • AT+CMGF=1: activa el módem para modo de SMS de formato texto.
  • AT+CMGS="numero_telefono": establece el número de teléfono al que se enviará el SMS.
  • AT+CPIN=PIN: establece el PIN para la tarjeta SIM conectada al módem GSM.
  • AT+COPS=?: muestra las redes disponibles para la tarjeta SIM del módem GSM.
  • AT+CGMI: devuelve el fabricante del módem GSM o teléfono móvil.
  • AT+CGMM: devuelve el modelo del módem GSM o teléfono móvil.
  • AT+CGMR: devuelve la versión de la revisión del dispositivo.
  • AT+CPAS: devuelve el estado del módem, las posibilidades son:
    • 0 Ready.
    • 1 Unavailable.
    • 2 Status unknown.
    • 3 Ringing.
    • 4 Call in progress.
    • 5 Asleep.
  • AT+CPBR=1,10: devuelve las diez primeras entradas del la agenda de contactos de la tarjeta SIM (devuelve el número de teléfono y el nombre del contacto).

 

GSM (Sistema global para las comunicaciones móviles)

El sistema global para las comunicaciones móviles (GSM, del francés Groupe Spécial Mobile) es un sistema estándar, libre de regalías, de telefonía móvil digital.

Un cliente GSM puede conectarse a través de su teléfono con su computador y enviar y recibir mensajes por correo electrónico, faxes, navegar por Internet, acceder con seguridad a la red informática de una compañía (red local/Intranet), así como utilizar otras funciones digitales de transmisión de datos, incluyendo el servicio de mensajes cortos (SMS) o mensajes de texto.

GSM se considera, por su velocidad de transmisión y otras características, un estándar de segunda generación (2G). Su extensión a 3G se denomina UMTS y difiere en su mayor velocidad de transmisión, el uso de una arquitectura de red ligeramente distinta y sobre todo en el empleo de diferentes protocolos de radio (W-CDMA).

Una de las características principales del estándar GSM es el módulo de identidad del suscriptor, conocida comúnmente como tarjeta SIM. La tarjeta SIM es una tarjeta inteligente desmontable que contiene la información de suscripción del usuario, parámetros de red y directorio telefónico. Esto permite al usuario mantener su información después de cambiar su teléfono. Paralelamente, el usuario también puede cambiar de operador de telefonía, manteniendo el mismo equipo simplemente cambiando la tarjeta SIM. Algunos operadores introducen un bloqueo para que el teléfono utilice un solo tipo de tarjeta SIM, o sólo una tarjeta SIM emitida por la compañía donde se compró el teléfono, esta práctica se conoce como bloqueo de sim, y es ilegal en algunos países.

 

SMS (Short Message Service ó Servicio de mensajes cortos)

El servicio de mensajes cortos o SMS (Short Message Service) es un servicio disponible en los teléfonos móviles que permite el envío de mensajes cortos (también conocidos como mensajes de texto) entre teléfonos móviles, teléfonos fijos y otros dispositivos de telefonía. SMS fue diseñado originariamente como parte del estándar de telefonía móvil digital GSM, pero en la actualidad está disponible en una amplia variedad de redes, incluyendo las redes 3G.

Un mensaje SMS es una cadena alfanumérica de hasta 140 caracteres o de 160 caracteres de 7 bits, y cuyo encapsulado incluye una serie de parámetros. En principio, se emplean para enviar y recibir mensajes de texto normal, pero existen extensiones del protocolo básico que permiten incluir otros tipos de contenido, dar formato a los mensajes o encadenar varios mensajes de texto para permitir mayor longitud .

En GSM existen varios tipos de mensajes de texto: mensajes de texto "puros", mensajes de configuración (que contienen los parámetros de conexión para otros servicios, como WAP o MMS), mensajes WAP Push, notificaciones de mensajes MMS...

Existen otros estándares diferentes de GSM, como CDMA2000 o UMTS, en estos el proceso de codificación de los mensajes se realiza de otra forma, pero el funcionamiento es transparente de cara al usuario.

En un principio, los mensajes SMS se definieron en el estándar GSM como un medio para que los operadores de red enviaran información sobre el servicio a los abonados, sin que éstos pudieran responder ni enviar mensajes a otros clientes. Este tipo de mensajes se denominaban MT-SM (Mobile Terminated-Short Message ó mensajes que llegan al terminal del usuario). Sin embargo, la empresa Nokia desarrolló un sistema para permitir la comunicación bidireccional por SMS; los mensajes enviados por los usuarios pasaron a denominarse MO-SM (Mobile Originated, originados en el terminal del usuario).

Los mensajes de texto son procesados por un SMSC o centro de mensajes cortos (Short Message Service Center) que se encarga de almacenarlos hasta que son enviados y de conectar con el resto de elementos de la red GSM.

Para la correcta gestión de los mensajes SMS se hace necesario introducir en el sistema GSM un elemento: el centro de mensajes cortos o SMSC (Short Message Service Center.) Las funciones del SMSC son:

  • Recibir y almacenar los mensajes cortos enviados por los usuarios (MO-SM) o por otras fuentes (avisos del operador, buzón de voz, sistemas de publicidad, alertas de correo electrónico...) hasta que puedan ser enviados.
  • Verificar los permisos para enviar mensajes, en comunicación con el HLR de origen.
  • Verificar si el usuario al que se envía el mensaje está operativo o no, mediante consulta al VLR de destino; si está operativo, el mensaje se envía, y si no se almacena temporalmente en el SMSC.
  • Verificar periódicamente el estado de los usuarios que tienen mensajes pendientes.

Cuando un usuario de la red genera un mensaje corto (MO-SM) se producen los siguientes acontecimientos:

  • El HLR donde está registrado el usuario decide si puede o no enviar mensajes, si todo es correcto.
  • El MSC al que está conectado el usuario recibe el mensaje, envía la información necesaria al VLR para su posterior tarificación y después lo remite al SMSC de origen.
  • El SMSC de origen envía el mensaje al SMSC de destino. Una vez allí, se convierte en MT-SM y se procesa como veremos a continuación.
  • El SMSC de destino informa del estado del mensaje y devuelve un informe de recepción al MSC y al usuario. En la pantalla del usuario se advierte: “mensaje enviado”.
  • Si el usuario lo ha solicitado, recibirá posteriormente un mensaje de estado confirmándole si el usuario de destino ha recibido el mensaje o no, y un mensaje de error en caso de que caduque.

Una vez hay un mensaje preparado para su envío en el SMSC de destino, originado por un usuario o por cualquier otra circunstancia, se le denomina MT-SM y el proceso de entrega es el siguiente:

  • El SMSC que ha recibido el mensaje lo almacena en su base de datos y solicita al VLR del usuario la información de localización;
  • Si el usuario destino está disponible, el SMSC envía al MSC el mensaje, indicando en qué parte del BSS debe ser entregado; si no lo está, se almacena en el SMSC durante su periodo de vigencia.
  • Si el usuario destino está disponible, el MSC envía un aviso al VLR al que está conectado el usuario destino (que puede ser o no de su operador) para indicarle que va a entregarse un mensaje.
  • El VLR avisa al terminal del usuario y verifica si está conectado a la red (en zona de cobertura).
  • El VLR responde al MSC con el estado del usuario y, si está operativo, con la información de localización (parte del BSS en que se encuentra conectado).
  • El MSC envía el mensaje al usuario.
  • El MSC informa al SMSC de que el mensaje se ha entregado y puede ser borrado de su base de datos.
  • Opcionalmente, el SMSC de destino responde a quien originó el mensaje (normalmente, el SMSC origen) con un aviso de entrega del mensaje.

 

Requisitos para dotar a nuestras aplicaciones de la opción de envío de SMS desde el PC con módem GSM

Vamos a explicar lo que se necesita, los requisitos para añadir la opción de envío de SMS en nuestras aplicaciones, para notificación a determinados usuarios mediante un SMS cuando sucede algún evento. Por ejemplo, si estamos desarrollando una aplicación para control de la flota de camiones de una empresa de Transportes (viajes, portes, reportes, etc.), mediante esta utilidad podríamos añadir la opción de envío de SMS a un camionero desde nuestra aplicación con los datos del porte que ha de realizar. Por supuesto, existen multitud de utilidades para esta característica de envío de SMS.

Los requisitos son:

  • Equipo informático con puerto serie, en caso de no tenerlo se podrá usar un adaptador de USB a Serie, pero es recomendable un equipo con puerto serie (COM) pues los adaptadores pueden no funcionar adecuadamente.
  • Sistema operativo: usaremos un equipo informático con sistema operativo Micrsoft Windows 7, aunque este método es válido para cualquier sistema operativo de Microsoft.
  • Módem GSM, en nuestro caso usaremos un CellRoute GSM de Telecom FM. Estos dispositivos van conectados al PC mediante el puerto serie (también los hay con conexión al puerto USB).
  • Tarjeta SIM de móvil con línea activa y servicio de envío de SMS activo, esta tarjeta irá introducida en el módem GSM.
  • IDE de desarrollo: en nuestro caso usaremos Microsoft Visual Basic .net del paquete Microsoft Visual Studio .Net 2010.

En la siguiente imagen mostramos un módem GSM conectado al PC mediante un adaptador USB-Serie:

Requisitos para dotar a nuestras aplicaciones de la opción de envío de SMS desde el PC con módem GSM

La tarjeta SIM insertada en el módem GSM:

Requisitos para dotar a nuestras aplicaciones de la opción de envío de SMS desde el PC con módem GSM

 

Métodos para obtener los resultados devueltos por el puerto serie

Método simple

Para leer los datos devueltos por el puerto serie directamente, hacemos referencia a la lectura de datos programada, es decir que se ejecuta el método de lectura del objeto justo en el momento en que deseamos recibir los datos. Por ejemplo:

StrRead = objeto.Read  
IntRead = objeto.ReadByte  
IntRead = objeto.ReadChar  
StrRead = objeto.ReadExisting  
StrLineRead = objeto.ReadLine

Es posible utilizar cualquiera de estos métodos de acuerdo a las necesidades o al tipo de dato que se espera recibir; en el ejemplo, en las tres primeras letras se indica el tipo de datos a leer. Generalmente este método se aplica a ocasiones en que enviamos datos a un dispositivo y luego esperamos una respuesta. Por ejemplo:

serialPort.WriteLine(tstxtSend) 'Se Envia el dato.  
serialPort.ReadExisting() 'Lee la respuesta.

Método Complejo

A menudo estamos interactuando con dispositivos que pueden no requerir una trasmisión de datos en ambos sentidos o que pueden genera información de una manera espontánea. Es entonces donde entra en juego el evento DataReceived, el cual se dispara en el mismo momento en que se detecta la llegada de datos al puerto previamente abierto. Este evento se dispara en un hilo o Thread separado; se pueden manipular los datos en ese hilo de modo separado, como por ejemplo enviarlos a una base de datos. Pero muchas veces se necesita pasar esta información al hilo principal para desplegar estos datos en algún objeto del formulario; en este caso necesitaremos utilizar un delegado para invocar un método dentro del hilo principal que contiene la Interfaz de Usuario:

Delegate Sub WriteDataDelegate(ByVal str As String)

En el siguiente código se muestra el procedimiento utilizado por el evento:

Private Sub serialPort_DataReceived(ByVal sender As Object, ByVal e As   
    System.IO.Ports.SerialDataReceivedEventArgs) _  
    Handles serialPort.DataReceived     
  Dim strData As String = serialPort.ReadExisting     
  Dim WriteInvoke As New _  
      WriteDataDelegate(AddressOf Me.WriteData)     
  Me.Invoke(WriteInvoke, strData)  
End Sub

Si observamos el código, encontraremos que al dispararse el evento DataReceived lo primero que hacemos es obtener los datos provenientes del disposivo conectado al puerto ya abierto, en este ejemplo se utiliza ReadExisting. Una vez obtenidos los datos provenientes del puerto, procedemos a instanciar el procedimiento WriteData a través del delegado WriteDataDelegate. Finalmente invocamos el procedimiento previamente instanciado pasando los datos capturados desde el puerto serie. Dentro del procedimiento WriteData colocamos el siguiente código:

Private Sub WriteData(ByVal str As String) 
  txtConsole.AppendText(str)  
End Sub 

La razón de que el evento se dispare en hilo separado ofrece sus ventajas y desventajas de acuerdo a la cantidad de información a recibir y del procesamiento de esta información. Debido a que el Framework utiliza ciertos recursos del sistema para manejar los hilos, sería conveniente no utilizar el evento DataReceived a menos que la situación lo requiera.

Sin embargo, este mismo evento nos da una ventaja enorme cuando, por ejemplo, se recibe una cadena de texto que debe ser analizada, procesada y finalmente almacenada en una base de datos, porque todo este proceso es realizado en hilos separados de la interfaz de usuario.

Hay que mencionar que si usamos el evento DataReceived de un componente SerialPort agregado a un formulario de nuestra aplicación, como en el ejemplo de más abajo, no será necesario usar un delegado para acceder a los componentes del formulario.

 

 

Desarrollar aplicación en Visual Basic .Net para envío de SMS mediante puerto serie y módem GSM

Una vez adquirida la correspondiente licencia e instalado Microsoft Visual Bascic .net (o bien si usamos la versión Trial limitada en el tiempo) abriremos Visual Basic .Net, pulsaremos en el menú "Archivo" - "Nuevo Proyecto", seleccionaremos en "Plantillas instaladas" la opción "Visual Basic" - "Windows", en la parte derecha seleccionaremos "Aplicación de Windows Forms". En "Nombre" estableceremos el nombre del proyecto, por ejemplo "AjpdSoftEnvioSMS". En el desplegable de la versión de .NET Framework seleccionaremos ".NET Framework 4" (aunque los componentes que usaremos pueden funcionar con versiones inferiores):

Desarrollar aplicación en Visual Basic .Net para envío de SMS mediante puerto serie y módem GSM

En el formulario (ventana) principal de nuestra aplicación AjpdSoft Envío SMS colocaremos los siguientes componentes, indicamos los más importantes:

  • System.Windows.Forms.ComboBox: varios desplegables para seleccionar el puerto serie del equipo y otros datos de configuración.
  • System.Windows.Forms.TextBox: varios cuadros de texto para solicitar el PIN, para introducir comandos AT personalizados, para introducir el número de teléfono y para introducir el texto del mensaje SMS que se enviará.
  • System.Windows.Forms.Button: varios botones para obtener los puertos serie del equipo, para conectar con el módem GSM conectado al puerto serie, para establecer el PIN de la tarjeta SIM, para enviar un comando AT personalizado, para enviar un SMS mediante el módem GSM y el puerto serie.
  • System.Windows.Forms.StatusStrip: barra de estado de la aplicación donde mostraremos la información más importante (intensidad de la señal del módem GSM, ID del dispositivo, estado de la red móvil, estado del módem GSM, etc.
  • System.IO.Ports.SerialPort: componente más importante que usaremos para conectar nuestro equipo informático (PC) con el módem GSM mediante el puerto serie. Este componente será el encargado de establecer la conexión con el módem, de enviar los comandos AT necesarios y de obtener el resultado de la ejecución de cada comando AT.

En las siguientes imagenes mostramos cómo ubicar los componentes anteriores en la ventana principal de nuestra aplicación para envío de SMS mediante módem GSM:

  • En la ventana principal, añadimos un TabControl con tres pestañas, para los componentes de "Envío de SMS", de "Envío de comando AT personalizado" y de "Configuración del puerto serie y el módem GSM":

Desarrollar aplicación en Visual Basic .Net para envío de SMS mediante puerto serie y módem GSM

  • En la pestaña "Enviar comando AT" colocaremos el TextBox para introducir el comando AT personalizado y un Button para enviar el comando:

Desarrollar aplicación en Visual Basic .Net para envío de SMS mediante puerto serie y módem GSM

  • En la pestaña "Configuración puerto y módem GSM" introduciremos los componentes necesarios para personalizar los parámetros de conexión (bits por segundo, paridad, control de flujo, bits de datos, bits de parada, buffer de lectura, buffer de escritura, tiempo de espera, puerto serie, PIN):

Desarrollar aplicación en Visual Basic .Net para envío de SMS mediante puerto serie y módem GSM

Indicamos a continuación el código fuente Visual Basic .Net más importante de la aplicación:

  • El botón que obtendrá los puertos serie del equipo (btObtenerPuertos):
    Private Sub btObtenerPuertos_Click(sender As System.Object,
                  e As System.EventArgs) Handles btObtenerPuertos.Click
        Dim puertosSerie As List(Of String)
        Dim i As Integer

        txtPuerto.Items.Clear()

        puertosSerie = obtenerPuertosSeriePC()
        For i = 0 To puertosSerie.Count - 1
            txtPuerto.Items.Add(puertosSerie(i).ToString)
        Next

        If txtPuerto.Items.Count >= 1 Then
            txtPuerto.Text = txtPuerto.Items(0)
        Else
            txtPuerto.Text = ""
        End If

        If puertosSerie.Count = 0 Then
            MsgBox("No se han detectado puertos serie en su equipo, " +
                   "asegúrese de que están correctamente configurados.",
                   MsgBoxStyle.Information + MsgBoxStyle.OkOnly)
        End If
    End Sub
 

  • El código de la función obtenerPuertosSeriePC usada por el botón anterior será:
    'Obtener los puertos Serie (COM) disponibles en el PC
    Function obtenerPuertosSeriePC() As List(Of String)
        Dim puertosSerie As List(Of String)

        puertosSerie = New List(Of String)
        Try
            puertosSerie = New List(Of String)
            For Each puertosSerieObtenidos As String
                        In My.Computer.Ports.SerialPortNames
                puertosSerie.Add(puertosSerieObtenidos)
            Next
            obtenerPuertosSeriePC = puertosSerie
        Catch ex As Exception
            MsgBox(ex.Message, MsgBoxStyle.Critical +
                   MsgBoxStyle.OkOnly)
            obtenerPuertosSeriePC = puertosSerie
        End Try
    End Function

 

  • Para establecer los valores de conexión al puerto serie por defecto (btDefecto):
    Private Sub btDefecto_Click(sender As System.Object,
               e As System.EventArgs) Handles btDefecto.Click
        lsBitPorSegundo.Text = "9600"
        lsBitDatos.Text = "8"
        lsParidad.Text = "Ninguno"
        lsBitsParada.Text = "1"
        lsControlFlujo.Text = "Ninguno"
        txtTamanoBufferLectura.Text = "1024"
        txtTamanoBufferEscritura.Text = "1024"
        txtTiempoEspera.Text = "500"
    End Sub
  • Para conectar con el puerto serie y obtener los datos básicos del módem GSM y la tarjeta SIM (cobertura ó intensidad de la señal, ID de dispositivo (IMEI), disponibilidad de módem en puerto indicado, disponibilidad de red móvil para enviar SMS en tarjeta SIM de módem GSM) (btConectar):
    Private Sub btConectar_Click(sender As System.Object,
                  e As System.EventArgs) Handles btConectar.Click
        Dim posBusqueda As Integer
        Dim resultadoDevuelto As String

        Try
            If btConectar.Text = "Conectar" Then
                If txtPuerto.Text = "" Or
                        txtTamanoBufferEscritura.Text = "" Or
                        txtTamanoBufferLectura.Text = "" Or
                        txtTiempoEspera.Text = "" Or
                        lsBitDatos.Text = "" Or
                        lsBitPorSegundo.Text = "" Or
                        lsBitsParada.Text = "" Or
                        lsControlFlujo.Text = "" Or
                        lsParidad.Text = "" Then
                    MsgBox("Antes de conectar con el puerto serie " &
                           "debe introducir los datos " &
                            "de conexión con el módem GSM y la tarjeta SIM.",
                            MsgBoxStyle.Information + MsgBoxStyle.OkOnly)
                Else
                    abrirPuertoSerie(txtPuerto.Text)

                    'Comprobar si hay un módem GSM conectado al puerto serie
                    compPuertoSerie.Write("AT" & Chr(13))
                    'Esperamos un segundo para dar tiempo a 
                    'las comunicaciones serie
                    System.Threading.Thread.Sleep(1000)
                    'Si el comando AT devuelve OK es que hay módem GSM
                    If compPuertoSerie.ReadExisting().IndexOf("OK") Then
                        bePModem.Text = "Módem GSM activo"
                        bePModem.ForeColor = Color.Green
                    Else
                        bePModem.Text = "Módem GSM no encontrado"
                        bePModem.ForeColor = Color.Red
                    End If
                    'Limpiamos el bugger de datos de entrada 
                    'devueltos por el módem GSM
                    compPuertoSerie.DiscardInBuffer()

                    'Comprobar si el módem módem GSM está conectado a una red GSM
                    compPuertoSerie.Write("AT+CREG?" & Chr(13))
                    System.Threading.Thread.Sleep(1000)
                    'Si el comando AT+CREG? devuelve 0,1 es que hay red móvil
                    If compPuertoSerie.ReadExisting().IndexOf("0,1") Then
                        bePRedMovil.Text = "Red móvil disponible"
                        bePRedMovil.ForeColor = Color.Green
                    Else
                        bePRedMovil.Text = "No hay red móvil"
                        bePRedMovil.ForeColor = Color.Red
                    End If
                    compPuertoSerie.DiscardInBuffer()

                    'Obtener la intensidad de la señal (cobertura) del módem GSM
                    'máximo: 31.99
                    compPuertoSerie.Write("AT+CSQ" & Chr(13))
                    System.Threading.Thread.Sleep(1000)
                    resultadoDevuelto = compPuertoSerie.ReadExisting()
                    posBusqueda = resultadoDevuelto.IndexOf("+CSQ: ")
                    If posBusqueda >= 0 Then
                        bpSenal.Minimum = 0
                        bpSenal.Maximum = 39
                        bpSenal.Value = obtenerCobertura(resultadoDevuelto)
                    Else
                        bpSenal.Minimum = 0
                        bpSenal.Value = 0
                        bpSenal.Minimum = 39
                    End If
                    compPuertoSerie.DiscardInBuffer()

                    'Obtener ID del dispositivo GSM (IMEI)
                    compPuertoSerie.Write("AT+CGSN" & Chr(13))
                    System.Threading.Thread.Sleep(1000)
                    resultadoDevuelto = compPuertoSerie.ReadExisting()
                    posBusqueda = resultadoDevuelto.IndexOf("CGSN")
                    If posBusqueda >= 0 Then
                        resultadoDevuelto =
                            quitarSaltosLinea(resultadoDevuelto, " ")
                        bePID.Text = "IMEI: " &
                            Replace(Mid(resultadoDevuelto,
                            posBusqueda + Len("CGSN") + 1,
                            Len(resultadoDevuelto)), "OK", "")
                    End If

                    btConectar.Text = "Desconectar"
                End If
            Else
                If compPuertoSerie.IsOpen Then
                    compPuertoSerie.Close()
                End If
                btConectar.Text = "Conectar"
            End If
        Catch ex As Exception
            MsgBox("Error al abrir el puerto serial: " &
                   ex.Message, MsgBoxStyle.Critical)
        End Try
    End Sub
 

A continuación listamos el código fuente de las funciones usadas en el botón anterior:

  • Función abrirPuertoSerie:
    'Abre el puerto serie pasado como parámetro
    Sub abrirPuertoSerie(ByVal puerto As String)
        Try
            With compPuertoSerie
                If .IsOpen Then
                    .Close()
                End If

                .PortName = puerto
                .BaudRate = CInt(lsBitPorSegundo.Text)
                .DataBits = CInt(lsBitDatos.Text)
                Select Case lsBitsParada.Text
                    Case "1"
                        .StopBits = IO.Ports.StopBits.One
                    Case "1.5"
                        .StopBits = IO.Ports.StopBits.OnePointFive
                    Case "2"
                        .StopBits = IO.Ports.StopBits.Two
                    Case "Ninguno"
                        .StopBits = IO.Ports.StopBits.None
                End Select

                Select Case lsParidad.Text
                    Case "Par"
                        .Parity = IO.Ports.Parity.Even
                    Case "Impar"
                        .Parity = IO.Ports.Parity.Odd
                    Case "Ninguno"
                        .Parity = IO.Ports.Parity.None
                    Case "Marca"
                        .Parity = IO.Ports.Parity.Mark
                    Case "Espacio"
                        .Parity = IO.Ports.Parity.Space
                End Select

                Select Case lsControlFlujo.Text
                    Case "Hardware"
                        .Handshake = IO.Ports.Handshake.RequestToSend
                    Case "Xon / Xoff"
                        .Handshake = IO.Ports.Handshake.XOnXOff
                    Case "Ninguno"
                        .Handshake = IO.Ports.Handshake.None
                    Case "Hardware y Xon/Xoff"
                        .Handshake = 
                           IO.Ports.Handshake.RequestToSendXOnXOff
                End Select

                .DtrEnable = False

                .ReadBufferSize = CInt(txtTamanoBufferLectura.Text)
                .WriteBufferSize = CInt(txtTamanoBufferEscritura.Text)
                .WriteTimeout = CInt(txtTiempoEspera.Text)
                .RtsEnable = True
                .Encoding = System.Text.Encoding.Default
                .Open()
            End With

        Catch ex As Exception
            MsgBox("Error al abrir el puerto serie: " &
                   ex.Message, MsgBoxStyle.Critical)
        End Try
    End Sub

  • Función quitarSaltosLinea:
    'Función para quitar los saltos de línea de un texto
    Private Function quitarSaltosLinea(ByVal texto As String,
                      caracterReemplazar As String) As String
        quitarSaltosLinea = Replace(Replace(texto, Chr(10),
                caracterReemplazar), Chr(13), caracterReemplazar)
    End Function
  • Función obtenerCobertura:
    Private Function obtenerCobertura(
                      ByVal texto As String) As Double
        Dim pos As Integer
        Dim textoTemp As String

        texto = quitarSaltosLinea(texto, " ")
        pos = texto.IndexOf("CSQ:") + Len("CSQ:") + 1
        textoTemp = Mid(texto, pos, Len(texto))
        textoTemp = Trim(Replace(textoTemp, "OK", ""))

        obtenerCobertura = CDbl(textoTemp)
    End Function

  • Establecer el PIN de la tarjeta SIM del módem GSM (btPIN):

    Private Sub btPIN_Click(sender As System.Object,
                e As System.EventArgs) Handles btPIN.Click
        Try
            'Enviar PIN a tarjeta SIM del dispositivo módem GSM
            compPuertoSerie.Write("AT+CPIN=" &
                                  txtPIN.Text & Chr(13))
        Catch ex As Exception
            MsgBox(ex.Message, MsgBoxStyle.Critical +
                   MsgBoxStyle.OkOnly)
        End Try
    End Sub

  • Enviar comando AT personalizado (btEnviarATPrueba):
    Private Sub btEnviarATPrueba_Click(sender As System.Object,
                     e As System.EventArgs) _
                     Handles btEnviarATPrueba.Click
        Try
            compPuertoSerie.Write(txtComandoAT.Text & Chr(13))
        Catch ex As Exception
            MsgBox(ex.Message, MsgBoxStyle.Critical +
                   MsgBoxStyle.OkOnly)
        End Try
    End Sub
 
  • El botón más importante, para enviar el SMS (btEnviarSMS):
    Private Sub btEnviarSMS_Click(sender As System.Object,
                   e As System.EventArgs) Handles btEnviarSMS.Click
        If Not compPuertoSerie.IsOpen Then
            tabPes.SelectedTab = tabConfiguracionModem
            MsgBox("Antes de enviar el SMS debe introducir los datos " &
                    "de conexión con el módem GSM y la tarjeta SIM y " &
                    "conectar con el puerto serie.",
                    MsgBoxStyle.Information + MsgBoxStyle.OkOnly)
        Else
            If txtNumeroTelefono.Text = "" Or txtSMS.Text = "" Then
                MsgBox("Debe introducir el número de teléfono al  " &
                        "que se enviará el SMS y el texto del SMS.",
                        MsgBoxStyle.Information + MsgBoxStyle.OkOnly)

            Else
                Try
                    'Activar modo SMS en dispositivo GSM
                    compPuertoSerie.Write("AT+CMGF=1" & Chr(13))
                    System.Threading.Thread.Sleep(1000)
                    'Establecer número de teléfono de destino del SMS
                    compPuertoSerie.Write("AT+CMGS=" & Chr(34) &
                                          (txtNumeroTelefono.Text) &
                                          Chr(34) & Chr(13))
                    System.Threading.Thread.Sleep(1000)
                    'Enviar texto SMS a dispositivo GSM
                    compPuertoSerie.Write(txtSMS.Text & Chr(26))
                    Application.DoEvents()
                    System.Threading.Thread.Sleep(1000)
                    MsgBox("El SMS ha sido enviado al número " &
                           txtNumeroTelefono.Text & ".",
                            MsgBoxStyle.Information + 
                            MsgBoxStyle.OkOnly)
                Catch ex As Exception
                    MsgBox(ex.Message, MsgBoxStyle.Critical +
                           MsgBoxStyle.OkOnly)
                End Try
            End If
        End If
    End Sub
 

  • Para mostrar el resultado de cada comando AT, usamos el evento DataReceived del SerialPort (compPuertoSerie):
    'NOTA: este evento del SerialPort se ejecuta en un Thread 
    'diferente al de la aplicación, por lo que los datos devueltos 
    'por el puerto serie no tienen por qué ser instantáneos, puede que tengan retraso
    Private Sub compPuertoSerie_DataReceived(sender As System.Object,
            e As System.IO.Ports.SerialDataReceivedEventArgs) _
            Handles compPuertoSerie.DataReceived
        Dim resultadoModemGSM As String

        Try
            'Obtener el resultado devuelto por el puerto serie
            resultadoModemGSM =
                compPuertoSerie.ReadExisting.Trim().ToString

            If txtResultado.Text <> "" Then
                txtResultado.Text = txtResultado.Text + vbCrLf +
                       resultadoModemGSM
            Else
                txtResultado.Text = resultadoModemGSM
            End If

            'Mostrar última línea del TextBox
            txtResultado.Select(txtResultado.Text.Length, 0)
            txtResultado.ScrollToCaret()

        Catch ex As Exception
            MsgBox(ex.Message, MsgBoxStyle.Critical +
                   MsgBoxStyle.OkOnly)
        End Try
    End Sub

  • En el evento Load del formulario principal colocamos el siguiente código para desactivar la detección a llamadas en subprocesos equivocados:
    Private Sub formEnvioSMS_Load(sender As System.Object,
                e As System.EventArgs) Handles MyBase.Load
        'Desactivar detección a llamadas en subprocesos equivocados
        CheckForIllegalCrossThreadCalls = False
    End Sub

La descarga con la aplicación completa AjpdSoft Envío SMS y el código fuente en Visual Basic .Net 2010:

AjpdSoft Envío SMS

 

 

La aplicación AjpdSoft Envío de SMS en funcionamiento

Una vez conectado el módem GSM con su correspondiente tarjeta SIM activa al puerto serie del PC, ejecutaremos AjpdSoft Envío SMS, accederemos a la pestaña "Configuración puerto y módem GSM". Pulsaremos en el botón "Establecer valores por defecto":

La aplicación AjpdSoft Envío de SMS por GSM en funcionamiento

A continuación pulsaremos en el botón "Obtener" para listar los puertos serie del equipo:

La aplicación AjpdSoft Envío de SMS por GSM en funcionamiento

Seleccionaremos el puerto serie donde tengamos conectado el módem GSM (por ejemplo COM7) y pulsaremos "Conectar" para establecer la comunicación con el módem GSM y la tarjeta SIM conectada:

La aplicación AjpdSoft Envío de SMS por GSM en funcionamiento

Si todo es correcto, AjpdSoft Envío SMS obtendrá los datos básicos: comprobará si hay un módem GSM conectado al puerto serie, comprobará si hay red móvil disponible, obtendrá el IMEI del módem GSM y obtendrá la intensidad de la señal (cobertura). Mostrará estos datos en la parte inferior:

La aplicación AjpdSoft Envío de SMS por GSM en funcionamiento

Si nuestra tarjeta SIM está protegida con un PIN de seguridad deberemos establecerlo para poder usarla. Para indicar el PIN lo introduciremos en "PIN" y pulsaremos el botón "Establecer PIN". Si el PIN es correcto mostrará "OK" en la ventana de resultado de los comandos AT:

La aplicación AjpdSoft Envío de SMS por GSM en funcionamiento

Desde la pestaña "Enviar comando AT" podremos enviar cualquier comando AT que queramos al módem, a nos devolverá el resultado (si lo hay) en el cuadro "Resultado". Para enviar el comando AT lo introduciremos en "Comando AT", por ejemplo para obtener la primera entrada de la agenda de la tarjeta SIM introduciremos el comando AT: AT+CPBR=1,1 pulsando en el botón "Enviar comando AT" nos devolverá el resultado:

La aplicación AjpdSoft Envío de SMS por GSM en funcionamiento

Para enviar un SMS a un móvil pulsaremos en la pestaña "Envío de SMS", introduciremos el número de teléfono de destino del SMS en "Nº teléfomo" y el texto del mensaje SMS que queramos enviar en "Mensaje". Pulsaremos el botón "Enviar SMS":

La aplicación AjpdSoft Envío de SMS por GSM en funcionamiento

Si el envío se realiza (no implica que llegue el SMS necesariamente al destinatario) mostrará el mensaje:

La aplicación AjpdSoft Envío de SMS por GSM en funcionamiento

En el cuadro de resultado mostrará el resultado devuelto por el módem mediante el puerto serie de los comandos AT ejecutados para enviar el SMS:

La aplicación AjpdSoft Envío de SMS por GSM en funcionamiento

En el móvil del destinatario, casi instantáneamente (dependerá de los operadores y la saturación de la red) llegará el SMS enviado desde el PC:

La aplicación AjpdSoft Envío de SMS por GSM en funcionamiento

Abriremos el mensaje SMS (en nuestro caso en un LG Optimus 2x con Android):

La aplicación AjpdSoft Envío de SMS por GSM en funcionamiento

Y podremos consultar el mensaje enviado desde el PC con un módem GSM y AjpdSoft Envío SMS:

La aplicación AjpdSoft Envío de SMS por GSM en funcionamiento

 

Uso de envío de SMS por módem GSM desde PC

Obviamente el uso que se quiera dar a la opción de enviar mensajes de texto SMS dependerá de cada desarrollador y las necesidades de sus programas.

Existen multitud de utilidades para usar un módem GSM y enviar SMS desde un PC, por ejemplo se podría programar una aplicación que hiciera ping cada cierto tiempo a los servidores de nuestra empresa y, si algún ping falla, enviar un SMS al administrador de sistemas. Otra aplicación sería añadir la opción de enviar datos de un viaje por SMS a un camionero en una aplicación de transportes.

Como decimos, esta herramienta es muy interesante para notificaciones instantáneas, más eficiente y rápido que el correo electrónico. Podríamos dotar a nuestras aplicaciones de la posibilidad de avisar mediante SMS en determinadas circunstancias.

Desde el Proyecto AjpdSoft hemos pretendido mostrar todas las posibilidades del manejo de un módem GSM para envío de mensajes cortos SMS a móviles. Puesto que tenéis el código fuente gratuito y completo de la aplicación podréis modificarlo y usarlo para implementar esta opción en vuestras aplicaciones:

AjpdSoft Envío SMS

 

Artículos relacionados

  

Créditos

Artículo realizado íntegramente por Alonsojpd miembro fundador del Proyecto AjpdSoft.


Anuncios


Enviado el Martes, 16 agosto a las 02:00:00 por ajpdsoft
Visita nuestro nuevo sitio web con programas y contenidos actualizados: Proyecto A