Instalar No-IP en la Raspberry Pi

Voy a explicar a continuación cómo instalar y configurar una cuenta de No-IP para tener una dns dinámica que sea capaz de actualizarse periódicamente para poder solventar el problema que supone la IP dinámica que seguramente nos provee nuestro ISP.

Lo primero, hay que registrarse en no-ip y obtener un nombre de dominio.

A continuación

mkdir noiptemp
cd noiptemp
wget http://www.no-ip.com/client/linux/noip-duc-linux.tar.gz
tar -zxvf noip-duc-linux.tar.gz
cd noip-2.1.9-1/
make
sudo make install

 

Al compilarlo a mí me dio un par de errores:

gcc -Wall -g -Dlinux -DPREFIX=\"/usr/local\" noip2.c -o noip2
noip2.c: In function ‘dynamic_update’:
noip2.c:1595:6: warning: variable ‘i’ set but not used [-Wunused-but-set-variable]
  int i, x, is_group, retval, response;
      ^
noip2.c: In function ‘domains’:
noip2.c:1826:13: warning: variable ‘x’ set but not used [-Wunused-but-set-variable]
         int x;
             ^
noip2.c: In function ‘hosts’:
noip2.c:1838:20: warning: variable ‘y’ set but not used [-Wunused-but-set-variable]
         int     x, y, z;
                    ^

 

Pero son de variables definidas que no se usan, así que no pasa nada.

Ojo, que es posible que haya que cambiar el nombre de la carpeta, si la versión que descarguéis es posterior.

El instalador nos pregunta nuestro correo o nombre de usuario de no-ip, lo introducimos. También el nombre del host, y el intervalo de refresco. Por defecto viene 30 minutos; yo lo cambio a 5 minutos. También pregunta si queremos ejectuar algo tras actualizar la IP; en mi caso digo que no.

El instalador guarda el archivo de configuración en /usr/local/etc/no-ip2.conf

Y ya podemos borrar la carpeta temporal donde descargamos y descomprimimos el instalador.

Ahora que está instalado y configurado, tenemos que hacer que se inicie el proceso cada vez que reiniciemos. Para ello creamos un rc script:

sudo nano /etc/init.d/noip2

 

Y copiamos el siguiente contenido:

### BEGIN INIT INFO
# Provides:          noip2
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start daemon at boot time
# Description:       Enable service provided by daemon.
### END INIT INFO

 #! /bin/sh
# /etc/init.d/noip


# If you want a command to always run, put it here


# Carry out specific functions when asked to by the system
case "$1" in
  start)
    echo "Starting noip"
    # run application you want to start
    /usr/local/bin/noip2
    ;;
  stop)
    echo "Stopping noip"
    # kill application you want to stop
    killall noip2
    ;;
  *)
    echo "Usage: /etc/init.d/noip {start|stop}"
    exit 1
    ;;
esac

exit 0

Y por último:

sudo chmod +x /etc/init.d/noip2
sudo update-rc.d noip2 defaults

Ahora debemos hacer que se arranque tras cada reinicio. Para ello agregamos /usr/local/bin/noip2 al fichero /etc/rc.local, antes de la última línea, donde pone exit 0.

Ya está. Reiniciamos y debería funcionar.

Crear un servidor VPN en una Raspberry Pi

Uno de los primeros proyectos que hice con una Raspberry Pi fue crear un servidor VPN para poder acceder a mi red doméstica y navegar tranquilamente desde conexiones públicas. O, para cuando viajo a países como China, en los que el acceso a ciertas páginas está bloqueado, poder navegar tranquilamente.

Tengo una Raspberry Pi 2 permanentemente encendida, con una distribución OpenElec para usar Kodi al ver la televisión. Quería utilizar esta máquina como servidor VPN, pero tras investigar mucho he decidido desistir por los muchos problemas que tiene el emplear una distribución no completa como es OpenElec. Así que mejor lo hago en otra Raspberry exclusiva (una B), con una distribución decente, como es Raspbian.

Hay miles de tutoriales por internet sobre cómo hacer esto. Yo voy a seguir fundamentalmente este en dos partes, que me parece maravilloso (aunque hay varias cosas que han cambiado con las nuevas versiones de OpenVPN y no se puede seguir tal cual):

Building A Raspberry Pi VPN Part One: How And Why To Build A Server
Building A Raspberry Pi VPN Part Two: Creating An Encrypted Client Side

Configuraré mi portátil del trabajo (Windows), mi portátil personal (Mac) y mi iPhone para poder acceder a la VPN.

Pasos previos

Instalo Raspbian, cambio la contraseña, compruebo que puedo acceder a la Raspberry Pi por SSH, desde otro ordenador conectado a la misma red local. Y actualizo todo con sudo apt-get update y sudo apt-get upgrade.

También tengo que asegurarme de que la Raspberry Pi tiene asignada una IP estática dentro de la red local, o bien a mano (ver esta entrada) o en mi router. Hecho (no explico cómo hacerlo por el router porque en cada router se hace de una forma, aunque todos son similares). Supongamos que es la 192.168.1.45.

También seguramente necesite un servidor dns dinámico como no-ip.com, para poder acceder desde cualquier sitio al servidor, que seguramente tenga una IP dinámica. Puedo hacerlo siguiendo las instrucción ques expliqué en esta entrada.

Una cosa más en el router: debo hacer que todo paquete que llegue al puerto 1194 UDP sea dirigido a mi Raspberry Pi. Hecho (tampoco lo explico, si tienes dudas, googlea tu modelo de router).

Instalando OpenVPN

Instalo OpenVPN:

sudo apt-get install openvpn easy-rsa

 

Se me instala la versión 2.3.4.

Voy a generar las claves RSA. Empiezo por darme permiso de supersusuario, para no tener que andar haciendo sudo todo el rato:

sudo -s

 

Vamos a emplear easy-rsa.

Y ahora:

mkdir /etc/openvpn/easy-rsa
cp /usr/share/easy-rsa/* /etc/openvpn/easy-rsa/
cd /etc/openvpn/easy-rsa
nano /etc/openvpn/easy-rsa/vars

 

Busco dentro del fichero /etc/openvpn/easy-rsa/vars la línea que dice export EASY_RSA="`pwd`" y lo cambio por:

export EASY_RSA=”/etc/openvpn/easy-rsa” 

 

Y ahora genero los certificados, ejecutando los siguientes comandos:

source ./vars
./clean-all
./build-ca

 

¡Ojo! Si no es la primera vez que seguimos estos pasos es posible que ya tengamos algunos certificados generados en el directorio /etc/openvpn/easy-rsa. En este caso, NO debemos ejecutar el comando ./clean-all

Al ejecutar ./build-ca saltarán una serie de preguntas (Country name, State or Province Name, Locality Name, Organization Name, Organizational Unit Name, Common Name, Name), que yo prefiero no rellenar y dejo los valores por defecto, pulsando Enter.

Ahora definimos el nombre del servidor, en mi caso raspivpn:

./build-key-server raspivpn

 

Nuevamente, nos pedirá rellenar una serie de nombres, que dejo en sus valores por defecto, fijándome que el Common Name que me ofrece por defecto y apruebo es el que di al servidor, raspivpn. El Challenge Pasword lo dejo en blanco, y cuando me pregunte “Sign the certificate? [y/n]”, pues diré que sí (y), naturalmente.

Con esto ya tenemos configurado el servidor. Ahora nos queda generar las claves de los clientes y configurarlos.

Creo un certificado para cada usuario:

./build-key-pass usuario1
./build-key-pass usuario2
./build-key-pass usuario3
./build-key-pass usuario4
./build-key-pass usuario5
...

 

Introduzco la contraseña que quiero tenga cuando dice “Enter PEM pass phrase”, y el resto de opciones por defecto.

Y ahora encriptamos las llaves con des3:

openssl rsa -in usuario1.key -des3 -out usuario1.3des.key
openssl rsa -in usuario2.key -des3 -out usuario2.3des.key
openssl rsa -in usuario3.key -des3 -out usuario3.3des.key
openssl rsa -in usuario4.key -des3 -out usuario4.3des.key
openssl rsa -in usuario5.key -des3 -out usuario5.3des.key

 

E introducimos una nueva contraseña (o la misma).

Volvemos al directorio de easy-rsa:

cd /etc/openvpn/easy-rsa/ 

 

Ahora generamos el intercambio de llaves Diffie-Hellman. Esto puede tardar (en mi caso, una hora y cuarto, porque dejé la opción por defecto de encriptación 2048 bit):

./build-dh

 

Y la protección contra un ataque de DoS, generando una llave HMAC estática:

openvpn --genkey --secret keys/ta.key

 

Ya está todo instalado y creado. Falta configurar OpenVPN. Para ello vamos a crear un fichero /etc/openvpn/server.conf con el contenido de este archivo.

nano /etc/openvpn/server.conf

 

Más adelante he descubierto que OpenVPN no arranca tras reiniciar el servidor. Investigando, he llegado a que hay que comentar la primera línea de este fichero: # local 192.168.1.45. Entonces, en mi caso, lo dejo así:

#local 192.168.1.45 # SWAP THIS NUMBER WITH YOUR RASPBERRY PI IP ADDRESS
dev tun
proto udp #Some people prefer to use tcp. Don't change it if you don't know.
port 1194
ca /etc/openvpn/easy-rsa/keys/ca.crt
cert /etc/openvpn/easy-rsa/keys/raspivpn.crt # SWAP WITH YOUR CRT NAME
key /etc/openvpn/easy-rsa/keys/raspivpn.key # SWAP WITH YOUR KEY NAME
dh /etc/openvpn/easy-rsa/keys/dh2048.pem # If you changed to 2048, change that here!
server 10.8.0.0 255.255.255.0
# server and remote endpoints
ifconfig 10.8.0.1 10.8.0.2
# Add route to Client routing table for the OpenVPN Server
push "route 10.8.0.1 255.255.255.255"
# Add route to Client routing table for the OpenVPN Subnet
push "route 10.8.0.0 255.255.255.0"
# your local subnet
push "route 192.168.1.45 255.255.255.0" # SWAP THE IP NUMBER WITH YOUR RASPBERRY PI IP ADDRESS
# Set primary domain name server address to the SOHO Router
# If your router does not do DNS, you can use Google DNS 8.8.8.8
push "dhcp-option DNS 192.168.1.1" # This should already match your router address and not need to be changed.
# Override the Client default gateway by using 0.0.0.0/1 and
# 128.0.0.0/1 rather than 0.0.0.0/0. This has the benefit of
# overriding but not wiping out the original default gateway.
push "redirect-gateway def1"
client-to-client
duplicate-cn
keepalive 10 120
tls-auth /etc/openvpn/easy-rsa/keys/ta.key 0
cipher AES-128-CBC
comp-lzo
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn-status.log 20
log /var/log/openvpn.log
verb 1

 

Otra cosa, tenemos que redirigir el tráfico de internet, ya que Raspbian por defecto no lo hace. Para ello editamos el siguiente fichero:

nano /etc/sysctl.conf

 

Buscamos la línea donde dice:

# Uncomment the next line to enable packet forwarding for IPv4
#net.ipv4.ip_forward=1

 

Y lo descomentamos:

# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1

 

Aplicamos los cambios con el siguiente comando:

sysctl -p

 

Ahora queda desbloquear OpenVPN en el firewall, y además hacer que se haga en cada reinicio, ya que las excepciones del cortafuegos no se quedan grabadas. Para ello creamos este pequeño script:

nano /etc/firewall-openvpn-rules.sh

 

Y dentro del fichero escribimos lo siguiente:

#!/bin/sh
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j SNAT --to-source 192.168.1.45

 

Grabamos y salimos. Ahora toca darle permisos de ejecución a este fichero, y cambiarle el usuario a root:

chmod 700 /etc/firewall-openvpn-rules.sh 
chown root /etc/firewall-openvpn-rules.sh

 

En las versiones anteriores de Raspbian, bastaba con editar el fichero /etc/network/interfaces:

nano /etc/network/interfaces

 

buscar la línea:

iface eth0 inet manual

 

y debajo de ella, con un sangrado, añadir:

    pre-up /etc/firewall-openvpn-rules.sh

 

Pero si se tiene Raspbian Jessie o superior, hay que añadir además “auto eth0” en la línea anterior, de forma que finalmente debe quedar así:

auto eth0
iface eth0 inet manual
   pre-up /etc/firewall-openvpn-rules.sh

 

Con esto ya garantizamos que tras cada reinicio se abre el Firewall para OpenVPN. Así que reiniciamos la Raspberry Pi:

reboot

 

Configurando el cliente

Ya tenemos el servidor VPN en marcha. Ahora vamos a configurar los clientes.

Pero seguimos todavía en el servidor. Vamos a crear los ficheros de configuración que instalaremos en los clientes.

Creamos un fichero:

nano /etc/openvpn/easy-rsa/keys/Default.txt

Y copiamos lo siguiente:

client
dev tun
proto udp
remote TU-SERVIDOR-AQUI 1194
resolv-retry infinite
nobind
persist-key
persist-tun
mute-replay-warnings
ns-cert-type server
key-direction 1
cipher AES-128-CBC
comp-lzo
verb 1
mute 20 

Donde dice TU-SERVIDOR-AQUI pondremos la dirección pública de nuestro servidor. Puede ser una IP, o un nombre como mi.servidorVPN.com. Lo más probable es que aquí pongas una dirección de dominio dinámico gratuita como las que ofrece no-ip.com, que expliqué cómo se hace en otro post.

Ahora para generar los ficheros de configuración de cada cliente descargamos este pequeño script maravilloso aquí, y copiamos su contenido en un fichero en /etc/openvpn/easy-rsa/keys/MakeOVPN.sh (he corregido dos cosas menores):

#!/bin/bash 
 
# Default Variable Declarations 
DEFAULT="Default.txt" 
FILEEXT=".ovpn" 
CRT=".crt" 
KEY=".3des.key" 
CA="ca.crt" 
TA="ta.key" 
 
#Ask for a Client name 
echo "Please enter an existing Client Name:"
read NAME 
 
 
#1st Verify that client’s Public Key Exists 
if [ ! -f $NAME$CRT ]; then 
 echo "[ERROR]: Client Public Key Certificate not found: $NAME$CRT" 
 exit 
fi 
echo "Client’s cert found: $NAME$CR" 
 
 
#Then, verify that there is a private key for that client 
if [ ! -f $NAME$KEY ]; then 
 echo "[ERROR]: Client 3des Private Key not found: $NAME$KEY" 
 exit 
fi 
echo "Client’s Private Key found: $NAME$KEY"

#Confirm the CA public key exists 
if [ ! -f $CA ]; then 
 echo "[ERROR]: CA Public Key not found: $CA" 
 exit 
fi 
echo "CA public Key found: $CA" 

#Confirm the tls-auth ta key file exists 
if [ ! -f $TA ]; then 
 echo "[ERROR]: tls-auth Key not found: $TA" 
 exit 
fi 
echo "tls-auth Private Key found: $TA" 
 
#Ready to make a new .opvn file - Start by populating with the default file 
cat $DEFAULT > $NAME$FILEEXT 
 
#Now, append the CA Public Cert 
echo "" >> $NAME$FILEEXT 
cat $CA >> $NAME$FILEEXT 
echo "" >> $NAME$FILEEXT

#Next append the client Public Cert 
echo "" >> $NAME$FILEEXT 
cat $NAME$CRT | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' >> $NAME$FILEEXT 
echo "" >> $NAME$FILEEXT 
 
#Then, append the client Private Key 
echo "" >> $NAME$FILEEXT 
cat $NAME$KEY >> $NAME$FILEEXT 
echo "" >> $NAME$FILEEXT 
 
#Finally, append the TA Private Key 
echo "" >> $NAME$FILEEXT 
cat $TA >> $NAME$FILEEXT 
echo "" >> $NAME$FILEEXT 
 
echo "Done! $NAME$FILEEXT Successfully Created."

#Script written by Eric Jodoin
#No newline at end of file

 

Damos permiso de ejecución al script:

cd /etc/openvpn/easy-rsa/keys/
chmod 700 MakeOVPN.sh

 

Y ejecutamos el script:

./MakeOVPN.sh

 

Nos pide el nombre del cliente. Introduzco usuario1, trabaja un poco y crea el fichero usuario1.ovpn. Repito con el resto de usuarios.

De esta forma se me generan unos ficheros usuario1.ovpn, usuario2.ovpn, etc. que son los que cargaré a continuación en los clientes.

Basta con cargar el fichero .ovpn, introducir la contraseña, y listo.

Lo he probado de forma exitosa en:

iPhone, con OpenVPN.
Mac, con TunnelBlick
Windows, con OpenVPN Connect

Me consta que OpenVPN Connect también funciona en Android, pero no lo he probado.

Referencias

Raspberry Pi Powered OpenVPN – Server

IP estática en la Raspberry Pi

Hay varias formas de asignar una IP estática a nuestra Raspberry Pi. Una de ellas es entrar en la configuración del router, averiguar la dirección MAC de la tarjeta de red o wifi de la Raspberry Pi, y asignarle desde ahí una IP estática. Otra forma es configurando la propia Raspberry para que tenga la IP estática, que es como voy a explicar aquí.

Lo primero que tenemos que hacer es conectar nuestra Raspberry Pi por cable a la red. Si el router o servidor tiene un servicio DHCP, habrá asignado automáticamente una dirección IP a nuestra máquina. A continuación, ejecutamos el comando ifconfig y obtenemos información de la red, que vamos a necesitar para configurar adecuadamente la IP estática:

ifconfig

Obtenemos la siguiente pantalla:
Captura

Me fijo en inet addr:192.168.1.45, Bcast:192.168.1.255 y Mask:255.255.255.0

Ejecuto ahora el comando netstat -nr:

netstat -nr

Y obtengo:
Captura

Me fijo en: Gateway 192.168.1.1 y Destination 192.168.1.0

Con estos datos ya podría editar el fichero /etc/network/interfaces e introducir ahí la configuración de la IP estática. ¡Pero desde la versión 20150505 de Raspbian (Jessie) ya no se hace así! Ahora hay un demonio llamado dhcpcd, que cambia un poco cómo sea hace.

Lo más fácil es editar el fichero /etc/dhcpcd.conf y añadir al final:

# IP estática en eth0:
interface eth0
static ip_address=192.168.1.45/24
static routers=192.168.1.1
static domain_name_servers=192.168.1.1

El /24 tras la dirección IP indica que la netmask es 255.255.255.0, como obtuvimos arriba.

sudo nano /etc/network/interfaces

Ya está. Reiniciamos y listo.

Referencias
ModMyPi
Sizious.com

Display Adafruit 0.56” de 4 dígitos de 7 segmentos I2C en la Raspberry Pi

En este post expliqué cómo hacer funcionar un display de 4 dígitos de 7 segmentos con la Raspberry Pi. Ahora voy a explicar como hacerlo de forma más sencilla, empleando el display de Adafruit, que lleva un controlador incorporado y podemos controlarlo por medio de I2C empleando sólo cuatro cables. Está todo muy bien explicado en la página de Adafruit, así que sigo tal cual los pasos allí indicados.

Lo primero que tenemos que hacer es configurar la Raspberry Pi para I2C.
Luego ejecuto sudo raspi-config y activo I2C, indicando que se cargue en el arranque:
8- Advanced Options
A7 I2C Enable/Disable automatic loading of I2C Kernel module
Would you like the ARM I2C interface to be enabled?
Would you like the I2C kernel module to be loaded by default?

Edito el fichero sudo nano /etc/modules y añado estas dos líneas al final:

i2c-bcm2708 
i2c-dev

Edito el fichero sudo nano /boot/config.txt y añado al final:

dtparam=i2c1=on
dtparam=i2c_arm=on

Reinicio.

Ahora instalo lo siguiente:

sudo apt-get install python-smbus i2c-tools

Ahora conecto el display, de la siguiente forma:

Display VCC —-> RPi 5V (por ejemplo, pin 5)
Display GND —-> RPi GND (por ejemplo, pin6)
Display SDA —-> RPi SDA (pin 3)
Display SCL —-> RPi SCL (pin 5)

Compruebo a ver si funciona, ejecutando:

sudo i2cdetect -y 1

Me sale:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: 70 -- -- -- -- -- -- --   

El 70 está indicando que tengo algo conectado ahí, así que por el momento, todo bien.

Ahora me voy a instalar las librerías de Adafruit:

sudo apt-get install git
git clone https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code.git
cd Adafruit-Raspberry-Pi-Python-Code
cd Adafruit_LEDBackpack 

Y pruebo el ejemplo del reloj:

sudo python ex_7segment_clock.py

¡Funciona!

Referencias

Sensores de humedad y temperatura DHT11 y DTH22 en la Raspberry Pi

Existen varios sensores de humedad relativa, entre los cuales el DHT11 y el DHT22 son de los más comunes. El DHT11 es muy barato (alrededor de 2-3€ si lo compras desde China, 8-10€ en España), pero con algo menos de precisión tanto en la humedad como en la temperatura que la que da su hermano mayor, el DHT22, que es algo más caro. Puede verse una tabla comparativa de ambos modelos aquí.

Vamos a empezar conectando el sensor de humedad y temperatura DHT11 a la Raspberry Pi y tomar lecturas. Y después haremos lo mismo con el DHT22.

Sensor de humedad DTH11

Sensor de humedad DHT11

Sensor de humedad DTH22

Sensor de humedad DHT22

Sensores de humedad y temperatura DTH11 y DTH22

Sensores de humedad y temperatura DHT11 y DHT22

Hace falta además una resistencia entre el pin de alimentación y el de datos, aunque se puede comprar el sensor en una mini placa con la resistencia incorporada, como el caso del sensor que tengo yo y que se ve en la imagen de arriba.

En muchas páginas se explica cómo conectar el sensor a la Raspberry Pi (ver más abajo), y todas lo hacen al pin GPIO4 (pin 7). Como en el proyecto que estoy haciendo ahora mismo ya tengo conectado ahí un termómetro DS18B20 (ver este post), voy a conectarlo el GPIO5 (pin 29). Bastará con cambiar el código según a dónde lo conectemos.

Entonces lo conecto así:

  • GND del sensor a un pin GND de la RPi, en mi caso al 20
  • S (datos) al GPIO 5 (pin 29 de la Raspberry Pi)
  • 3V3 a uno de los 3V3 de la Raspberry Pi, en mi caso al 17.

Y ahora, el código para tomar las lecturas. Googleando se pueden encontrar varias formas de hacerlo. El problema en todas ellas es que linux no es un sistema operativo de tiempo real, y como el sensor requiere medidas muy rápidas consecutivas, esto puede suponer un problema. He visto varios ejemplos en Python y en C; en C funciona mejor porque es de más bajo nivel. De todas maneras, en todos los casos advierten de que en ocasiones da error en la lectura y hay que intentarlo varias veces.

Vamos a emplear el código de Adafruit. Es necesario hacer lo siguiente:

git clone https://github.com/adafruit/Adafruit_Python_DHT.git
cd Adafruit_Python_DHT

Hay que tener instaladas las siguientes librerías (que tal vez ya tengas instaladas):

sudo apt-get update
sudo apt-get install build-essential python-dev python-openssl

Y ahora compilamos la librería de Adafruit:

sudo python setup.py install

Tras instalarse, probamos a ver si funciona:

cd examples
sudo ./AdafruitDHT.py 11 5

Con esto estoy diciendo que lea los datos del sensor DHT11 (podría ser el DHT22 o el AM2302), conectado al pin GPIO 5.

Y con esto obtenemos la lectura de temperatura y humedad:

Temp=28.0*C  Humidity=29.0%

¡Funciona!

Vamos a probar ahora el sensor DHT22. Lo primero que tengo que hacer es soldarle la resistencia. En algunos sitios he visto que la resistencia debe ser de 4.7KΩ, y en otros, que debe ser de 10KΩ.

thumb_IMG_7031_1024

Soldando la resistencia al sensor DHT22

thumb_IMG_7032_1024

Y lo conecto a la Raspberry Pi de la siguiente forma:

dht22 temperature and humidty sensor circuitry wiring

thumb_IMG_7033_1024

Sensor DHT22 conectado a la Raspberry Pi

Sigo los pasos de instalación de más arriba, y cuando ejecuto:

sudo ./AdafruitDHT.py 22 4

Tras un par de segundos obtengo:

Temp=29.0*C  Humidity=26.4%

¡Funciona!

Los dos sensores funcionando al mismo tiempo, el DHT22 conectado al GPIO4, y el DHT11 al GPIO5:

Sensores DHT11 y DHT22 conectados a la Raspberry Pi

Sensores DHT11 y DHT22 conectados a la Raspberry Pi

 

Referencias

  • http://fpaez.com/sensor-dht11-de-temperatura-y-humedad/
  • http://www.uugear.com/portfolio/dht11-humidity-temperature-sensor-module/
  • https://learn.adafruit.com/dht-humidity-sensing-on-raspberry-pi-with-gdocs-logging/wiring

Copiar y pegar con nano

Nano es un editor de textos muy simplón y muy utilizado en linux. Viene instalado por defecto en la mayoría de las distribuciones de linux, por ejemplo en Raspbian, el sistema operativo basado en Debian que emplea la Raspberry Pi.

Como siempre se me olvidan los atajos de teclado del programa para copiar y pegar, los pongo aquí.

  • Selecccionar: ALT + m + a
  • Seleccionar: Ctrl+^ (para marcar el comienzo, luego nos desplazamos hasta el fin, y otra vez Ctrl+^)
  • Copiar: ALT + 6
  • Cortar la línea actual: CTRL + k
  • Pegar: CTRL + u

Otros atajos de teclado del nano son:

  • Ctrl + g: muestra pantalla de atajos

 

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/

Internet móvil con el modem 3G USB Huawei E303 en la Raspberry Pi

En este post expliqué cómo hacer funcionar el modem 3G Huawei E173 en la Raspberry Pi. Tengo ahora un módem E303 (en concreto E303h-1), y voy a intentar lo mismo.

El Huawei E303 es un dispositivo de internet móvil que funciona con redes 3G, EDGE, GPRS, GSM, HSDPA y HSUPA, y soporta las bandas GSM de 2100, 850, 900, 1800 y 1900 MHz.

Como ya expliqué, puede ser una tarea difícil. Uno de los motivos es que estos “pinchos USB” suelen llevar una memoria interna, o una ranura para una tarjeta microUSB, y la Raspberry Pi no lo reconoce como un módem sino como un dispositivo de almacenamiento (que es la intención de los fabricantes, para que al conectarlo a un PC con Windows, este automáticamente instale los drivers desde el almacenamiento). Para solucionar esto, y que la Raspberry Pi reconozca al dispositivo como lo que es, un modem, hay que recurrir al programa usb-modeswitch, y hay que prepararse para dedicarle muchas horas de búsqueda por internet para tu configuración, y luego mil pruebas…

IMG_6242

Dispositivo Huawei E303. Vista frontal

IMG_6243

Dispositivo Huawei E303. Vista trasera

IMG_6244

Dispositivo Huawei E303. Vista sin la tapa

Conseguir que la Raspberry Pi reconozca el modem Huawei E303

Antes de nada hay que asegurarse de que nuestra Raspberry Pi está bien alimentada, pues el modem 3G puede consumir bastante corriente. Lo segundo es que hayamos quitado el pin de la tarjeta SIM que hemos introducido en el modem 3G (esto generalmente lo podremos hacer o bien desde un móvil, o desde el programita/página web que salta por defecto al conectar el pincho a un PC).

Conecto el pincho y ejecuto el comando lsusb. Me sale, entre otros dispositivos USB que tengo conectados, este:

Bus 001 Device 006: ID 12d1:1f01 Huawei Technologies Co., Ltd. 

Si desconecto el pincho, ejecuto el comando tail -f /var/log/messages, y vuelvo a conectar el pincho sale:

Apr 18 10:07:25 piglobo2a kernel: [ 4792.775768] usb 1-1.4: new high-speed USB device number 7 using dwc_otg
Apr 18 10:07:25 piglobo2a kernel: [ 4792.877566] usb 1-1.4: New USB device found, idVendor=12d1, idProduct=1f01
Apr 18 10:07:25 piglobo2a kernel: [ 4792.877606] usb 1-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Apr 18 10:07:25 piglobo2a kernel: [ 4792.877625] usb 1-1.4: Product: HUAWEI Mobile
Apr 18 10:07:25 piglobo2a kernel: [ 4792.877642] usb 1-1.4: Manufacturer: HUAWEI
Apr 18 10:07:25 piglobo2a kernel: [ 4792.877660] usb 1-1.4: SerialNumber: FFFFFFFFFFFFFFFF
Apr 18 10:07:25 piglobo2a kernel: [ 4792.932324] usb-storage 1-1.4:1.0: USB Mass Storage device detected
Apr 18 10:07:25 piglobo2a kernel: [ 4792.933467] scsi host2: usb-storage 1-1.4:1.0
Apr 18 10:07:26 piglobo2a kernel: [ 4793.954310] scsi 2:0:0:0: CD-ROM            HUAWEI   Mass Storage     2.31 PQ: 0 ANSI: 2
Apr 18 10:07:26 piglobo2a kernel: [ 4794.052926] sr 2:0:0:0: [sr0] scsi-1 drive
Apr 18 10:07:26 piglobo2a kernel: [ 4794.054690] sr 2:0:0:0: Attached scsi generic sg1 type 5
Apr 18 10:07:26 piglobo2a kernel: [ 4794.073335] scsi 2:0:0:1: Direct-Access     HUAWEI   TF CARD Storage  2.31 PQ: 0 ANSI: 2
Apr 18 10:07:26 piglobo2a kernel: [ 4794.075205] sd 2:0:0:1: Attached scsi generic sg2 type 0
Apr 18 10:07:26 piglobo2a kernel: [ 4794.081446] sd 2:0:0:1: [sdb] Attached SCSI removable disk

Lo está reconociendo como una unidad de almacenamiento, y no como un modem, que es lo que quiero. Entonces tengo que instalar el programa usb_modeswitch:

sudo apt-get install usb-modeswitch

Si ahora hago lsusb obtengo:

Bus 001 Device 010: ID 12d1:14dc Huawei Technologies Co., Ltd.

Es decir, ha cambiado el id original 12d1:1f01 por el nuevo 12d1:14dc.

Y si hago de nuevo tail -f /var/log/messages, obtengo:

Apr 18 10:15:12 piglobo2a kernel: [ 5260.033848] usb 1-1.4: new high-speed USB device number 11 using dwc_otg
Apr 18 10:15:12 piglobo2a kernel: [ 5260.135921] usb 1-1.4: New USB device found, idVendor=12d1, idProduct=1f01
Apr 18 10:15:12 piglobo2a kernel: [ 5260.135960] usb 1-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Apr 18 10:15:12 piglobo2a kernel: [ 5260.135980] usb 1-1.4: Product: HUAWEI Mobile
Apr 18 10:15:12 piglobo2a kernel: [ 5260.135998] usb 1-1.4: Manufacturer: HUAWEI
Apr 18 10:15:12 piglobo2a kernel: [ 5260.136018] usb 1-1.4: SerialNumber: FFFFFFFFFFFFFFFF
Apr 18 10:15:13 piglobo2a kernel: [ 5260.267266] usb-storage 1-1.4:1.0: USB Mass Storage device detected
Apr 18 10:15:13 piglobo2a kernel: [ 5260.276429] scsi host6: usb-storage 1-1.4:1.0
Apr 18 10:15:13 piglobo2a usb_modeswitch: switching device 12d1:1f01 on 001/011
Apr 18 10:15:14 piglobo2a kernel: [ 5261.336395] usb 1-1.4: USB disconnect, device number 11
Apr 18 10:15:14 piglobo2a kernel: [ 5261.823824] usb 1-1.4: new high-speed USB device number 12 using dwc_otg
Apr 18 10:15:14 piglobo2a kernel: [ 5261.925562] usb 1-1.4: New USB device found, idVendor=12d1, idProduct=14dc
Apr 18 10:15:14 piglobo2a kernel: [ 5261.925603] usb 1-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
Apr 18 10:15:14 piglobo2a kernel: [ 5261.925623] usb 1-1.4: Product: HUAWEI Mobile
Apr 18 10:15:14 piglobo2a kernel: [ 5261.925643] usb 1-1.4: Manufacturer: HUAWEI
Apr 18 10:15:14 piglobo2a kernel: [ 5262.165445] cdc_ether 1-1.4:1.0 eth1: register 'cdc_ether' at usb-bcm2708_usb-1.4, CDC Ethernet Device, 00:1e:10:1f:00:00
Apr 18 10:15:14 piglobo2a kernel: [ 5262.167221] usb-storage 1-1.4:1.2: USB Mass Storage device detected
Apr 18 10:15:14 piglobo2a kernel: [ 5262.168907] scsi host7: usb-storage 1-1.4:1.2
Apr 18 10:15:15 piglobo2a kernel: [ 5263.169241] scsi 7:0:0:0: Direct-Access     HUAWEI   TF CARD Storage  2.31 PQ: 0 ANSI: 2
Apr 18 10:15:15 piglobo2a kernel: [ 5263.173135] sd 7:0:0:0: [sdb] Attached SCSI removable disk
Apr 18 10:15:15 piglobo2a kernel: [ 5263.175278] sd 7:0:0:0: Attached scsi generic sg1 type 0

Lo que está pasando es que la Raspberry Pi está reconociendo al modem 3G como una interfaz de red, pues este modem tiene esa propiedad HiLink de algunos Huawei.

Con esto ya tenemos una nueva “tarjeta de red”, y podríamos empezar a navegar haciendo lo siguente:

sudo nano /etc/network/interfaces

y añadimos este nuevo dispositivo ethernet eth1:

auto lo

iface lo inet loopback
iface eth0 inet dhcp

<strong>iface eth1 inet dhcp</strong>

allow-hotplug wlan0
iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp

Reiniciamos, y el pincho nos asignará la IP 192.168.8.100.

Y ya tenemos conexión a internet en la Raspberry Pi a través del pincho Huawei E303.

No hemos acabado todavía…

Pero yo quiero emplear este pincho para mandar SMS también, así que este procedimiento tan sencillo y maravilloso no me vale, pues no se reconoce el modem como tal. Tengo que especificar a usb-modeswitch que cambie no al modo HiLink, sino a otro modo.

Lo primero, editamos el fichero /etc/usb_modeswitch.conf haciendo que EnableLogging=1. De esta forma, el fichero de registro /var/log/usb_modeswitch_XXXXXXXXXXXX contendrá más información, que nos será muy útil en todas las pruebas que seguramente tengamos que hacer.. Cada vez que desconecte y reconecte el modem USB, veré el contenido de ese fichero para ver los pasos que sigue el programa.

En la página web de Usb_modeswitch se explica muy bien el funcionamiento del programa. Como en mi caso se cambia al modo HiLink, significa que usb_modeswitch reconoce bien el dispositivo y lo cambia correctamente, esto significa que la configuración está ya en la base de datos. Pero quiero cambiar al otro modo.

Continuo probando. En el fichero /usr/share/usb_modeswitch/configPack.tar.gz encuentro el fichero 12d1:1f01, con el siguiente contenido:

# Huawei E353 (3.se)

TargetVendor=  0x12d1
TargetProduct= 0x14db

MessageContent="55534243123456780000000000000a11062000000000000100000000000000"
NoDriverLoading=1

Hay algo raro, pues realmente carga el 14dc y no el 14db, pero me da igual, porque lo voy a pisar. Podemos hacer que usb-modeswitch pase de esta configuración y lea la que nosotros queramos, si colocamos el fichero correspondiente en /etc/usb_modeswitch.d/. Por defecto está vacío, así que voy a crear ahí el fichero con el que haré pruebas:

sudo nano /etc/usb_modeswitch.d/12d1\:1f01

(ojo con el \:). En ese fichero pego lo siguiente:

# Huawei E303
DefaultVendor= 0x12d1
DefaultProduct= 0x1f01
TargetVendor= 0x12d1
TargetProduct= 0x1001
MessageContent="55534243123456780000000000000011063000000100010000000000000000"

He llegado a esta configuración tras buscar mucho por internet y hacer muchas pruebas, pues hay varios modos que funcionan, pero sólo he encontrado éste en el que funcionase tanto GSM como 3G.

Otras configuraciones que funcionaron (sólo como 3G) fueron:

# Huawei E303
DefaultVendor= 0x12d1
DefaultProduct= 0x1f01
TargetVendor= 0x12d1
TargetProduct= 0x1442
MessageContent="55534243123456780000000000000011060000000000000000000000000000"

Y esta otra:

# Huawei E303
DefaultVendor= 0x12d1
DefaultProduct= 0x1f01
TargetVendor= 0x12d1
TargetProduct= 0x1442
MessageContent="55534243000000000000000000000011060000000000000000000000000000"

Pruebo ahora a desconectar el pincho y volverlo a conectar. Al cabo de unos segundo siempre lo acaba reconociendo. Hago lo mismo reiniciando, y siempre lo reconoce. Así que no tengo que hacer ninguna de las trampas a las que tuve que recurrir con el Huawei E173.

También podría haberlo hecho ejecutando directamente el comando:

sudo usb_modeswitch -v 0x12d1 -p 0x1f01 -V 0x12d1 -P 0x1001 -M "55534243000000000000000000000011060000000000000000000000000000" -n -I

(aunque esto me cambia a 12d1:1442)

Ahora edito el fichero /etc/usb_modeswitch.conf y vuelvo a dejar EnableLogging=0 para dejarlo todo como estaba originalmente. Reinicio un par de veces con el modem enchufado y parece que todo funciona. Así que puedo pasar al siguiente paso.

Instalando el demonio pppd, UMTSKeeper y Sakis3G

El programa más utilizado para realizar la conexión 3G es Sakis3g. Sin embargo, antes de lanzarnos a instalarlo, tenemos que saber que es muy frecuente perder la conexión 3G cada cierto tiempo, por lo que se suele recurrir a otro programa, UMTSKeeper, que está constantemente comprobando la conexión y recuperándola cuando se cae. Como este último programa instala por su cuenta Sakis, no es necesario que instalemos Sakis antes.

Así que empezamos. Lo primero es instalarse el servicio pppd:

sudo apt-get install ppp

A continuación instalamos UMTSKeeper:

cd ~
mkdir umtskeeper
cd umtskeeper
wget "http://mintakaconciencia.net/squares/umtskeeper/src/umtskeeper.tar.gz"
tar -xzvf umtskeeper.tar.gz
chmod +x sakis3g umtskeeper

Ahora, configuramos sakis:

sudo ./sakis3g --interactive 
Configruación Sakis 3G Pantalla 1

Configuración Sakis 3G Pantalla 1

Configruación Sakis 3G Pantala 2

Configuración Sakis 3G Pantalla 2

Configuración Sakis 3G Pantalla 3

Configuración Sakis 3G Pantalla 3

Configuración Sakis 3G Pantalla 4

Configuración Sakis 3G Pantalla 4

Configuración Sakis 3G Pantalla 5

Configuración Sakis 3G Pantalla 5

Configuración Sakis 3G Pantalla 6

Configuración Sakis 3G Pantalla 6

Configuración Sakis 3G Pantalla 7

Configuración Sakis 3G Pantalla 7

Si ahora hago ifconfig, obtengo, entre otras cosas:

ppp0      Link encap:Point-to-Point Protocol  
          inet addr:88.29.125.147  P-t-P:10.64.64.64  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:7 errors:0 dropped:0 overruns:0 frame:0
          TX packets:10 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:3 
          RX bytes:130 (130.0 B)  TX bytes:333 (333.0 B)

Así que efectivamente, tenemos conexión a internet por ppp0.

Y por último, configuro UMTSKeeper. Ejecuto el siguiente comando (una sola línea), que luego añadiré a /etc/rc.local para que se ejecute siempre que se arranque la Raspberry Pi:

sudo /home/pi/umtskeeper/umtskeeper --sakisoperators "USBINTERFACE='0' OTHER='USBMODEM' USBMODEM='12d1:1001' APN='movistar.es' CUSTOM_APN='movistar.es' APN_USER='0' APN_PASS='0'" --sakisswitches "--sudo --console" --devicename 'Huawei' --log --silent --monthstart 8 --nat 'no' --httpserver &amp;&gt;&gt; /home/pi/umtskeeper/error.log &amp;

Consulto el fichero /var/log/umtskeeper.log y veo que está todo en orden. Pruebo a desconectar y reconectar el pincho USB, y veo que tras medio minuto vuelve a conectarse automáticamente.

Así que he conseguido:

  1. Que la Raspberry Pi reconozca el modem USB 3G como modem y no como unidad de alamacenamiento, y que lo haga tras un reinicio
  2. Que se conecte a internet a través del modem USB
  3. Que mantenga la conexión mientras la Raspberry Pi esté fucnionando, bien tras caidas de la red, o por desenchufar-reenchufar el modem 3G

¡Prueba superada!

Referencias

Display de 4 dígitos de 7 segmentos en la Raspberry Pi

Para el monitor de bebé que estoy construyendo quiero un display en el que mostrar la temperatura de un sensor, la humedad, y ya de paso, la hora. Voy a emplear el siguiente display de 4 dígitos de 7 segmentos (ver hoja de referencia aquí):

4x7LED1

Lo compré aquí por menos de 2€. Hay varios modelos muy similares, con dos puntos entre el tercer y cuarto dígito, con algún puntito más, pero se manejan todos de la misma forma.

Buceando por google, encontré un par de páginas que explican (más o menos), cómo llegar a hacerlos funcionar conectados a una Raspberry Pi. Pongo los links más abajo.

Lo primero es conocer el funcionamiento del display, que no es más que 4 bloques (dígitos) de números que aparecen representados por 7 leds (por eso se llaman 7 segmentos, aunque en realidad este modelo tiene un led/segmento más, por el punto decimal).

220px-7_segment_display_labeled.svg

Cada segmento se numera de A a G, y el punto decimal (DP).

Como tener encendidos todos los leds que necesitásemos indistintamente al mismo tiempo para representar los números correspondientes en el display requeriría más corriente de la que la Raspberry puede proporcionar, se recurre a una técnica llamada multiplexing, que consiste en ir encendiendo sucesivamente y de forma muy rápida cada uno de los segmentos que queremos tener encendidos, de forma que el ojo humano no es capaz de percibir que en realidad no están todos encendidos al mismo tiempo.

4x7LED2

4x7LED3-2

Esquema

4x7LED5

La conexión con la Raspberry Pi la hago según el siguiente esquema, empleando una resistencia para cada segmento (las conexiones de los 4 dígitos no llevan resistencias):

FW0Y6QZI2BYJMXU.LARGE

No voy a explicar el funcionamiento del GPIO de la Raspberry Pi, pero es bastante sencillo (y maravilloso). Estudiando el código más abajo se puede entender muy fácilmente.

Y lo monto todo de manera pseudo-definitiva sobre una placa:

image2

Display de 4 dígitos de 7 segmentos. Montaje sobre placa (vista frontal)

image3

Display de 4 dígitos de 7 segmentos. Montaje sobre placa (vista trasera, con algunas soldaduras algo chapurreras)

El código que empleo para que el display actúe como un reloj es el siguiente (tomado y modificado de aquí), que guardo en un fichero llamado reloj.py:

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)

segments = (24,12,19,21,23,22,15,11)

for segment in segments:
        GPIO.setup(segment, GPIO.OUT)
        GPIO.output(segment, 0)

digits = (26,18,16,13)

for digit in digits:
        GPIO.setup(digit, GPIO.OUT)
        GPIO.output(digit, 1)

num =  {' ':(0,0,0,0,0,0,0),
        '0':(1,1,1,1,1,1,0),
        '1':(0,1,1,0,0,0,0),
        '2':(1,1,0,1,1,0,1),
        '3':(1,1,1,1,0,0,1),
        '4':(0,1,1,0,0,1,1),
        '5':(1,0,1,1,0,1,1),
        '6':(1,0,1,1,1,1,1),
        '7':(1,1,1,0,0,0,0),
        '8':(1,1,1,1,1,1,1),
        '9':(1,1,1,1,0,1,1)}

try:
        while True:
            n = time.ctime()[11:13]+time.ctime()[14:16]
            s = str(n).rjust(4)
            for digit in range(4):
                for loop in range(0,7):
                    GPIO.output(segments[loop], num[s[digit]][loop])

                if (int(time.ctime()[18:19])%2 == 0) and (digit == 1):
                    GPIO.output(11, 1)
                else:
                    GPIO.output(11, 0)

                GPIO.output(digits[digit], 0)
                time.sleep(0.001)
                GPIO.output(digits[digit], 1)

except KeyboardInterrupt:

        GPIO.cleanup()

Para ejecutarlos, basta con hacer sudo python reloj.py.

Y como lo que quiero es que el display no sólo muestre la hora, sino que también muestre la temperatura de un termómetro DS18B20 que tengo conectado a la Raspberry Pi, y que se vaya alternando la hora y la temperatura cada 5 segundos, empleo el suguiente código, que guardo en un fichero llamado relojYtemp.py:

import os #Para el termómetro
import RPi.GPIO as GPIO
import time

#Cargo los módulos para el termómetro:
os.system("sudo modprobe wire")
os.system("sudo modprobe w1-gpio")
os.system("sudo modprobe w1-therm")

#Función para obtener la temperatura del sensor interior:
def get_temp_sens1():
        try:
                tfile = open("/sys/bus/w1/devices/28-00000557e1a7/w1_slave")
                text = tfile.read()
                tfile.close()
                secondline = text.split("\n")[1]
                temperaturedata = secondline.split(" ")[9]
                temperature = float(temperaturedata[2:])
                temperature = temperature / 1000
                temperature = round (temperature,1)
        except:
                temperature = 0
        return float(temperature)

#print get_temp_sens1()

GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)

segments = (24,12,19,21,23,22,15,11)

for segment in segments:
        GPIO.setup(segment, GPIO.OUT)
        GPIO.output(segment, 0)

digits = (26,18,16,13)

for digit in digits:
        GPIO.setup(digit, GPIO.OUT)
        GPIO.output(digit, 1)

num =  {' ':(0,0,0,0,0,0,0),
        '0':(1,1,1,1,1,1,0),
        '1':(0,1,1,0,0,0,0),
        '2':(1,1,0,1,1,0,1),
        '3':(1,1,1,1,0,0,1),
        '4':(0,1,1,0,0,1,1),
        '5':(1,0,1,1,0,1,1),
        '6':(1,0,1,1,1,1,1),
        '7':(1,1,1,0,0,0,0),
        '8':(1,1,1,1,1,1,1),
        '9':(1,1,1,1,0,1,1)}


try:
        while True:
            temp = str(int(get_temp_sens1()*10)).rjust(4)

            t_fin = time.time() + 5
            while time.time() &lt; t_fin:
                for digit in range(4):
                    for loop in range(0,7):
                        GPIO.output(segments[loop], num[temp[digit]][loop])

                    if (digit == 2):
                        GPIO.output(11, 1)
                    else:
                        GPIO.output(11, 0)

                    GPIO.output(digits[digit], 0)
                    time.sleep(0.001)
                    GPIO.output(digits[digit], 1)

            t_fin = time.time() + 5
            while time.time() &lt; t_fin:
                n = time.ctime()[11:13]+time.ctime()[14:16]
                s = str(n).rjust(4)
                for digit in range(4):
                    for loop in range(0,7):
                        GPIO.output(segments[loop], num[s[digit]][loop])

                    if (int(time.ctime()[18:19])%2 == 0) and (digit == 1):
                        GPIO.output(11, 1)
                    else:
                        GPIO.output(11, 0)

                    GPIO.output(digits[digit], 0)
                    time.sleep(0.001)
                    GPIO.output(digits[digit], 1)


except KeyboardInterrupt:

        GPIO.cleanup()

(Ya expliqué en este post cómo usar el sensor de temperatura DS180B20 con la Raspberry Pi).

Display de 4 dígitos de 7 segmentos, conectado a la Raspberry Pi junto con sensor DS18B20

Display de 4 dígitos de 7 segmentos, conectado a la Raspberry Pi junto con sensor DS18B20

Cuando me llegue el sensor de humedad, actualizaré este post para que muestre también la humedad relativa del ambiente.

El display mostrando la temperatura en la cuna

El display mostrando la temperatura en la cuna

Si queremos ahorrarnos tanto cable y programación, también se venden estos displays con un controlador incorporado, de forma que podemos conectarlos fácilmente a la Raspberry Pi por I2C. Pero son de 5 a 10 veces más caros, claro (por ejemplo, este). En otra entrada explicaré su manejo.

 

Referencias

  • http://www.instructables.com/id/Controlling-a-7-segment-4-digit-display-with-a-Ras/
  • http://www.techni.ca/2014/11/drive-7-segment-4-digit-display-with.html
  • https://www.raspberrypi.org/forums/viewtopic.php?f=37&t=91796
  • http://rpi.science.uoit.ca/lab/ssdispay/
  • http://razzpisampler.oreilly.com/ch09.html
  • http://learn.parallax.com/4-digit-7-segment-led-display-arduino-demo
  • http://ahoj.io/raspberry-pi-s-load-on-a-7-segment-display
  • http://hackyourmind.org/articles/2013/06/07/raspberry-pi-with-7-segment-display.html

 

WiFi en la Raspberry Pi con el adaptador TP-LINK TL-WN725N

Vamos a conectarnos a una red WiFi con el adaptador de red TP-LINK TL-WN725N.

Lo primero, conecto el adaptador de red USB, en mi caso un TP-LINK TL-WN725N, comprado aquí por menos de 10€. (Como veremos más adelante, este adaptador no funciona directamente en la Raspberry Pi, y hay que hacer un par de cosas para que lo reconozca)

TPLink

Si no queremos complicarnos la vida, lo más sencillo es editar el siguiente fichero:

sudo nano /etc/wpa_supplicant/wpa_supplicant.conf

Y añadir al final del mismo:

network={
    ssid="SSID(nombre)_de_la_red_wifi_a_la_que_me_quiero_conectar"
    psk="Contraseña"
}

(podríamos añadir otras configuraciones en este fichero, pero mejor empezar así).

Es posible que tengamos que editar también el fichero /etc/network/interfaces, pero en mi caso, dejándolo como viene por defecto en una instalación limpia de Raspbian funciona tanto con cable como por wifi.

Y ya estaría, si nuestra Raspberry Pi reconociese el adaptador según lo enchufas. Pero este no es el caso del TP-LINK TL-WN725N, a menos a fecha de 5 de julio de 2015. Ni siquiera aparece entre los dispositivos USb cuando ejecuto el comando sudo lsusb. Así que tenemos que hacer lo siguiente.

Lo primero, actualizo el firmware de la Raspberry Pi:

sudo rpi-update

En mi caso, se actualizó desde la versión 3.18.11+ a la 4.0.7+. Reiniciamos para que tenga efecto la actualización. Y tras reiniciar, podemos ver la versión con el siguiente comando:

uname -a

Actualizo los repositorios y todos los paquetes:

sudo apt-get update &amp;&amp; sudo apt-get upgrade

Tenemos que ver qué versión de drivers descargarnos, en función de la versión de nuestro kernel (que acabamos de actualizar). Podemos consultarlo aquí. Cuidadín, porque también dependerá de si nuestra Raspberry Pi es una Pi 2 o no. En mi caso, para la versión 4.0.7+ de una Raspberry Pi B+, será el fichero 8188eu-20150630.tar.gz
Ahora, ejecuto los siguientes comandos:

wget https://dl.dropboxusercontent.com/u/80256631/8188eu-v7-20150630.tar.gz //ojo, corregir versión en función del kernel
tar -zxvf 8188eu-v7-20150630.tar.gz //ojo, corregir versión en función del kernel
./install.sh
sudo reboot

Tras reiniciar, con el pincho USB conectado, vuelvo a ejecutar el comando sudo lsusb, y ahora me aparece un dispositivo que antes no aparecía:

Bus 001 Device 006: ID 0bda:8179 Realtek Semiconductor Corp. 

Y si hago dmesg | more, encuentro estas líneas:

[    3.091661] usb 1-1.2: new high-speed USB device number 4 using dwc_otg
[    3.212446] usb 1-1.2: New USB device found, idVendor=0bda, idProduct=8179
[    3.238162] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[    3.271447] usb 1-1.2: Product: 802.11n NIC
[    3.288971] usb 1-1.2: Manufacturer: Realtek
[    3.301363] usb 1-1.2: SerialNumber: 00E04C0001

Así que ahí está mi dispositivo WiFi.

Si hago sudo iwconfig, también aparace todo en orden.

Ojo. Si en algún momento actualizamos el kernel (con el comando rpi-update), tendremos que volver a descargarnos e instalar los drivers. Si encima tiene el mismo número de driver, tendremos que volver a instalarlo, haciendo lo siguiente:

wget https://dl.dropboxusercontent.com/u/80256631/8188eu-201xyyzz.tar.gz

Si quisiéramos ver un listado de redes disponibles, bastaría con hacer:

sudo iwlist wlan0 scan

Refencias