Sei sulla pagina 1di 8

GSM, SMS, CORREO ELECTRÓNICO

El código fuente de todos los ejemplos se puede descargar desde aquí .


http://www.python-exemplary.com/index_en.php?inhalt_links=navigation_en.inc.php&in
halt_mitte=raspi/en/gsm.inc.php

GSM - La puerta inalámbrica al mundo.

Si su Raspberry Pi necesita comunicarse con el mundo exterior cuando no está dentro del
alcance de un punto de acceso WiFi, se puede usar una red celular digital. Al igual que con los
teléfonos móviles, necesita una tarjeta SIM y una suscripción de cualquier proveedor. En la
mayoría de las aplicaciones, solo se necesita la transmisión de datos o SMS con poco volumen
de datos y baja velocidad de transferencia, por lo que puede comprar una tarjeta SIM barata
de "solo datos".

En el lado del hardware, necesita un módulo GSM, también llamado módem GSM, que se pueda
conectar con la Raspberry Pi. La mayoría de los módems utilizan un enlace de comunicación
serial (RS-232) y el buen conjunto de comandos de Hayes (extendido) con el prefijo "AT". Este
capítulo se basa en el chip SIM800 que es muy versátil y está disponible en varios módulos. Ya
que necesita una fuente de alimentación de 4.3V, verifique que la placa incluya un regulador de
voltaje, de modo que pueda alimentarse con una fuente de alimentación externa de 5V USB.

Incluso hay tableros de ruptura GSM diseñados


especialmente para el cabezal Raspberry Pi de 40
pines, como el "RPI GSM Add-on V2.0" que se
encuentra en eBay. Este módulo es fácil de usar,
ya que interactúa con el UART RX / TX de la
Raspberry Pi y se puede activar / desactivar y
restablecer a través de los puertos de E / S de
GPIO. Cuando funciona con su puerto USB de 5 V,
la Raspberry Pi también recibe alimentación.

Simplemente monte la antena, agregue una


tarjeta SIM sin bloqueo, inserte el módulo en el
cabezal GPIO y conecte un cable USB de una
fuente de 5V / 2A. Cuando se presiona el
interruptor de alimentación por un tiempo, el
sistema se inicia y se conecta automáticamente a
su red GSM.

Observaciones: debe eliminar el bloqueo de la tarjeta SIM antes de poder usarlo en el módem. Para hacerlo, inserte la
tarjeta SIM en cualquier teléfono inteligente que tenga a mano y aplique la opción de configuración específica para la
eliminación del bloqueo de la tarjeta SIM (que se encuentra principalmente en "Seguridad de la tarjeta SIM"). También
puede pedirle a su operador de red que lo haga por usted. Compruebe que el teléfono inteligente se inicia sin pedir más el
código.

Experimento 1: Raspberry Pi como mayordomo de SMS

El SIM800 te abre el mundo para muchos proyectos de comunicación interesantes. Algunos de


ellos pueden ser muy útiles y profesionales. Déjate inspirar e inventar algo especial. En el
siguiente ejemplo, la Raspberry Pi se comunica a través de SMS.

Objetivo:
convertir tu Raspberry Pi en un mayordomo SMS que devuelve un SMS con información de
estado cada vez que se recibe un SMS. (El mayordomo se podría expandir para realizar algunas
acciones útiles cuando se recibe un SMS, por ejemplo, para encender / apagar el calentador en
una residencia de invierno desocupada remota e informar la temperatura actual de la
habitación).

Puede usar un terminal PuTTY para jugar con los comandos SMS manualmente. Haz lo
siguiente:
Comando (termina con <cr>) Responder: Significado
AT + CMGF = 1 OK: configura el modem en modo texto
AT + CMGS = "+ 41764331357" >: Prepárate para enviar a un número de teléfono dado
¡Que tengas un buen día! <^ Z> OK: enviar texto y terminar con Ctrl + Z
Tercer SMS entrante + CMTL: "SM", 3
AT + CMGR = 3 Mostrar contenido de SMS # 3
AT + CMGDA = "DEL ALL" Borrar todos los SMS

Si la Raspberry Pi recibe un SMS que contiene el texto "getStatus", envía un SMS con la marca
de tiempo actual y el estado de GPIO pin # 24 a un número de teléfono determinado.

Programa: [►]

Programa:

# SIMSMS1.py

importación RPi.GPIO como GPIO


importar serie
importación tiempo, sys
importación de fecha y hora

Botón P_BUTTON = 24 #, se adapta a su cableado

def configuración ():


GPIO.setmode (GPIO.BOARD)
GPIO.setup (P_BUTTON, GPIO.IN, GPIO.PUD_UP)

SERIAL_PORT = "/ dev / ttyAMA0" # Raspberry Pi 2


#SERIAL_PORT = "/ dev / ttyS0" # Raspberry Pi 3

ser = serial.Serial (SERIAL_PORT, baudrate = 9600, timeout = 5)


preparar()
ser.write ( "AT + CMGF = 1 \ r" ) # configurado en modo de texto
time.sleep (3)
ser.write ( 'AT + CMGDA = "DEL ALL" \ r' ) # borrar todos los SMS
time.sleep (3)
reply = ser.read (ser.inWaiting ()) # Clean buf
print "Listening for ingomming SMS ..."
mientras True:
reply = ser.read (ser.inWaiting ())
si la respuesta es = = "" :
ser.write ( "AT + CMGR = 1 \ r" )
time.sleep (3)
reply = ser.read (ser.inWaiting ())
imprimir "SMS recibido. Contenido:"
imprimir respuesta
si "getStatus" en respuesta:
t = str (datetime.datetime.now ())
si GPIO.input (P_BUTTON) == GPIO.HIGH:
state = "Botón soltado"
else :
state = "Button presionado"
ser.write ( 'AT + CMGS = "+ 41764331356" \ r' )
time.sleep (3)
msg = "Estado de envío en" + t + ": -" + impresión de estado
"Enviando SMS con información de estado:" + msg
ser.write (msg + chr (26))
time.sleep (3)
ser.write ( 'AT + CMGDA = "DEL ALL" \ r' ) # borrar todo
time.sleep (3)
ser.read (ser.inWaiting ()) # Borrar buf
time.sleep (5)
Código de programa destacado (Ctrl + C copia, Ctrl + V pegar)

Observaciones:
tenga en cuenta que debe esperar un momento la respuesta del módem antes de recuperar el
contenido del búfer del receptor con ser.read () .

Si la marca de tiempo no es correcta, consulte el tutorial Temporizador para ver cómo


configurar el reloj del sistema.

Experimento 2: envío de datos a un servidor TCP a través de GSM

Cuando la Raspberry Pi está fuera


del alcance de cualquier punto de
acceso WLAN, se puede establecer
una conexión a Internet a través de
la red móvil GSM. Aquí, el RPi
desempeña el papel de un cliente
TCP utilizando la placa
complementaria basada en SIM800.
El escenario es el mismo que en el
ejemplo 3 del tutorial de
comunicación de datos , pero ahora
el enlace se establece a través de la
red GSM.

El servidor debe hacerse visible desde Internet como se describe anteriormente, ya sea utilizando la
dirección IP punteada del enrutador o el alias IP proporcionado por no-ip.

Objetivo:
ejecutar un servidor de socket simple en una PC que escucha en el puerto 22000 que solo muestra los
mensajes de estado en una consola. Intente configurar su enrutador para que el servidor sea visible
desde cualquier lugar de Internet.

Programa: [►]

# DataServer3.py

desde tcpcom import TCPServer

IP_PORT = 22000

def onStateChanged (state, msg):


if state == "LISTENING" :
print "Servidor: - Escuchando ..."
elif state == "CONNECTED" :
print "Servidor: - Conectado a" , msg
elif state == "MENSAJE" :
imprimir "Servidor: - Mensaje recibido:" , msg

server = TCPServer (IP_PORT, stateChanged = onStateChanged)

Código de programa destacado (Ctrl + C copia, Ctrl + V pegar)

El módem implementa una multitud de comandos AT . Al estudiar el siguiente ejemplo, aprenderá a usar
el módem como un cliente TCP. (Más información sobre cómo usar TCP el modo se encuentra aquí .)

Como se muestra arriba, se recomienda instalar un emulador de terminal como PuTTY que use con una
pantalla adjunta o un acceso VPN. Luego, prueba los comandos AT manualmente antes de
implementarlos en un programa.
Después de iniciar el tipo de emulador AT <cr> para verificar si el módem responde correctamente.
Luego escribe otros comandos AT que toma de la documentación del conjunto de comandos (use ^ H
para eliminar una entrada de caracteres incorrecta). Para iniciar una conexión a Internet, los siguientes
comandos pueden ayudar:

Comando (termina con <cr>) Responder: Significado


A DE ACUERDO
¿AT + CREG? + CREG: 0,1: Módem registrado para net carrier.
OK: el módem está conectado al operador de red (APN)
AT + CSTT = "gprs.swisscom.ch"
(use el APN de su proveedor)
AT + CIICR OK: conexión inalámbrica habilitada
AT + CIFSR 10.221.69.48: Dirección IP conseguida

Debido a que somos demasiado perezosos para escribir todas estas líneas crípticas a mano, escribimos
un programa Python que envía los comandos y verifica la información de respuesta.
Se debe prestar atención a que su programa y PuTTY no estén accediendo al módem al mismo tiempo, porque PuTTY traga las
respuestas del módem. Pero a veces es conveniente ver en la ventana de la terminal lo que envía su programa y el mensaje de correo
electrónico que se encuentra en el terminal, fue el programa de envío.

Como es habitual, estructuramos el código escribiendo un módulo SIM800Modem.py que define


funciones específicas del módem.

Una clase SIM800Modem sería una mejor opción, depende de usted definirla.

Para obtener la respuesta del módem, verificamos con n = ser.inWaiting () el número de caracteres
que esperan en el búfer de respuesta y los recuperamos todos junto con ser.read (n) , donde ser es
la instancia del puerto serie devuelta cuando el puerto serie Se abre con serial.Serial ()

Programa: [►]

# SIM800Modem.py

importar RPi.GPIO como GPIO


tiempo de importación

VERBOSE = Falso
P_POWER = 11 # Power pin
P_RESET = 12 # Reset pin

def debug (texto):


si VERBOSE:
imprime "Debug: ---" , texto

def resetModem ():


GPIO.setmode (GPIO.BOARD)
GPIO.setup (P_RESET, GPIO.OUT)
GPIO.output (P_RESET, GPIO.LOW)
time.sleep (0.5)
GPIO.output (P_RESET, GPIO.HIGH)
time.sleep (0.5)
GPIO.output (P_RESET, GPIO.LOW)
time.sleep (3)

def togglePower ():


GPIO.setmode (GPIO.BOARD)
GPIO.setup (P_POWER, GPIO.OUT)
GPIO.output (P_POWER, GPIO.LOW)
time.sleep (0.5)
GPIO.output (P_POWER, GPIO.HIGH)
time.sleep (3)
GPIO.output (P_POWER, GPIO.LOW)

def isReady (ser):


# Restablecimiento de los valores predeterminados
cmd = 'ATZ \ r'
debug ( "Cmd:" + cmd)
ser.write (cmd)
time.sleep (2)
reply = ser.read (ser.inWaiting ())
time.sleep (8) # Espere hasta que se conecte a la
devolución neta ( "OK" en la respuesta)

def connectGSM (ser, apn):


# Inicie sesión en APN, no se necesita ID de usuario / contraseña
cmd = 'AT + CSTT = "' + apn + '" \ r'
debug ( "Cmd:" + cmd)
ser.write (cmd)
time.sleep (3)

# Activando la red
cmd = "AT + CIICR \ r"
debug ( "Cmd:" + cmd)
ser.write (cmd)
time.sleep (5)

# Obtener la dirección IP
cmd = "AT + CIFSR \ r"
debug ( "Cmd:" + cmd)
ser.write (cmd)
time.sleep (3)

# Devolviendo todos los mensajes de modem


reply = ser.read (ser.inWaiting ())
debug ( "connectGSM () retured: \ n" + reply)
devolver respuesta

def connectTCP (ser, host, puerto):


cmd = 'AT + CIPSTART = "TCP", "' + host + '", "' + str (puerto) + '" \ r'
ser.write (cmd)
time.sleep (5)
reply = ser.read (ser.inWaiting ())
debug ( "connctTCP () retured: \ n" + responder)
devolver respuesta

def sendHTTPRequest (ser, host, solicitud):


ser.write ( "AT + CIPSEND \ r" )
time.sleep (2)
request = "GET" + request + "HTTP / 1.1 \ r \ nHost:" + host + "\ r \ n \ r \ n"
ser.write (request + chr (26)) # data <^ Z>
time.sleep (2)

def closeTCP (ser, showResponse = False):


ser.write ( "AT + CIPCLOSE = 1 \ r" )
reply = ser.read (ser.inWaiting ())
debug ( "closeTCP () retured: \ n" + reply)
si showResponse:
print "Server reponse: \ n" + reply [(reply.index ( "SEND OK" ) + 9):]
time.sleep (2)

def getIPStatus (ser):


cmd = "AT + CIPSTATUS \ n"
ser.write (cmd)
time.sleep (1)
reply = ser.read (ser.inWaiting ())
respuesta de
retorno
Código de programa destacado (Ctrl + C copia, Ctrl + V pegar)

Observaciones:
Como ve, se necesita bastante conocimiento y experiencias prácticas para escribir estas líneas de
código. Es importante tener en cuenta que los retrasos adecuados entre varias acciones son necesarios,
ya que el programa es muy rápido y debe esperar hasta que el módem o la red GSM cumplan con el
comando. Pero esta es una codificación peligrosa porque los retrasos de tiempo requeridos pueden
variar dependiendo de retardos imprevisibles. Una mejor solución sería permanecer en un bucle hasta
que el módem responda con un mensaje de éxito.

Existe otra posible mejora: cuando un comando informa un error o un tiempo de espera, no se debe
abandonar completamente la acción completa, sino que se debe intentar nuevamente. Estas mejoras
hacen explotar el código considerablemente y, por lo tanto, no se consideran aquí.

Puede establecer el indicador VERBOSE = True para obtener una gran cantidad de mensajes de
depuración que le ayudan a depurar el código.

Objetivo:
utilizando el código del módulo anterior, escriba un cliente que se conecte mediante GSM a un servidor
remoto y envíe información del sensor (aquí solo el estado de un botón) aproximadamente cada 5
segundos.

Programa: [►]

# SIMClient.py

importar serie
importación tiempo, sys
de SIM800Modem importación *
importación RPi.GPIO como GPIO

APN = "gprs.swisscom.ch"
#HOST = "5.149.19.125"
HOST = "raspibrick.zapto.org"
PUERTO = 5000
SERIAL_PORT = "/ dev / ttyAMA0" # Raspberry Pi 2
#SERIAL_PORT = "/ dev / ttyS0" # Raspberry Pi 3
P_BUTTON = 24 # se adapta a su cableado

def configuración ():


GPIO.setmode (GPIO.BOARD)
GPIO.setup (P_BUTTON, GPIO.IN, GPIO.PUD_UP)

preparar()
imprimir "reiniciando modem ..."
resetModem ()
ser = serial.Serial (SERIAL_PORT, baudrate = 9600, timeout = 5)
si no está listo (ser):
imprima "El módem no está listo".
sys.exit (0)

Imprimir "Conectando a la red GSM ..."


connectGSM (ser, APN)

imprimir "Conectando al servidor TCP ..."


respuesta = connectTCP (ser, HOST, PORT)
si "CONNECT OK" no en respuesta:
print "Error de conexión"
sys.exit (0)

imprima "Conexión establecida. Enviando datos ..."


mientras sea Verdadero:
si GPIO.input (P_BUTTON) == GPIO.LOW:
msg = "Botón presionado"
else :
msg = "Botón liberado"
k = len (msg) # ¿no excede el valor devuelto por AT + CIPSEND? (máx. 1460)
ser.write ( "AT + CIPSEND =" + str (k) + "\ r" ) # tiempo de envío de longitud
fija.sleep (1) # esperar solicitud
ser.write (msg)
time.sleep (4)

Código de programa destacado (Ctrl + C copia, Ctrl + V pegar)

Observaciones:
Como se explica en el capítulo Comunicación de datos, el cliente debe conocer la dirección IP de su
servidor de PC tal como se ve desde Internet. Debido a que su enrutador está configurado para el
reenvío de IP, se considera que la PC tiene la dirección IP del enrutador.

Experimento 3: Enviar correos electrónicos con archivos adjuntos

El correo electrónico es otro canal de comunicación para informar información y alertas de la


Raspberry Pi. Incluso puede adjuntar un archivo de imagen grande tomado de la cámara. Si está
conectado a Internet a través de WLAN, los correos son enviados por su servidor SMTP personal.
Puede crear una cuenta de correo electrónico con un proveedor de servicios de correo electrónico
gratuito, por ejemplo, una cuenta de Gmail (debe habilitar el "acceso para aplicaciones menos
seguras" para que funcione).

Objetivo:
enviar un correo electrónico desde la Raspberry Pi a un destinatario cada vez que se presiona un
botón. El RPi tiene una conexión a Internet a través de Ethernet o WLAN y hay un servidor SMTP
disponible.

En el siguiente programa usamos una de nuestras cuentas de Gmail.

Programa: [►]

# SendMail1.py

importar RPi.GPIO como GPIO


importar smtplib, datetime, os, time
from email.mime.multipart importar MIMEMultipart
desde email.mime.text importar MIMEText
desde email.mime.image importar MIMEImage

USERNAME = 'raspi4kids@gmail.com' # Nombre de usuario para la autenticación


PASSWORD = 'raspi1234' # Contraseña para la autenticación
SMTP_SERVER = 'smtp.gmail.com' # URL del servidor SMTP

FROM = "Aegidius Pluess" # El nombre se muestra como remitente


TO = 'a2015@pluess.name' # Dirección de correo del destinatario
SSL_PORT = 465

P_BUTTON = 24 # Botón pin, se adapta a su cableado

def configuración ():


GPIO.setmode (GPIO.BOARD)
GPIO.setup (P_BUTTON, GPIO.IN, GPIO.PUD_UP)

def sendMail (asunto, texto, img = Ninguno):


imprimir ( "Enviando el correo ..." )
msg = MIMEMultipart ( "alternativa" )
msg.attach (MIMEText (texto, "html" ))

tmpmsg = msg
msg = MIMEMultipart ()
msg.attach (tmpmsg)
si img! = Ninguno:
si no es os.path.exists (img):
imprime "Archivo" , img, "no existe".
otra cosa :
fp = abierto (img, 'rb' )
img = MIMEImage (fp.read ()) # incluido en el correo, no como archivo adjunto
fp.close ()
msg.attach (img)

msg [ 'Asunto' ] = asunto


msg [ 'De' ] = DE
server = smtplib.SMTP_SSL (SMTP_SERVER, SSL_PORT)
server.login (NOMBRE DE USUARIO, CONTRASEÑA)
server.sendmail (FROM, [TO], msg.as_string ())
server.quit ()
imprimir ( "Correo enviado con éxito" )

preparar()
imprima "Esperando evento de botón ..."
mientras es Verdadero:
si GPIO.input (P_BUTTON) == GPIO.LOW:
t = str (datetime.datetime.now ())
text = "Alert on" + t + "<br> ¡Se presionó el botón <b>! </b>"
subject = "Alert from Raspberry Pi"
enviar correo (asunto, texto)
#sendMail (asunto, texto, "c: /scratch/mailtest.png")
time.sleep (30)

Código de programa destacado (Ctrl + C copia, Ctrl + V pegar)

Observaciones:
La función sendMail () es algo complicada y no se explica en detalle aquí. Puede adjuntar un archivo
adjunto de correo especificando el parámetro img . La misma función se puede utilizar para enviar
correos electrónicos desde un programa Python que se ejecuta en una PC.

Potrebbero piacerti anche