Nikon 1 J1 (primera toma de contacto)

Recién me ha llegado mi nueva adquisición para llevar de forma mas cómodo a cualquier sitio. Sin tener que llevar la D90 un poco mas pesadas. Se trata de la Nikon 1 J1 (en color blanco muy cool).

awesomeness.openphoto

Aquí algunas pruebas de fotos de detalle. La verdad es que es muy manejable y cómoda, el enfoque es rápido y el vídeo a 1080p la hace una sucesora de los vídeos con la D90. Además poder grabar vídeos en slowmotion a 400fps (a 1200fps no los recomiendo,…quedan con muy mala calidad) son divertidos (supongo que la novedad).

awesomeness.openphoto awesomeness.openphoto awesomeness.openphoto 

awesomeness.openphoto awesomeness.openphoto awesomeness.openphoto

Resto de las fotos aquí

También el primer vídeo a 400fps que he grabado

http://www.youtube.com/watch?v=05OHhseLsmg

Panorámicas en la nieve

Esta mañana nos hemos levantado con una estampa muy poco frecuente por aquí, así que ha sido toda una novedad, aunque la cantidad de nieve era muy poquita,…he aprovechado para hacer unas panorámicas:

awesomeness.openphoto

awesomeness.openphoto

awesomeness.openphoto

awesomeness.openphoto

 

Exposición de Playmobil

Algunas fotos de una reciente exposición de Playmobils en BCN

awesomeness.openphotoawesomeness.openphotoawesomeness.openphoto

awesomeness.openphotoawesomeness.openphotoawesomeness.openphoto

Resto de fotos en mi nuevo site de trovebox.com (aka OpenPhoto) http://akirasan.trovebox.com/photos/tags-Playmobil/list

Momento friki: “hola mundo” en ensamblador

He tenido un pequeño momento friki de recuerdo de mis antiguas andanzas con la programación en ASM (ensamblador). Ese recuerdo me ha hecho pensar en intentar el típico “hola mundo” en ensamblador.

Siempre había programado en x86 bajo MS-DOS y recuerdo aquella interrupción para hacer casi de todo, la int 21h. Ahora, un aliciente mas ha sido que no tengo MS-DOS, sino Ubuntu y en 64bits (nada de 32bits), por lo que hay algunos pequeños cambios: por ejemplo la int 21h es la int 80h (la que tiene los servicios de kernel).

Para empezar el compilador; he utilizado el NASM por poner uno, aunque hay varios y la verdad es que no he tenido tiempo ni de comparar ni analizar nada,…

Creamos un fichero holamundo.asm con este código fuente:

section .text
    global _start               ;necesario para el linkado (ld)

_start:                         ;inicio del codigo

        mov     edx,txtlong             ;longitud del maxima del mensaje
        mov     ecx,texto               ;mensaje
        mov     ebx,1           ;file descriptor (stdout)
        mov     eax,4           ;numero de servicio (sys_write)
        int     0x80            ;interrupcion 80h (llama al kernel)

        mov     eax,1           ;numero de servicio (sys_exit)
        int     0x80            ;llamada al kernel otra vez

section .data
texto   db      'Hola mundo!!!',0xa     ;mensaje, acabado en null
txtlong equ     $ - texto                       ;length of our dear string

Para compilar el código tan simple como:

nasm -f elf64 holamundo.asm -o holamundo.o

Una vez compilado y generado el fichero objeto, hay que linkarlo. Para ello hay que utilizar el comando ld:

ld -o holamundo holamundo.o

Listo!!! compilado y linkado, ahora ya solo queda ejecutarlo:

Que maravilla!!! :)

OpenStreetMap, mapas gratuitos para todos

OpenStreetMap.org (o también conocido como OSM) es uno de esos grandes proyectos de colaboración que todos podríamos aportar un poquito de nuestro tiempo. Se trata de un sistema gratuito de mapas, en el cual puedes aportar el conocimiento de tu zona para enriquecerlo y que el resto de usuarios lo puedan disfrutar mejor. Además tiene diversas capas de información que puedes aportar tu conocimiento de la zona, como por ejemplo: una ruta en bici, senderismo, lineas de alta tensión, lineas de autobuses, etc,…

Normalmente utilizo Google Maps, que está muy actualizado. Pero la ventaja de OSM es que no tiene muchas de las restricciones que los proveedores de servicios de mapas tienen (prohibido la impresión, prohibido sacar capturas de pantalla, prohibido redistribuir los mapas si no es a través de sus portales web, etc.). Mejor explicado en las preguntas frecuentes en la web de openstreetmap.es.

Para editar los mapas puedes utilizar tanto la herramienta online que tiene OSM (Potlatch2) o herramientas de escritorio como JOSM o Merkaartor. Yo personalmente utilizo JOSM para Ubuntu.

Esta es una de mis últimas aportaciones. He mejorado una zona que conozco y que estaba algo desactualizada. Aquí podéis ver la foto del antes y del después:

Tweet: Tablet CUBE U30GT, solo por esta descripción me lo…

Tablet CUBE U30GT, solo por esta descripción me lo voy a comprar!!!,…quiero ver que narices de tecnología utiliza http://t.co/7P191G6H

Zooomr KO = perdida de fotos en el blog

Una gran perdida, el servicio gratuito para compartir fotos desde hace años en el blog llamado Zooomr, ha dejado de funcionar tras 7 años. Eso a mi se me traduce en que he perdido todas las fotos que ilustraban el blog. A parte, el equipo de Zooomr  no ha dado oportunidad para descargar las fotos y permitir alojarlas en otro sitio :(

No mola nada!!!,…

Tweet: Un @arduino pinchado con USB, y de tamaño reducido…

Un @arduino pinchado con USB, y de tamaño reducido!!! Digispark [outgrow.me] outgrow.me/product/digisp… vía @outgrowme

Tweet: En esta carcasa hecha de #sugru hay un @arduino +…

En esta carcasa hecha de #sugru hay un @arduino + pantalla OLED con un GPS para geoposicionar fotos con una Nikon D90 http://t.co/5u1bMAmC

Ahora mejora el acceso al blog desde plataforma móvil

Acabo de instalar el pluging WPTouch (la versión gratuita) para WordPress y va de fábula. Supongo que muchos de los que navegais desde un smartphone o tablet agradeceis cuando el acceso a la página web se adapta perfectamente a las.dimensiones y características de vuestro dispositivo. Pues eso es precisamente lo que hace WPTouch, “mejorar” el aspecto de las páginas del blog cuando son visitadas fuera de una plataforma no PC.

image

Arduino + pantalla OLED (SSD1306)

Recientemente me ha llegado una pantalla OLED de 128×64 pixels, preparada para arduino (permite la comunicación mediante SPI), comprada en ebay por unos 10€. Por si aún no puede ser mas sencilla la comunicación por hardware (gracias a estas placas ya ensambladas, sino a ver quien se traga la cantidad de información técnica para utilizar la pantalla: http://www.gemmarduino.net/PM1/00100-101/SSD1306.pdf ), existe una librería para arduino, que también nos simplifica mucho el código. Se trata de la librería U8glib (Universal Graphics Library for 8bits Embedded Systems) que soporta una serie de dispositivos de este tipo, entre ellos el SSD1306 (aquí la lista completa y el constructor de la clase a utilizar).

Para empezar vamos a tener que descargar la librería U8glib y añadirla al directorio de libraries del IDE de arduino. Luego arrancamos el IDE y ya podremos utilizarla (esto es fácil y no voy a entrar en detalle).

Os dejo un simple sketch como ejemplo, que permite ver algunas de las funcionalidades de esta librería y de paso probar como funciona la pantalla OLED. Para mi ejemplo he tenido que utilizar la clase U8GLIB_SSD1306_128X64 que utilizar comunicación SPI por software y no por hardware. Esto dependerá un poco del circuito que compréis.

#include <U8glib.h>

#define cs 2     // CS
#define a0 3     // DC
#define reset 4  // RST
#define sck 5    // D0
#define mosi 6   // D1

int x, y;

//SPI Comunicación por SW (sck, mosi, cs, a0 , reset)
U8GLIB_SSD1306_128X64 u8g(sck, mosi, cs, a0, reset);

void setup() {
  x = 50;
  y = 5;
}

void loop() {
  // picture loop
  u8g.firstPage();
  do {
   draw("Hello mundo!!!!");
   pie(x, y, "by akirasan 2k12");

   u8g.drawBox(10,22,20,30);

   u8g.drawCircle(50, 50, 14);

   u8g.drawFrame(110,30,15,10);

   u8g.drawPixel(14,23);
   u8g.drawPixel(24,43);
   u8g.drawPixel(125,53);
   u8g.drawPixel(0,0);
   u8g.drawPixel(127,0);
   u8g.drawPixel(127,63);
   u8g.drawPixel(0,63);

  } while( u8g.nextPage() );
  if (y <= 62) {
    y++;
  }

  // rebuild the picture after some delay
  delay(5);
}

void draw(char* text) {
  // graphic commands to redraw the complete screen should be placed here
  u8g.setFont(u8g_font_unifont);
  u8g.drawStr( 0, 20, text);
}

void pie(int x, int y, char* text) {
  // graphic commands to redraw the complete screen should be placed here
  u8g.setFont(u8g_font_04b_03);
  u8g.drawStr( x, y, text);
}

El resultado de este programita es el siguiente:

awesomeness.openphoto

Muy fácil, verdad??,…pues existe otra librería llamada http://code.google.com/p/m2tklib/ que soporta la U8glib y permite realizar GUI (graphical user interface), es decir, menús y control de entrada de datos para interactuar. Aún no la he probado, pero seguro que tiene que ser igualmente sencillo (un posible post en el futuro).

Existen otros tipos de pantalla OLED y evidentemente circuitos con pines diferentes. En este caso en concreto, voy a explicar cual es el pineado necesario y su relación con el constructor de la clase de la librería U8glib. Estos son los pines que trae este circuito:

awesomeness.openphoto

awesomeness.openphoto

Esta es la relación de pines (OLED) y parámetros (U8glib) y pines digitales (arduino) (sin contar con los pines de alimentación GND y V (a +3.3V) ):

 
PIN OLED Parámetro clase
U8GLIB_SSD1306_128X64
PIN arduino
CS cs 2
DC a0 3
RST reset 4
D0 sck 5
D1 mosi 6
CS cs 2

PP: Me he pedido otra pantalla de color blanco,… :)

Mi primer uso con tubo termoretractil

Pues aprovechando que últimamente el cable de alimentación del netbook me estaba dando problemas y cuando se doblaba por algún sitio dejaba de funcionar, he querido repararlo y de paso utilizar un tubo termoretractil, es decir, que al aplicar calor se contraen fijando, sellando e impermeabilizar el cable.

…así que he tenido que buscar el punto de fallo, cortar y soldar,…

No hay que olvidar que el termoretractil hay que ponerlo antes de soldar,… :) una vez preparado el tema hay que calentarlo. Yo he utilizado un secador de pelo a la máxima potencia.

El resultado final ha quedado bastante bien y el cable funciona de maravilla :)

Modificación ratón bluetooth HP

Ha llegado a mis manos un ratón HP bluetooth extraplano, de los que se cargan introduciendo en un slot pcmcia.

El ratón es muy majo, pero claro, los portátiles ya no suelen venir con pcmcia,…así que ¿como cargo el ratoncillo?, pues haciendo un modmouse :)

La modificación es sencilla, únicamente hay que quitar la tapa que tiene con cuatro tornillos y justo debajo hay una batería con un controlador de carga. Simplemente hay que soldar a los dos cables de entrada al controlador de carga, dos cables con el pineado de USB de V+ y GND.

RAID en modo Degraded al arrancar (Ubuntu 12.04)

Una de las cosas que me he encontrado tras actualizar mi NAS de Ubuntu 11.04 a 12.04 es un tema con el RAID1 que tenía montado entre dos discos. Al arrancar el sistema detecta que existe un RAID y que uno de los discos no está bien (cual realmente no hay problema) y pide confirmación de arrancar el raid en modo Degraded. Este mecanismo de alerta es por si el raid se tiene como boot y por lo tanto el sistema operativo no puede arrancar. Hay que decir que mi RAID1 es de datos y no de sistema operativo, por lo que en cierta forma esto me daría igual.

Resulta que existe un bug reportado a Ubuntu con este fallo: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/990913 (he de comentar que mi versión no es la 12.04 Server, pero es lo mismo :) )

Para solucionarlo de forma temporal hasta que esté corregido, he optado por poner el parámetro BOOT_DEGRADED=true como parámetro de arranque. De esta forma ignorará este advertencia y arrancará sin pedir confirmación. Estos son los pasos a seguir:

sudo nano /etc/initramfs-tools/conf.d/mdadm

Este será el fichero que editaremos:

# mdadm boot_degraded configuration
#
# You can run 'dpkg-reconfigure mdadm' to modify the values in this file, if
# you want. You can also change the values here and changes will be preserved.
# Do note that only the values are preserved; the rest of the file is
# rewritten.
#
# BOOT_DEGRADED:
# Do you want to boot your system if a RAID providing your root filesystem
# becomes degraded?
#
# Running a system with a degraded RAID could result in permanent data loss
# if it suffers another hardware fault.
#
# However, you might answer "yes" if this system is a server, expected to
# tolerate hardware faults and boot unattended.

BOOT_DEGRADED=false

…al final ponemos el parámetro BOOT_DEGRADED=false a “true“. Guardamos y reiniciamos.

OJO!!! que previamente tenéis que comprobrar que realmente tras arrancar el raid funciona correctamente y que tenéis este bug!!!. Para ver que tenéis el raid en perfecto estado tenéis que ejecutar este comando:

root@qtrnas:~# mdadm --query --detail /dev/md0
/dev/md0:
        Version : 1.2
  Creation Time : Thu Sep  8 21:29:33 2011
     Raid Level : raid1
     Array Size : 488376184 (465.75 GiB 500.10 GB)
  Used Dev Size : 488376184 (465.75 GiB 500.10 GB)
   Raid Devices : 2
  Total Devices : 2
    Persistence : Superblock is persistent

    Update Time : Mon May  7 15:36:44 2012
          State : clean
 Active Devices : 2
Working Devices : 2
 Failed Devices : 0
  Spare Devices : 0

           Name : qtrnas:0  (local to host qtrnas)
           UUID : cfff5808:181b19bc:154931a0:1f3ecfc4
         Events : 7441

    Number   Major   Minor   RaidDevice State
       0       8       33        0      active sync   /dev/sdc1
       2       8       17        1      active sync   /dev/sdb1

Reparando Arduino nano

Una de las ventajas que tiene la plataforma arduino es que al ser opensource se puede disponer del esquema y poder encontrar posibles fallos e incluso repararlos. Como me ha pasado a mí,…tanto trastear con el arduino es lo que tiene,…así que tocó hacer un pedido en http://es.rs-online.com/web/ (que por cierto muy bien) y soldador en mano cambiar, en mi caso, el MBR0520.

Proyecto GPS+D90+Arduino (Parte 4 y “última”)

En esta última parte únicamente se trata de pasar el prototipo a una placa Arduino mini pro, la cual permite reducir el tamaño y poderlo encapsular mejor:

Aquí algunas fotos de las primeras pruebas de campo con el sistema “a la vista”:

He reciclado el conector del disparador para que me haga de caja. Para ello hay que desmontarlo todo y con la “dremel” vaciar el contenido de plástico para poder hacer hueco.

He tenido que sacrificar los tres led’s con indicaciones (aunque no descarto ponerlos en algún momento mediante LED’s SMD) y únicamente me he quedado con el indicador del estado del módulo bluetooth, que realmente “me da información“.

Le he incorporado un pequeño pulsador para poder realizar el reset, en caso que se quede sin señal o cualquier otra cosa. Así no tengo que quitarlo y volverlo a conectar (ya que la alimentación de la cámara es constante). La idea es colocarle un pequeño interruptor que permita apagar/encender y no tener que desmontarlo.

Para fijar el conector he utilizado, por primera vez, Sugru. Que aunque es muy versátil  y fácil de utilizar,…tiene su “que”. Las pruebas de campo fueron muy bien aquí os dejo alguna foto del cacharro y alguna de las fotos geoposicionadas directamente desde la cámara.

Fotos geoposicionadas en Panoramio:

PD: Tal vez haga una revisión 2 del proyecto (que he bautizado como qtrArduD90) con GPS incorporado y batería propia.

Proyecto GPS+D90+Arduino (Parte 3)

Tercera parte  del proyecto: Ya tengo el engendrillo montado y funcionando en modo prototipo!!!. El arduino está programado para recibir y transformar la información que recibe vía bluetooth el GPS (Holux M-241) y envía por el conector a la cámara (Nikon D90). Antes de pasar a la teoría aburrida del código, aquí os dejo alguna foto:

Le he puesto tres led’s para conocer el estado (rojo = estado del bluetooth, verde = operativo, amarillo = proceso de configuración). En el código veréis referencias y funciones para tratar los leds:

En esta parte prácticamente es todo programación. He colocado bastantes comentarios en el sketch y el código está muy modularizado para simplificar y entender las acciones. Como podéis ver, en las funciones estandars setup() y loop(), es muy simple:

void setup()
{
  configurar_pines();
  check_leds();            //secuencia de chequeo visual de los leds
  pinMode(ledR,INPUT);     //redefinimos pin del led rojo para que funcione como led del estado del bluetooth
  configurar_bluetooth();
  onled(ledV);
}

void loop()
{
  while (bt.available()){
    i = 0;
    buffer[i] = (char)bt.read();
    if (buffer[i]=='$'){        //inicio sentencia
      leer_comando();           //lee hasta la "," i=","
      validar_comando();        //verifica si es $GPGGA o $GPRMC
      if (_GPGGA || _GPRMC){
        procesar_comando();     //comando válido
        i = 0;
      }
    }//fin inicio sentencia
  }//fin bt.available
}//fin loop

…pero, hay un par de puntos que hay que tener en cuenta:

  1. Configurar el módulo de bluetooth para conectarse al GPS, es decir, que cuando arranquemos el bluetooth sea capaz de emparejarse con el GPS.
  2. Tratar las sentencias NMEA que envía el GPS para que las reconozca la Nikon D90. Hay un par de temillas a tener en cuenta :)

Configurar módulo bluetooth

Antes de utilizarlo, es recomendable conectarlo vía adaptador USB-UART(TTL) y entrar en modo AT para configurar la velocidad por defecto, que es de 9600 a 4800. Velocidad con la que trabajaremos, ya que la Nikon D90 utiliza esta velocidad para recibir los datos. Esta parte es simple, únicamente necesitas un adaptador serial-USB y conectarte al puerto COM. Puedes utilizar el mismo monitor de serial que viene en el IDE de Arduino o utilizar el Putty u otros,…(recordad que para entrar en modo AT hay que seguir lo que se comenta en el siguiente párrafo para entrar en modo AT). Comandos AT que se pueden utilizar. Necesitaréis algo como esto:

Este módulo conversor con chip CP2102 es bastante barato y en ebay lo podéis encontrar por unos 3$ (con gastos incluidos).

Para que el módulo BT (bluetooth) se conecte al GPS hay que inicializarlo en modo AT, es decir, que acepte los comandos de configuración AT. Para ello hay que poner en HIGH (tensión) el pin 34 (o el PIO11) y luego poner encender el módulo. Esto hará que el módulo BT acepte comandos AT.

Básicamente le enviaremos los comandos de fijar a rol master, fijamos el password o pincode (del módulo GPS), emparejamiento y vinculación:

void iniciar_BT_modoAT(){
  // Entrar en modo AT - pin34_HIGH + power
  flashled(ledA,2);
  digitalWrite(bt_PowerPin, HIGH);
  delay(4000);
  flashled(ledA,1);
  digitalWrite(bt_KEYPin, HIGH);
  delay(1000);
  bt.listen();
}

void finalizar_BT_modoAT(){
  // Quitamos power al pin34
  digitalWrite(bt_KEYPin, LOW);
}

void configurar_bluetooth()
{
  String result, bt_pincode, bt_mac;

  flashled(ledA,3);
  Serial.println("Inicializando modulo BT...");

  iniciar_BT_modoAT();

  // Entramos en modo master============================== se supone que debe estar en role=1
  flashled(ledA,2);
  Serial.println("-----------------role");
  enviar_comandoAT("AT+ROLE=1", &result);
  Serial.println(result);

  // Fijamos el pin==============================
  flashled(ledA,2);
  bt_pincode = BT_pincode;
  Serial.println("-----------------password");
  enviar_comandoAT("AT+PSWD="+bt_pincode, &result);
  Serial.println(result);

  // Fijamos el emparejamiento==============================
  flashled(ledA,2);
  bt_mac = BT_MAC;
  Serial.println("-----------------pair");
  enviar_comandoAT("AT+PAIR="+bt_mac+",20", &result);
  Serial.println(result);

  // Vinculamos al GPS==============================
  flashled(ledA,2);
  Serial.println("-----------------link");
  enviar_comandoAT("AT+LINK="+bt_mac, &result);
  Serial.println(result);

  finalizar_BT_modoAT();
}

void enviar_comandoAT(String cmd, String *resultado)
{
  String result = "";

  Serial.print("\n-----llamamos al comando "+cmd+" --> ");

  for (int i2=0; i2<10 ; i2++){
    while (bt.available()){
      Serial.print((char)bt.read());
    }
  }

  bt.print(cmd+"\r\n");
  delay(3000);

  if (bt.available()){
    while(bt.available())
    {
      result.concat((char)bt.read());
    }
  }
  Serial.print("------resultado:"+result);
  *resultado = result;
}

En el sketch está indicado, pero hay que tener en cuenta un detalle con el número de la MAC del dispositivo al que nos tenemos que conectar, es decir, hay que adaptar su formato. Por ejemplo una MAC del estilo 00:1b:c1:06:1b:6b se debe enviar así 1B,C1,61B6B.

Adaptación de sentencias NMEA

De todas las sentencias NMEA que envía el GPS, la Nikon D90 únicamente reconoce (o simplemente utiliza) dos: $GPGGA y $GPRMC. En mi caso, de estas sentencias, la $GPGGA requiere además una pequeña adaptación para que la D90 la entienda (tal vez sería bueno una actualización de firmware de la cámara,…). Así que ojo con el módulo de GPS que utilizáis, porque tal vez no sea necesaria esta adaptación,…o si,…hay que verificarlo. Para ello conéctalo por un puerto COM y monitoriza sus sentencias NMEA.

Ejemplo de una trama en formato NMEA:

$GPGGA,152848.000,4199.9999,N,00209.9999,E,1,7,1.46,10.8,M,51.3,M,,*6B
$GPGSA,A,3,02,10,07,13,05,04,23,,,,,,1.72,1.46,0.90*0A
$GPGSV,3,1,12,10,79,346,22,07,67,128,16,13,51,047,27,04,50,216,28*72
$GPGSV,3,2,12,02,48,279,33,08,43,179,,23,23,063,30,05,21,304,31*7C
$GPGSV,3,3,12,16,08,044,,26,03,250,,20,02,120,,49,,,*4B
$GPRMC,152848.000,A,4199.9999,N,00209.9999,E,0.31,0.27,020212,,,A*67
$GPVTG,0.27,T,,M,0.31,N,0.57,K,A*38

Sentencia $GPGGA. Dos son las modificaciones que con el GPS Holux M-241 hay que hacer:

  1. Número de satélites
  2. El número de satélites tiene que ser de dos dígitos, por lo que si recibimos un número inferior a 10, tendremos que añadir un 0 (cero) por delante. Por ejemplo, esta sentencia:

    $GPGGA,152848.000,4199.9999,N,00209.9999,E,1,7,1.46,10.8,M,51.3,M,,*6B

    Se tiene que sustituir por:

    $GPGGA,152848.000,4199.9999,N,00209.9999,E,1,07,1.46,10.8,M,51.3,M,,*6B

    Esta info la descubrí por propia experiencia la cual confirmé en esta web http://we.easyelectronics.ru/upgrade-repair/analog-nikon-gps.html (ojo!!! que el contenido está en ruso).

  3. Altitud
  4. Algo parecido al anterior punto le pasa al número que marca la altitud en metros. Hay que hacer lo mismo, rellenar con 0 (ceros) hasta completar un número con cuatro digitos. Un ejemplo:

    $GPGGA,152848.000,4199.9999,N,00209.9999,E,1,07,1.46,10.8,M,51.3,M,,*6B

    Debe quedar así:

    $GPGGA,152848.000,4199.9999,N,00209.9999,E,1,07,1.46,0010.8,M,51.3,M,,*6B

La parte del código que se encarga de hacer toda esta adaptación es esta:

void enviar_comando_gprmc(){
  int i2 = 7;
  //leer y enviar hasta final del comando --> previo al inicio del nuevo $
  Serial.print("$GPRMC,");    //enviamos lo que tenemos en el buffer
  while (bt.peek()!='$'){
    while (bt.available() && bt.peek()!='$'){
      Serial.print((char)bt.read());
    }
  }
}

void enviar_comando_gpgga(){
  int cs;
  int i2;
  leer_comando_entero();
  adaptar_satelites();      //  ",7," --> ",07," i=,
  adaptar_altitud();        //  ",148.0," --> ",00148.0,"
  cs=getCheckSum(buffer);
  Serial.write(buffer);
  Serial.print(cs,HEX);
  Serial.println("");
}

void adaptar_satelites(){
  int n=0;
  int i=0;
  while (n<8)              //llegamos hasta el final del comando numero #8
  {
    i++;
    if (buffer[i]==',') n++;
  }
  if (buffer[i-2]==','){
    for (n=strlen(buffer);n>i-2;n--){
      buffer[n+1] = buffer[n];
    }
    buffer[i-1]='0';
  }
}

void adaptar_altitud(){
  int n=0;
  int i=0;
  int k=0;
  int dig=6;

  while (n<10)   //llegamos hasta el comando n9 -->(k)XXXXXX(i) k=, inicial y i=, final
  {
    i++;
    if (n==8) k=i;
    if (buffer[i]==',') n++;
  }

  if (buffer[k+1]=='-'){
    k++;
    dig--;
  }

  int offset = dig-((i-k)-1);            //la longitud del dígito es de 6 o 5 dependiendo del signo - o +

  for (n=strlen(buffer);n>k;n--){        //desplazamos todo n posiciones segun offset
    buffer[n+offset] = buffer[n];
  }
  for (n=k+1;n<=k+offset;n++) buffer[n]='0';
}

Ojo!!! que en ocasiones también pueden venir altitudes negativas. Normalmente cuando no hay suficientes satélites para establecer una posición correcta (el código ya lo contempla).

Lo malo” de modificar la información que se envía de esta sentencia, es que el número de control o checksum (para verificar que la info es correcta), no sirve y hay que recalcularlo nuevamente. Para ello hay que utilizar un XOR desde el inicio de la sentencia, “$” hasta el “*“, y luego colocarlo en formato hexadecimal. Esta parte del código no es mía, lo saqué de aquí:
int getCheckSum(char *string) {
  int i2;
  int XOR;
  int c2;
  // Calculate checksum ignoring any $'s in the string
  for (XOR = 0, i2 = 0; i2 < strlen(string); i2++) {
    c2 = (unsigned char)string[i2];
    if (c2 == '*') break;
    if (c2 != '$') XOR ^= c2;
  }
  return XOR;
}

Un vez programado, prototipado y probado, ya solo queda traspasarlo y empaquetarlo todo debidamente, ponerle un pulsador de reset exterior y un interruptor de encendido. Para ello voy a utilizar un Arduino mini pro versión de 3.3V a 8Mhz (ya veremos si funciona!!! y es capaz de procesar toda la información correctamente y sin retrasos, ya que sino habrá perdidas en los datos).

Para acabar aquí os dejo el link para descargar el sketch, está realizado con la versión Arduino 1.0 (tenedlo en cuenta para la compilación). También agradecer en esta parte del proyecto la colaboración de fefago , por su aporte de información y comentarios ;) .

Links de referencia de esta parte:

http://www.cutedigi.com/pub/Bluetooth/BMX_Bluetooth_quanxin.pdf

http://www.gpsinformation.org/dale/nmea.htm

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1293745670

http://timzaman.wordpress.com/code-c-arduino/checksum-xor-cpp/

http://air.imag.fr/mediawiki/index.php/Wireless_Bluetooth_RS232_TTL_Transceiver_Module

Proyecto GPS+D90+Arduino (Parte 2)

Comenzamos la segunda parte del proyecto con “un pequeño contratiempo“. Ya me ha llegado el módulo Bluetooth para conectarlo con el Arduino. Se trata de un BT BC41713 de CSR (aquí podréis ver las especificaciones). Me ha salido por unos 7€ en ebay. Esto bluetooth viene configurado inicialmente como slave, lo que quiere decir que cualquier otro dispositivo (master) se puede conectar utilizando el pin que tiene por defecto, “1234″. Como mi idea es que este módulo se conecte al GPS (que es slave) tengo que “convertirlo” en master. Para ello hay que poner a HIGH el pin34 (llamado POI11 o en mi caso/módulo KEY) y mediante comandos AT (AT+ROLE=1) ponerlo como master.

…bueno esto era lo que yo pensaba, hasta que lo he probado y he visto que mi módulo no aceptaba este comando, ni otros comandos AT. Arrebuscando información por internet me he dado cuenta de un inconveniente: el chipi-chipi viene con un firmware llamado HC-06 o Linvor V1.5, el cual acepta muy pocos comandos AT. Básicamente estos:

Comando
Respuesta
Nota
AT
OK
Conexión lista!!!
AT+VERSION
Linvor1.5
Versión del firmware (firmware maldito!!!)
AT+BAUDx
OKyyyy
Configurar velocidad de datos donde x puede ser uno de esto números:
  • 1 para 1200 bps
  • 2     2400 bps
  • 3     4800 bps
  • 4     9600 bps
  • 5    19200 bps
  • 6    38400 bps
  • 7    57600 bps
  • 8   115200 bps
  • 9   230400 bps
  • A   460800 bps
  • B   921600 bps
  • C  1382400 bps
AT+NAMEString
OKsetname
Cambiar el nombre emitido por bluetooth
AT+PINxxxx
OKsetpin
Pincode, por defecto 1234

…y lo mas grave no permite el modo master :( . En este post tenéis info sobre el HC-06 o Linvor V1.5 (este hardware puede aceptar varios firmware, incluso existe un IDE para poder desarrollarlos uno mismo,…).

Llegados a este punto, solo me quedaba dos opciones: comprar un nuevo módulo master en ebay (10$) o tostar un firmware nuevo sobre el cacharro. Así que siguiendo el siguiente esquema, descargando el software BlueSuiteCasira 1.24 y recuperando un viejo PC con puerto paralelo LPT y WindowsXP,…he actualizado el firmware!!!,…

Evidentemente, y para un único uso, no he hecho ni una sola soldadura (bueno las del puerto LPT reaprovechado que he encontrado por casa). Así es como me ha quedado el “engendro” temporal. Lo increíble es que ha funcionado “a la primera“:

Ahora ya tengo el módulo tal y como yo quería. Siguiente paso,…programar el Arduino con los componentes pinchados!!!

Si queréis mas información aquí os dejo los links que he utilizado yo. Tendréis mas detalle (paso a paso de la aplicación para flashear, aunque no tiene mucho secreto) y un poco mas de teoría:

http://byron76.blogspot.com/

http://curiosidadesford.blogspot.com/2011/01/modulo-bluetooth-bluetooth-module.html

http://www.neoteo.com/modulo-bluetooth-hc-06-android

Proyecto GPS+D90+Arduino (Parte 1)

He comenzado un proyecto (y voy a tratar de acabar,…) en el cual, la idea básica es: conectar un GPS Holux M241 vía bluetooth a un módulo Arduino Nano v3.0 que está conectado por cable al conector de GPS de mi Nikon D90, con la finalidad de que la cámara geoposicione de forma automática las fotos. Vamos, que guarde en el Exif, info del punto donde fue tomada la foto. Este es el concepto.

En esta primera parte he conectado el Arduino por cable a la Nikon D90 y he simulado la entrada de datos del GPS en formato NMEA. Para ello hará falta: un Arduino (en mi caso un Nano v3.0, pero cualquier versión vale), un pequeño programa (sketch) para que Arduino simule la salida de datos y un conector para la entrada GPS de la cámara (ahora explicaré como conseguirlo).

El conector GPS para la Nikon D90: Se puede conseguir muy barato en eBay (por unos 5$-6$) un disparador remoto por cable (modelo MC-DC2). De este cable únicamente nos servirá el conector, el cual hay que volverlo a pinear correctamente. En esta web tenéis el pineado necesario (es de donde he sacado algo de información). Esta es la pinta que tiene el mío (evidentemente sin el envoltorio):

conector

Bien, una vez pineado el conector de forma correcta, hay que centrarse en el Arduino. Os dejo el programa que he generado como ejemplo para simular la entrada de datos GPS a la cámara:

 #include <SoftwareSerial.h>
 */
 GPS test D90
 SoftwareSerial(rxPin, txPin)
 rxPin = 2
 txPin = 3
 */
 SoftwareSerial mySerial(2, 3);
 void setup()
 {
 mySerial.begin(4800);
 pinMode(2,INPUT);
 pinMode(3,OUTPUT);
 pinMode(13,OUTPUT);
 }
 void loop()
 {
 digitalWrite(13,HIGH);
 mySerial.println("$GPGGA,154654,4428.2011,N,00440.5161,W,0,00,,-00044.7,M,051.6,M,,6B");
 mySerial.println("$GPGSA,A,1,,,,,,,,,,,,,,,1E");
 mySerial.println("$GPGSV,3,1,10,02,50,290,00");
 mySerial.println("$GPGGA,154655,4328.1874,N,00340.5185,W,1,03,08.5,-00044.7,M,051.6,M,,*79");
 mySerial.println("$GPGSA,A,2,13,23,25,,,,,,,,,,08.5,08.5,00.9*0E");
 mySerial.println("$GPGSV,3,1,10,02,50,290,26,04,60,210,26,08,33,173,29,10,21,296,00*7E");
 mySerial.println("$GPGSV,3,2,10,13,58,044,34,16,03,035,00,20,02,109,00,23,26,057,34*7B");
 mySerial.println("$GPGSV,3,3,10,25,24,045,35,27,56,145,27,,,,,,,,*7D");
 mySerial.println("$GPRMC,154655,A,4428.1874,N,00440.5185,W,000.7,000.0,050407,,,A*6C");
 digitalWrite(13,LOW);
 }

Ahora ya solo queda conectar el cable a la salida del Arduino y a la entrada GPS de la D90, dar corriente al Arduino y encender la cámara y verificar que correctamente está recibiendo los datos:

D90+GPS+Arduino

Si disparas alguna foto y consulta sus datos, verás que tiene la información del GPS.

Bueno hasta aquí la primera parte. Estoy a la espera de que me llegue el módulo bluetooth para pincharlo a la placa Arduino y ver de emparejar el GPS Holux (aunque evidentemente se podría utilizar un movil con GPS, porque no?)

Scripting al poder

Una duda de hoy que ha salido en el trabajo: Si tengo Ubuntu Desktop instalado y le quiero desinstalar el Python ¿porque me desinstala todo el Desktop?. Después de buscar por internet un rato,…creo haber encontrado la respuesta:

  • Gnome Shell está basado en Javascript y utiliza librerías GTK
  • Unity está basado en Phyton y utiliza librerías GTK
  • KDE está basado en QtScript y utiliza librerías Qt
Gracias  @meinteresatodo por la duda.

Next Page »