Actualizar Raspberry Pi 2 a Debian Jessie

Debian Jessie lleva ya un rato en los repositorios de raspbian así que aprovechando que ha salido hacer un par de días la versión estable (y que nos hacen falta algunas librerías que solo están en Jessie :/ ) vamos a actualizar la Raspberry Pi fácilmente:

Nos logueamos como habitualmente y ejecutamos:

pi@raspberrypi ~ $ sudo nano /etc/apt/sources.list

para poder editar el fichero con las fuentes de los paquetes.

Cambiamos todas las apariciones de wheezy:

deb http://mirrordirector.raspbian.org/raspbian/ wheezy main contrib non-free rpi

por jessie:

deb http://mirrordirector.raspbian.org/raspbian/ jessie main contrib non-free rpi

y actualizamos…

pi@raspberrypi ~ $ sudo apt-get update
pi@raspberrypi ~ $ sudo apt-get upgrade

NOTA IMPORTANTE: La actualización lleva unas cuantas horas (8-10 a mi) y rompe algunas cosas (o todo) personalmente di preferencia a los archivos del instalador sobre los que había en la pi.
Y con un poco de suerte, tras reiniciarla, la pi debería volver a la vida con Debian Jessie y la posibilidad de instalar algunas cosas mas, como chromium v37.

 

 

Fuentes:

http://sjoerd.luon.net/posts/2015/02/debian-jessie-on-rpi2/

 

Compilando el firmware para una camara IP WV54GCA

Linksys WV54GCA

 

Hace un mogollón de años compré esta cámara Linksys WV54GCA, hace un tiempo que esta dando problemillas así que decidí actualizar el firmware. Despues de hurgar mucho en Google dí con la versión 1.00R24 que os dejo por aquí.
Firmware WV54GCA V1.00R24

En eso que buscaba dí con un artículo de hablaba de como activar telnet en la cámara, tan simple como acceder http://IP/adm/file.cgi?todo=inject_telnetd con el único problema de que no sabemos la contraseña (el usuario sí, es root).

Hurgando un poco mas averiguamos el hash de la contraseña: 9szj4G6pgOGeA pero pasar de eso a una contraseña es cosa de la NSA, asi que basándonos en este otro post: http://hacktracking.blogspot.com.es/2014_08_01_archive.html recompilamos el firmware cambiando la contraseña de root a «root» y activando el servidor telnet por defecto.

El resultado, aquí abajo (compilado en un ubuntu server 12.04):

Firmware WV54GCA V1.00R24 modificado

 

Copio el código del artículo por si desaparece, con algunas modificaciones:

# file /sbin/init
/sbin/init: ELF 32-bit LSB  shared object, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=c394677bccc720a3bb4f4c42a48e008ff33e39b1, stripped
# cat /etc/lsb-release | grep DESC
DISTRIB_DESCRIPTION="Ubuntu 14.04.1 LTS"
# mkdir wvc54gca
# cd wvc54gca
# wget http://downloads.linksysbycisco.com/downloads/wvc54gca_v1.00R24.tgz
# tar xvzf wvc54gca_v1.00R24.tgz
# md5sum wvc54gca_v1.00R24.tgz
26475f583a55acf515d90d9c0340899d  wvc54gca_v1.00R24.tgz
# apt-get install autotools-dev libncurses5-dev
# rm /bin/sh
# ln -s /bin/bash /bin/sh
# cd source
# cat README
# cat src/rootfs/etc/init.d/rcS
# echo -e "\n# ---- Start Telnet Server (debug) ---- #\n/usr/sbin/telnetd &" >> src/rootfs/etc/init.d/rcS
# cat src/rootfs/etc/passwd
root:9szj4G6pgOGeA:0:0:root:/root:/bin/sh
# openssl passwd -crypt toor
TEcqq4feRqPLA
# sed -i 's/9szj4G6pgOGeA/TEcqq4feRqPLA/' src/rootfs/etc/passwd
# ./makeall
# file FW/WVC54GCA.bin
FW/WVC54GCA.bin: data

Streaming (bestia) con VLC

Con el objeto de forzar unas líneas de transmisión hemos configurado 3 emisiones de vídeo por red con el VLC para poder acceder a ellas vía Windows Media Player ( ¬¬ )

mms://ip:8080/
mms://ip:8081/
mms://ip:8082/

#!/bin/bash
vlc -I dummy jdc.avi --repeat --sout "#transcode{vcodec=DIV3,vb=800,scale=1,acodec=mp3,ab=128,channels=2,samplerate=44100}:std{access=mmsh,mux=asfh,dst=0.0.0.0:8080}" --sout-keep
vlc -I dummy jdc3.avi --repeat --sout "#transcode{vcodec=DIV3,vb=800,scale=1,acodec=mp3,ab=128,channels=2,samplerate=44100}:std{access=mmsh,mux=asfh,dst=0.0.0.0:8081}" --sout-keep
vlc -I dummy tbbt.mp4 --repeat --sout "#transcode{vcodec=DIV3,vb=800,scale=1,acodec=mp3,ab=128,channels=2,samplerate=44100}:std{access=mmsh,mux=asfh,dst=0.0.0.0:8081}" --sout-keep

-I dummy
Ejecutar el vlc sin interfaz

–repeat
Repetir en bucle la emisión

{vcodec=DIV3,vb=800,scale=1,acodec=mp3,ab=128,channels=2,samplerate=44100}
Esta línea es la configuración con la que se codifica el vídeo, idealmente sería h264 pero no hay codecs en el reproductor… así que así.

std{access=mmsh,mux=asfh,dst=0.0.0.0:8081}
Salida por protocolo mms, contenedor asf, escuchando en la ip 0.0.0.0 (todas las interfaces) y el puerto 8081.

Sí… los nombres de los vídeos son … «casuales»

Comunicación I2C Raspberry Pi -> Arduino

Vamos a ver si podemos comunicar una Arduino y una Raspberry Pi mediante I2C. Empezaremos por lo básico: una sola dirección, con la Raspberry Pi como «master» y el arduino como «esclavo».

Raspi+Arduino

No complicaremos mucho de momento… copia y pega de los ejemplos de Arduino para hacer una recepción de datos por I2C, con alguna pequeña modificación para que las cadenas salgan mejor por pantalla y que pite el buzzer:RasPi Arduino I2C

#include <Wire.h>

int led = 13;
int buzz = 4;

int direccion=31;

void setup() {
  pinMode(led, OUTPUT);
  pinMode(buzz, OUTPUT);
  Wire.begin(direccion);        // nos unimos al bus i2c bus con la dirección #direccion
  Wire.onReceive(receiveEvent); // registramos el evento de recepción de datos
  Serial.begin(9600);
  beep(); // Pos eso... beep... xD
}

void loop() {
  // Ponemos a la placa a hacer algo...
  digitalWrite(led, HIGH);   // Encendemos el led de la placa
  delay(100);               // Esperamos un poco
  digitalWrite(led, LOW);    // Apagamos el led de la placa
  delay(100);               // Esperamos un poco
}

void receiveEvent(int howMany) {
  beep();
  Serial.print("RX:");
  while(Wire.available()>0) // Mientras tengamos caracteres en el buffer
  {
    char c = Wire.read(); // Leemos uno
    Serial.print(c);  // Imprimimos
  }
  Serial.println('|'); // Para que veamos por pantalla cuando acaba
}

void beep() {
  digitalWrite(buzz, HIGH);
  delay(50);
  digitalWrite(buzz, LOW);
}

Y en la parte de la Raspberry Pi algo también muy simple (hay que configurar primero el I2C en la Raspberry Pi)

import smbus
import time
bus = smbus.SMBus(0)

DEVICE_ADDRESS = 0x1F # La misma con la que configuramos el arduino
DEVICE_MODE1 = 0x00
DEVICE_COM0 = 0x48 # 'H'

cadena= [0x48, 0x6f, 0x6c, 0x61] #'H' 'o' 'l' 'a'
#Bucle principal
while True:
    try:
        #bus.write_byte_data(0x1f,DEVICE_MODE1 , DEVICE_COM0 ) #Con esto enviamos un byte
        bus.write_i2c_block_data(DEVICE_ADDRESS, DEVICE_COM0 , cadena) # Con esto enviamos un array de bytes
        time.sleep(0.1)
    except IOError as e:
        print e

Referencias:
http://razzpisampler.oreilly.com/ch10.html

http://wiki.erazor-zone.de/wiki:linux:python:smbus:doc

http://nullege.com/codes/search/smbus.SMBus.read_byte_data

Configurar I2C en la Raspberry Pi

En las Raspberry no viene configurado por defecto el I2C, primero tenemos que activar los modulos:

Editamos:

sudo nano /etc/modules

y añadimos las líneas:

i2c-bcm2708
i2c-dev

Ademas tendremos que instalar esto para disponer de las herramientas de línea de comandos:

sudo apt-get install i2c-tools

Y esto si queremos usar el bus I2C desde python:

sudo apt-get install python-smbus

Ademas tendremos que comprobar que en /etc/modprobe.d/raspi-blacklist.conf no aparecen los mismos módulos de antes. Si aparecen, habrá que comentarlos:

sudo nano /etc/modprobe.d/raspi-blacklist.conf

Y… ¡reiniciamos!

sudo reboot

Con suerte a la vuelta usando el comando i2cdetect (con el valor 1 para la Resumen de la configuración del bus I2C en la Raspberry Pi B 512Mb, 0 para la antigua) podremos detectar los dispositivos que tengamos colgados del bus i2c:

sudo i2cdetect -y 1

Referencias:
https://learn.adafruit.com/adafruits-raspberry-pi-lesson-4-gpio-setup/configuring-i2c
Imagen: http://opensource.com/life/14/3/favorite-raspberry-pi-projects

Mini #smartSantander

Iberobotics

Con el objetivo de escenificar un pequeño #smartSantander para echar un cable a Iberobotics en el Nautilus Lab nos hemos puesto manos a la obra, hemos hecho un sensor bastante simple que mide la intensidad lumínica con una LDR y una Arduino Ethernet, un «servidor» con una Raspberry Pi B y Node.js  y un demostrador básico con otra Arduino Ethernet y un servo que hace las veces de indicador.

No nos hemos complicado mucho: cada 100mS el sensor mide la intensidad y envía al servidor un comando «guardar sensor 0 valor».
A su vez nuestro indicador envía también cada 100mS al servidor una solicitud «recoger sensor 0» por la que el servidor le devuelve el valor de la intensidad, que adapta al recorrido del servo y muestra.

Aquí abajo os dejamos el código de las 3 aplicaciones, por si queréis echar un vistazo 🙂

-Sensor de luminosidad:

Sensor de luminosidad mini #smartSantander

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = {  0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x01 };
IPAddress ip(192,168,1,21);

// initialize the library instance:
EthernetClient cliente;

char serverName[] = "192.168.1.37";

void setup() {
  Serial.begin(9600);
  pinMode(9, OUTPUT);

  Serial.println("Pidiendo IP por DHCP...");
  if (!Ethernet.begin(mac)) {
    Serial.println("Falló, la ponemos por defecto.");
    Ethernet.begin(mac, ip);
  }
  Serial.print("IP Local:");
  Serial.println(Ethernet.localIP());
  connectToServer();
}

int nSensor=0; // Que sensor tenemos
void loop() {
  int sensorValue;
  sensorValue = analogRead(A0); // Leemos el valor
  Serial.println(sensorValue);
  analogWrite(9, sensorValue*2); // Representamos el valor en la intensidad de un led

  if (cliente.connected()) { // Si estamos conectados al servidor
    cliente.print('g'); // Enviamos el comando de guardar
    cliente.print(nSensor); // Enviamos el número de sensor
    cliente.println(sensorValue); // Enviamos el valor que hemos leído del sensor
    cliente.stop(); // Desconectamos
  } else { // Si no estamos conectados
    connectToServer();
  }
  delay(100);
}

void connectToServer() {
  Serial.println("Conectamos con el servidor");
  if (cliente.connect(servidor, puertoServidor)) {
      Serial.println("conectados...");
  } else {
    delay(1500);
    Serial.println("esperamos...");
  }
}

 

-Servidor «nube» de mini #smartSantander:

Servidor "nube" mini #smartSantander

 

// Load the TCP Library
var net = require('net');

var datos=[0,0,0,0,0];

//Start a TCP Server
net.createServer(function (socket) {
	// Identify this client
	socket.name = socket.remoteAddress + ":" + socket.remotePort ;
	console.log(getDateTime() + ">" + socket.name+" <Hola>");
	socket.on('data', function (data) {
		try {
			data=''+data;
			var orden=data.substr(0,1);
			var nSensor=parseInt(data.substr(1, 1));
			var valor=parseInt(data.substr(2));
			switch (orden) {
				case '?':
					console.log(getDateTime() + ">" + socket.name+" >> Nos piden datos del sensor " + nSensor);
					socket.write(String.fromCharCode(datos[nSensor]+32));
					break;
				case 'g':
					console.log(getDateTime() + ">" + socket.name+" >> Nos envian datos del sensor " + nSensor + ": "+ valor);
					datos[nSensor]=valor;
					break;
				default:
					console.log(getDateTime() + ">" + socket.name+" >> Comando desconocido: " + data);
					break;
			}
		} catch (e) {
			console.log(getDateTime() + ">> Error");
			console.log(e);
		}
		//socket.end();
	});

	socket.on('end', function () {
		console.log(getDateTime() + ">" + socket.name+" <Adios>");
	});
}).listen(8081);

console.log(getDateTime() + ">" + "Escuchando...");

function getDateTime() {

    var date = new Date();

    var hour = date.getHours();
    hour = (hour < 10 ? "0" : "") + hour;

    var min  = date.getMinutes();
    min = (min < 10 ? "0" : "") + min;

    var sec  = date.getSeconds();
    sec = (sec < 10 ? "0" : "") + sec;

    var year = date.getFullYear();

    var month = date.getMonth() + 1;
    month = (month < 10 ? "0" : "") + month;

    var day  = date.getDate();
    day = (day < 10 ? "0" : "") + day;

    return day+'/'+month+'/'+year + " " + hour + ":" + min + ":" + sec;

}

-Demostrador:

Demostrador mini #smartSantander

#include <SPI.h>
#include <Ethernet.h>
#include <Servo.h>

Servo servo;

byte mac[] = {  0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x01 };
IPAddress ip(192,168,1,20);

// initialize the library instance:
EthernetClient cliente;

char servidor[] = "192.168.1.37";
int puertoServidor=8081;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  servo.attach(9);

  // attempt a DHCP connection:
  Serial.println("Pidiendo IP por DHCP...");
  if (!Ethernet.begin(mac)) {
    // if DHCP fails, start with a hard-coded address:
    Serial.println("Falló, la ponemos por defecto.");
    Ethernet.begin(mac, ip);
  }
  Serial.print("IP Local:");
  Serial.println(Ethernet.localIP());
  connectToServer();
  servo.write(180);
}

int nSensor=0; // Que número de sensor nos interesa
void loop() {
  if (cliente.connected()) { // Si estamos conectados
    Serial.println("Pedimos datos...");
    cliente.print('?'); // Comando para pedir datos
    cliente.print(nSensor); // Enviamos el número de sensor del que queremos los datos
    delay(100); // Esperamos un poco
    if (cliente.available()) { // Comprobamos si hay datos disponibles
      // leemos el dato
      int inChar = cliente.read();
      int valor=(inChar-32)*4; // Adaptamos el dato (0-40) al rango de nuestro servo (0-180)
      Serial.print("Valor:");
      Serial.println(valor);
      servo.write(180-valor); // Lo mandamos al servo
    }
    cliente.stop(); // Cerramos la conexión
  } else { // No estamos conectados
    connectToServer(); // Nos conectamos
  }
  delay(100);
}

void connectToServer() {
  Serial.println("Conectamos con el servidor");
  if (cliente.connect(servidor, puertoServidor)) {
      Serial.println("conectados...");
  } else {
    delay(1500);
    Serial.println("esperamos...");
  }
}

Sonar doble para multicóptero

ardusonar para multicóptero

Un pequeño sonar doble para detectar distancia vertical y horizontal de un multicóptero a un obstáculo e informar al piloto vía telemetría.

Usa una arduino pro mini para recoger los datos y un max233 para reconvertir los valores ttl del puerto serie a rs232 para que la telemetría los pueda enviar a la estación en tierra.

Una pequeña exhibición despues de la charla de robótica

Realizamos una pequeña exhibición con un multicóptero dentro de la conferencia ‘La robótica en la sociedad actual: pasado, presente y futuro’ impartida por Iván Bermejo de (Iberobotics).

Cargamos el maletero

IMG-20141001-WA0004

 

Vemos la charla después de dejar el multicóptero listo:

IMG_20141001_194808240

 

y a volar:

 

 

Mas fotos:
http://www.radiocamargo.es/index.php/component/k2/item/1081-los-drones-y-robots-protagonizan-una-conferencia-impartida-este-miercoles-en-el-centro-de-empresas-de-camargo-fotos.html