Adafruit Ultimate GPS Breakout v3 en la Raspberry Pi

Conectar un módulo de GPS a la Raspberry Pi abre un mundo de posibilidades, y no es demasiado complicado. Voy a explicar a continuación cómo conectar el módulo Adafruit Ultimate GPS Breakout v3. Como todos los productos de Adafruit, está muy bien documentado, y en la propia página de Adafruit tenemos muchos ejemplos de código y de conexiones. Aunque es algo carillo, unos 40-50€ (por ejemplo, aquí)…

Además, es uno de los pocos GPS que tienen correctamente implementadas las restricciones (ya obsoletas) COCOM, por las que un GPS comercial deja de funcionar si se supera la velocidad de 1000 nudos (unos 1900 km/h) y una altitud de 60.000 pies (unos 18 km). Que no vayamos a construir un misil, vamos. El problema es que la mayoría de los GPS se venden programados para que dejen de funcionar si una de las dos restricciones se alcanza (la velocidad o la altitud), y no las dos al mismo tiempo.

Como este GPS lo quiero emplear, entre otros poryectos, en una sonda estratosférica, que superará (espero) los 18 km de altitud, necesito un GPS que siga funcionando por encima de esa altitud, ya que la velocidad que llevará el globo será en torno a 5 m/s (18 km/h) bien lejos de los, ya quisiera yo, 1900 km/h.

Tenemos dos formas de conectar el GPS de Adafruit a la Raspberry Pi. La fácil, por USB, y la algo más complicada, por UART. Cuento primero la forma de hacerlo por USB, para lo cual necesitaremos un adaptador.

Conexión con adaptador USB-TTL

Podemos conectar el GPS a un puerto USB de la Raspberry Pi por medio de un adaptador USB a serie TTL PL2303. Yo compré este por menos de 3€.

FullSizeRender

Adaptador USB a serie TTL PL2303. Vista frontal

FullSizeRender2

Adaptador USB a serie TTL PL2303. Vista trasera

Conectamos el adaptador al GPS de la siguiente forma:

FullSizeRender

Conexión del módulo GPS al adaptardor USB-TTL

PL2303HX      GPS

3V3 --------- (No lo conecto)
TXD --------- RX
RXD --------- TX
GND --------- GND
+5V --------- VIN

Y enchufo el módulo USB a la RaspberrY Pi. Ejecuto:

ls /dev/ttyUSB*

Aparece el dispositivo /dev/ttyUSB0.

Si hago sudo lsusb, me aparece, entre otros dispositivos:

Bus 001 Device 006: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port

Así que ahí está mi Prolific PL2303, ok.

Miro a ver si el dispositivo está mandando alguna información (coordenadas GPS…), de forma un poco rupestre:

sudo cat /dev/ttyUSB0

Sale una ristra de lo que podría ser información geográfica, así que pinta bien.

$GPVTG,72.99,T,,M,0.01,N,0.01,K,A*08

$GPGGA,180130.000,4027.3560,N,00350.2876,W,1,6,1.29,694.6,M,51.7,M,,*4D

$GPGSA,A,3,12,25,29,24,14,31,,,,,,,2.52,1.29,2.16*06

$GPRMC,180130.000,A,4027.3560,N,00350.2876,W,0.03,72.99,280315,,,A*46

$GPVTG,72.99,T,,M,0.03,N,0.05,K,A*0E

$GPGGA,180130.000,4027.3560,N,00350.2876,W,1,6,1.29,694.6,M,51.7,M,,*4D
$GPGSA,A,3,12,25,29,24,14,31,,,,,,,2.52,1.29,2.16*06
94.6,M,51.7,M,,*4D
$GPRMC,180130.000,A,4027.3560,N,00350.2876,W,0.03,72.99,280315,,,A*46
D
$GPVTG,72.99,T,,M,0.03,N,0.05,K,A*0E
.2876,W,0.03,72.99,280315,,,A*46
D
$GPGGA,180130.000,4027.3560,N,00350.2876,W,1,6,1.29,694.6,M,51.7,M,,*4D
$GPGSA,A,3,12,25,29,24,14,31,,,,,,,2.52,1.29,2.16*06
94.6,M,51.7,M,,*4D
$GPRMC,180130.000,A,4027.3560,N,00350.2876,W,0.03,72.99,280315,,,A*46

Esto parecen datos de GPS, así que asumo que mi GPS está conectado al puerto /dev/ttyUSB0.

Instalo el demonio GPS (gpsd), y otras utilidades Python para poder leer datos del GPS:

sudo apt-get install gpsd gpsd-clients python-gps

Asigno ahora en gpsd el puerto del GPS:

sudo gpsd /dev/ttyUSB0 -F /var/run/gpsd.sock

Y compruebo a ver si funciona con el siguiente programita:

cgps -s

¡Bingo! Me sale una pantalla como esta:

┌───────────────────────────────────────────┐┌─────────────────────────────────┐
│    Time:       2015-03-28T18:08:55.000Z   ││PRN:   Elev:  Azim:  SNR:  Used: │
│    Latitude:    40.xxxxxx N               ││  25    70    001    34      Y   │
│    Longitude:    3.xxxxxx W               ││  29    67    185    32      Y   │
│    Altitude:   691.7 m                    ││  14    47    254    46      Y   │
│    Speed:      2.7 kph                    ││  12    41    060    37      Y   │
│    Heading:    271.1 deg (true)           ││  31    29    311    44      Y   │
│    Climb:      0.0 m/min                  ││  24    26    130    18      N   │
│    Status:     3D FIX (29 secs)           ││   2    25    071    00      N   │
│    Longitude Err:   +/- 15 m              ││   6    05    033    00      N   │
│    Latitude Err:    +/- 24 m              ││  34    00    000    00      N   │
│    Altitude Err:    +/- 22 m              ││                                 │
│    Course Err:      n/a                   ││                                 │
│    Speed Err:       +/- 174 kph           ││                                 │
│    Time offset:     0.625                 ││                                 │
│    Grid Square:     IN80dk                ││                                 │
└───────────────────────────────────────────┘└─────────────────────────────────┘

(he puesto .xxxxxxx en las coordenadas)

Si pasa deja de funcionar o pasa algo raro, habrá que parar el servicio y reiniciarlo:

sudo killall gpsd
sudo gpsd /dev/ttyUSB0 -F /var/run/gpsd.sock

Además, esto hay que hacerlo cada vez que reiniciemos la Raspberry Pi, así que podemos colocarlos en /etc/rc.local

Conexión UART

En el post del GPS GY-NEO6MV2 explico cómo conectar el GPS por UART. Se hace de la misma forma.

Lectura de posición en Python

Tengo hechos varios scripts que consultan la posición GPS, velocidad, etc. por Python. Pero está algo desordenado y ahora mismo no lo voy a poner en limpio. Si alguien lo necesita, que por favor me lo pida.

Fijar la hora de la Raspberry Pi a través del GPS

Si queremos que la hora de la Raspberry Pi se fije a través de la hora obtenida por GPS, tenemos que instalar el servicio ntp, si es que no lo tenemos instalado:

sudo apt-get install ntp

Y después, editar el fichero /etc/ntp.conf, añadiendo lo siguiente al final del fichero:

# gps ntp
server 127.127.28.0 minpoll 4
fudge  127.127.28.0 time1 0.183 refid NMEA
server 127.127.28.1 minpoll 4 prefer
fudge  127.127.28.1 refid PPS

Y reiniciamos el servicio:

sudo service ntp restart

Comprobamos, ejecutando:

ntpq -p

Y obtenemos:

     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*ns1.indaloweb.n 193.190.230.65   2 u   17   64    3   22.815   -1.711   2.731
 static-21.herco 14.234.237.209   2 u   16   64    3   19.209   -4.084   3.189
 SHM(0)          .NMEA.           0 l    -   16    0    0.000    0.000   0.000
 SHM(1)          .PPS.            0 l    -   16    0    0.000    0.000   0.000

Esas dos últimas líneas son el GPS. A veces no se conecta bien, entonces hacemos:

sudo killall gpsd
sudo gpsd /dev/ttyUSB0 -F /var/run/gpsd.sock
sudo service ntp restart

Interferencias con la cámara

Tengo que advertir que hacer funcionar un GPS al mismo tiempo que la cámara de la Raspberry Pi puede suponer un verdadero problema. El cable plano o la propia cámara no están bien apantallados e interfieren con la recepción de la señal del GPS, llegando a impedir siquiera que funcione. Si acercas el GPS de tu móvil a la cámara, también deja de funcionar…

Para solucionarlo, o al menos mitigarlo, tenemos que alejar lo más posible la cámara del GPS. Para esto podemos comprar un cable plano más largo, como este o este. Mucho cuidado, pues uno de estos cables, creo que el chino, no es exactamente el de la Raspberry Pi, que requiere que las conexiones del cable (la zona «pelada») estén en caras contrarias en ambos extremos, sino que viene con el cable con conexiones por un mismo lado. Si conectamos el cable así directamente, se sobrecaliente la cámara y se rompe. Reconozco que quemé dos cámaras así hasta que descubrí el motivo…

[foto cables largos y extremos pelados]

Otra estrategia puede ser apantallar el cable plano. He probado con papel de aluminio, que conecto luego a un pin tierra de la Raspberry Pi, y mejora algo, pero no totalmente.

[foto apantallando cable]

Pero lo que mejor me ha funcionado ha sido colocar un núcleo de ferrita en el cable, como este, que me costó mucho encontrar.

[foto núcleo de ferrita]

Al final, lo mejor es alejar la cámara del GPS lo más posible, y además apantallarlo, es decir, combinar las tres estrategias.

[Foto de la cámara y el GPS alejado]

 

Referencias

  •  http://blog.retep.org/2012/06/18/getting-gps-to-work-on-a-raspberry-pi/
  • http://open.konspyre.org/blog/2012/10/18/raspberry-flavored-time-a-ntp-server-on-your-pi-tethered-to-a-gps-unit/
  • http://www.danmandle.com/blog/getting-gpsd-to-work-with-python/

Whatsapp (Yowsup) en la Raspberry Pi

Es posible mandar y recibir Whastapps en una Raspberry Pi. Para ello emplearemos el programa Yowsup.

En primer lugar, instalaremos las siguientes librerías, que son necesarias para que funcione Yowsup:

sudo apt-get install python-dateutil python-pip
sudo pip install python-axolotl

(Este último tarda, pero es necesario para que funcione la última versión de yowsup).
A continuación descargamos la librería Yowsup de GitHub:

cd ~
git clone git://github.com/tgalal/yowsup.git

(Lo descargamos en la carpeta home del usuario, o donde queramos)

Registramos el número en Whatsapp

Aquí está el quid de la cuestión. Para poder enviar Whatsapp es necesario asociar nuestra «cuenta» a un número de teléfono móvil (no vale fijo). Si empleamos nuestro número de móvil no podremos usar Whatsapp en ese móvil, así que cuidado con qué número asociais. Además, tiene que ser un número en el que podáis recibir un SMS o una llamada en el momento del registro (después, nunca más…)

Hasta hace unos meses, había una compañía en España que se llamaba Fonyou que te daba una línea de teléfono «virtual» que se redirigía a tu móvil. Pero dejó de operar.

 

 

Primero hay que solicitar el código:

cd ~/yowsup
python yowsup-cli registration -p 34666354324 -C 34 -m 214 -n 07 -r sms

El número de teléfono (tras -p) debe llevar el código del país delante, pero sin 00 ni +, sólo el código. En mi caso, que vivo en España, 34. Tras -C hay que poner el código del país, nuevamente sin 00 ni + delante. Tras -m y -n hy que poner el Mobile Country Code (MCC) y el Mobile Network Code, que podemos consultar en esta página de la Wikipedia. En mi caso (Movistar) son 214 y 07, respectivamente. Tras -r podemos escoger cómo queremos recibir el código de registro, si por sms o por llamada (voice). La llamada es automática, con voz femenina y en inglés; repite el código hasta el infinito (aunque no dice que hay un guión entre medias).

Saldrá lo siguiente:

INFO:yowsup.common.http.warequest:{"status":"sent","length":6,"method":"sms","retry_after":1805}

status: sent
retry_after: 1805
length: 6
method: sms

 

Tras unos minutillos (paciencia), llegará un código, como por ejemplo: 488-970. Con este código hacemos el registro, con casi el mismo comando de antes, pero cambiando el final e introduciendo el código recibido:

python yowsup-cli registration -p 34666354324 -C 34 -m 214 -n 07 <strong>-R 488-970</strong>

Aparece lo siguiente:

pi@pigorra1 ~/yowsup $ python yowsup-cli registration -p 34666354324 -C 34 -m 214 -n 07 -R 488-970
INFO:yowsup.common.http.warequest:{"status":"ok","login":"34666354324","pw":"EVen6FsZpzprEJJI1Sk9RFvZsz8=","type":"new","expiration":1458505212,"kind":"free","price":"0,89 \u20ac","cost":"0.89","currency":"EUR","price_expiration":1429949417}

status: ok
kind: free
pw: <strong>EVen6FsZpzprEJJI1345RFvZsz8=</strong>
price: 0,89 €
price_expiration: 1429949417
currency: EUR
cost: 0.89
expiration: 1458505212
login: 34666354324
type: new

¡Ya estamos registrados, y ya debería funcionar yowsup!

Ahora vamos a crear el fichero de configuración, con la contraseña recibida:

nano /home/pi/yowsup/yowsup.config

Con el siguiente contenido:

cc=34
phone=34666354324
password=EVen6FsZpzprgdfgJI1Sk9RFvZsz8=

Guardamos y salimos (Ctrl+x, S, enter).

Mandar un whatsapp desde la línea de comando

Para mandar un whatsapp, podemos hacerlo así:

python yowsup-cli demos -c /home/pi/yowsup/yowsup.config -s 34666666666 "Hola, mundo"

Tras la -s va el número de teléfono al que queremos mandar el mwnsaje. Es imprescindible que vaya con el código del país delante, sin 00 ni +. También podemos enviar el mensaje sin pasar por el fichero de configuración, directamente así:

python yowsup-cli demos -l 34666354324:EVen6FsZpzprEJJI1Sk9RFvZsz8= -s 34666666666 "Hola, mundo"
python yowsup-cli demos -l 34666823398:SZQHAegfjH32saYXed1jrjhYEOQ= -s 34666666666 "Hola, mundo"

Mandar whatsapps con Python

En realidad, es más versatil en enviar whatsapp empleando las librerías en Python, que nos darán muchas más posibilidades, como enviar imágenes, etc. El problema es que la documentación de yowsup es muy mala, y casi es mejor estudiarse las propias librerías. Cuidado con las pruebas y errores, pues cuando Whatsapp detecta que se está haciendo uso erróneo, cancela al usuario…

Referencias

Mandar y recibir SMS con Gammu en la Raspberry Pi

Enviar un SMS es muy sencillo, pero no quiero engañar a nadie: configurar el modem de forma que la Raspberry Pi lo reconozca puede dar mucha guerra, y ya lo he explicado en este otro post.

Antes de nada, también hay que aclarar que para poder mandar SMS desde la Raspberry Pi según el procedimiento que voy a contar necesitamos tener conectado a la Raspberry Pi un modem GSM (cualquier modem 3G USB actual) con una tarjeta SIM con su correspondiente contrato.

Modem 3G USB Huawei E173u-2

Modem 3G USB Huawei E173u-2

Modem 3G USB Huawei E173u-2

Modem 3G USB Huawei E173u-2

Mandar SMS

Lo primero, una vez que nuestra Raspberry Pi reconoce el modem como tal (ver, como he dicho antes, este otro post en el que lo explico), es instalarnos el programa Gammu:

sudo apt-get install gammu

Ejecuto dmesg | grep tty, y me sale al final:

[ 3101.026510] usb 1-1.4: GSM modem (1-port) converter now attached to ttyUSB0
[ 3101.047379] usb 1-1.4: GSM modem (1-port) converter now attached to ttyUSB1
[ 3101.050728] usb 1-1.4: GSM modem (1-port) converter now attached to ttyUSB2
[ 3101.054227] usb 1-1.4: GSM modem (1-port) converter now attached to ttyUSB3

Apunto el primer puerto (ttyUSB0), que será el puerto que introduciré en la configuración:

sudo gammu-config 
Captura de pantalla 2015-03-21 a las 19.32.41

Configuración de Gammu

No cambio ninguna cosa más que el puerto y listo. El asistente anterior lo que hace es generar el fichero /root/.gammurc, que podremos modificar si queremos más adelante. En mi caso, he hecho pruebas y puedo enviar SMS desde ttyUSB0 y ttyUSB2, pero no del 1 y 3.

Ahora ejecuto el comando sudo gammu --identify para ver que todo está bien, y obtengo:

Dispositivo          : /dev/ttyUSB0
Fabricante           : Huawei
Modelo               : E173 (E173)
Firmware             : 11.126.15.00.18
IMEI                 : 342341311668563
IMSI SIM             : 134546457667592

(he alterado el IMEI y el IMSI SIM).

Así que puedo probar a enviar mi primer SMS:

echo "Hola mundo" | sudo gammu sendsms TEXT 650696969

¡Funciona! Tarda unos 9 segundos desde que se da al enter hasta que llega el SMS al móvil.

Mandar un fichero de texto, o varias líneas

 

También podemos enviar ficheros, siempre con la precaución de la longitud de los mismos.

 

Mandar SMS empleando Python

sudo apt-get install python-gammu

 

 

Recibir SMS

Instalo el programa gammu-smsd:

sudo apt-get install gammu-smsd

Creo el fichero de configuración:

sudo nano /etc/gammu-smsdrc 

Edito algunas partes:

port = /dev/ttyUSB0
connection = at

(No hace falta poner la velocidad at19200 o at152000, basta con at).

Hay muchas más opciones de configuración y qué hacer con los mensajes que llegan, bases de datos MySQL, etc. (ver el manual), pero a mí lo que me interesa es poder ejecutar un comando al recibir un determinao SMS.

Si queremos que se ejecute un comando, añadimos al final:

RunOnReceive = /home/pi/gammu/recibeSMS.sh

(apuntando a la ruta donde tengamos el bash que queremos que se ejecute al recibir el SMS, en mi caso en /home/pi/gammu/recibeSMS.sh. Previamente hay que dar permisos de ejecución a ese fichero: chmod + x /home/pi/gammu/recibeSMS.sh).

Y el fichero /home/pi/gammu/recibeSMS.sh contiene lo que queremos que se ejecute. Por ejemplo:

#!/bin/sh
from=$SMS_1_NUMBER
echo "¡Hola, mundo!" | sudo gammu sendsms TEXT "$from"

O que haga algo determinado, en función del contenido del mensaje:

#!/bin/sh
from=$SMS_1_NUMBER
message=$SMS_1_TEXT
reply=""
 
if test "$message" = "Ping"; then
    reply="Pong!"
else
    reply="Y U NO PLAY PING PONG?"
fi
 
echo "$reply" | sudo gammu sendsms TEXT "$from"

En esta página del manual se explican más acciones.

Para ejecutar el demonio y que esté a la escucha de SMS:

sudo gammu-smsd

(Podremos llamar a este demonio en el arranque, añadiéndolo al /etc/rc.local).

Enviar MMS

First you need to create MMS data (SMIL). Then upload them somewhere
where phone can download it over GPRS
(http://somewehere.something/location in next example). Now you can
send MMS indicator message to phone which will then download the
message:
gammu —sendsms MMSINDICATOR +123456789 \
http://somewehere.something/location \
«Message from Gammu» \
«Gammu program»

MMSETTINGS settings can be used to send MMS settings from Gammu backup
format (you can generate it by gammu –backup).

Referencias