Dataloggerestaciones Watson 8681,1081 con un router asus wl500gpv2 y un pendrive

Desconectado hola

  • Sol
  • *
  • 5
Construccion de un datalogger para la estacion 8681, 1081 y similares, con un pendrive y un router ASUS WL500gpv2
Bien, empezemos.
Las herramientas necesarias para ello son:

Un router ASUS WL500gpv2. ¿Porque este router?. Porque tiene dos puertos usb 2.0 y además se puede instalar en el
un firmware Linux que será el que colocaremos para hacer el datalogger sobre un pendrive.

La clave de este proyecto están en las siguientes cosas:

-Flashear el router (meter el firmware WL500gpv2-1.9.7-10-US-1.71.trx, se puede bajar de
http://koppel.cz/cdmawifi/download/171/

-Montar el pendrive sobre el sistema de ficheros linux.
mount /dev/scsi/lun .... /directoriolinux
En el siguiente enlace hay todo lo necesario para ver como se monta un pendrive, se activa ssh (necesario para transferir ficheros al router mediante scp)
Para subir un fichero al router scp fichero admin@iprouter: (importante los dos puntos). Este firmware poner admin y contraseña admin por defecto cuando se flashea.
-Codigo fuente cesc8681.tar.gz o bien usar el código que proporciono, que no es mas que el cesc8681 modificado para
que fuese en el router.
-El código cesc modificado hay que compilarlo con el compilador que genera el proceso de creacion del firmware openwrt
para el fonera, al que hay que añadir la librería usb.
Enlace que describe el proceso de compilacion de openwrt,
http://downloads.openwrt.org/docs/buildroot-documentation.html
primer paso.
svn co https://svn.openwrt.org/openwrt/trunk/

Hay que instalar gcc, ncurses para poder ir al menu de configuracion.
Despues de pegaros con la compilacion, además de añadirle la librería usb,tendreis que desactivar algunas cosas como oldisdn, pcmcia
y aparecerá dentro de trunk, en el directorio bin, algunos ficheros trx, con el que podreis flashear el router, aunque no es necesario, porque
de flashearlos con alguno de estos ficheros, vuestro router no funcionará correctamente, pues solo el firmware indicado arriba funciona.
Este paso es necesario para poder obtener el compilador para vuestro router y compilarlo con el, para poder meter en el el programa que
lea los datos de la estacion y grabarlos periodicamente en un fichero de vuestro pendrive adosado a la estación.
Despues de todo, encontrareis vuestro compilador en trunk/staging_dir/toolchain.../usr/bin y se llamará
mipsel-openwrt-linux-gcc-3.4.6, con el compilareis el codigo de cesc o el modificado para poder leer la estacion.
-Una vez compilado se transfiere al router mediante scp.
-Crear la entrada correspondiente del crontab, para que nuestro programa se ejecute periodicamente y enviemos los datos a
un fichero en el pendrive. Con crontab podemos programar tareas hasta de periodos de un minuto.
-Enchufar la estacion en un puerto usb.
-Recoger los datos mediante scp a nuestro pc o mediante ftp.

Ventajas respecto a tener la estacion conectada al ordenador, menor consumo de energía, y que podemos almacenar tantos
tantos como espacio tenga el pendrive, además de que podemos alimentar el router con una batería.

El siguiente enlace muestra una estacion conectada al internet usando el router y la estacion 8681
http://www.stribog.net/Home

Codigo de cesc modificado.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <signal.h>
#include <ctype.h>
#include <usb.h>
#include <sys/time.h>
#include <time.h>
struct usb_device *dev,*disp;
static struct usb_dev_handle *devh;
   struct usb_bus *bus;
 int ret,pausa=1000,hexadecimal=1;
 static float i_temp,i_hum,e_temp,e_hum,presion=0.0,direccion,viento,racha,contadorlluvia,lluviatotal,lluviames,lluvia1h,lluviasemana,lluviadia,offsetaltura,altura=0.0;;
static int lee_memoria(int bloque,int mem,int tam,char *_buf,int palabra);
static int lee_datos(int tam,char *_buf,int palabra);
static void vuelca();
char buffer[512];
int endpoint=8;
char   buf[1000];
char   buf2[400];
void escribemensaje( char msg1[1],char msg2[1],char msg3[1],char msg4[1],char msg5[1],char msg6[1],char msg7[1],char msg8[1] );
void leemensaje(char *buffer) ;
static void carga_registro(unsigned char *registro);

int main()
{
struct tm *tiempo;
unsigned char cabecera[32];
unsigned char registro[32],registro2[32];
int indice,indice2,i,j,cont=0,offr=0,nreg,contador1=0,ndia;
//static long hora;
time_t hora;

   inicia(0x1941,0x8021);
   //vuelca();
   
carga_registro(registro);

lee_memoria(0,0,32,cabecera,1);
nreg = *((unsigned short *)(cabecera+27));
 indice = *((unsigned short *)(cabecera+30));
offr = 16;
indice -= 16;
lee_memoria(indice/256,indice%256,32,registro,1);

carga_registro(registro+offr);

lee_memoria(0,4*32,32,registro2,1);
lluviatotal = ((float)(*(unsigned short *)(registro2+6)))/10;
lluviames = ((float)(*(unsigned short *)(registro2+8)))/10;
lluviasemana = ((float)(*(unsigned short *)(registro2+10)))/10;                  
                  

printf("%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f\n",i_temp,i_hum,e_temp,e_hum,presion,direccion,viento,racha,contadorlluvia,lluviadia,lluviames,lluvia1h,lluviatotal,lluviasemana);

/*r(j=0;j<500;j++)
for (i = 0;i < 256;i+=32)
           {
              lee_memoria(j,i,32,registro,1);
carga_registro(registro);
 printf("registro %d,pos %d it %.1f ih %.1f, et %.1f eh %.1f, p %.1f d %.1f, v %.1f,r %.1f,cll %.1f\n",registro[offr],cont, i_temp,i_hum,e_temp,e_hum,presion,direccion,viento,racha,contadorlluvia);
cont++;
           }
*/
   finaliza();
}

 int finaliza()
{
 usb_release_interface(devh, 0);
    usb_close(devh);       
}


int inicia(int fabricante,int producto)

{
int j=0;
//rintf("usb init \n");
usb_init();
usb_find_busses();
//printf("encontradon buses \n");
usb_find_devices();
//printf("usb buscando dispositivos \n");
//printf("lista de dispositivos usb\n");
for (bus = usb_get_busses();bus; bus = bus->next)
     {
    for (dev = bus->devices;dev; dev = dev->next)
         {
      //printf("dispositivo num: %d fabricante: %d producto: %d\n",j,dev->descriptor.idVendor,dev->descriptor.idProduct);
      if((dev->descriptor.idVendor==fabricante)&&(dev->descriptor.idProduct==producto)) {
                                 //printf("el dispositivo %d %d está\n",fabricante,producto);     
               disp=dev;
                                     }   
   j++;                           
          }
     }

   devh = usb_open(disp);

       if (!devh)
       {
       printf("No se puede abrir la W8681\r\n");
                   return -1;
       }   
     usleep(pausa);

    ret = usb_detach_kernel_driver_np(devh, 0);
    if (ret >= 0)
       usleep(pausa);
 
    ret = usb_claim_interface(devh, 0);
ret=usb_claim_interface(devh, 0);
ret=usb_set_altinterface(devh, 1);
    if (ret < 0)
    {
       // printf("claim_interface:%d\r\n",ret);
        return -1;
    }

    usleep(pausa);
    ret = usb_control_msg(devh, 0x21, 0x0a, 0x000, 0, buf, 0x0, 1000);
    if (ret < 0)
    {
        printf("usb_control_msg_1:%d\r\n",ret);
        return -1;
    }
    usleep(pausa);
    ret = usb_control_msg(devh, 0x80, 0x06, 0x2200, 0, buf, 0x74, 1000);
    if (ret < 0)
    {
        printf("usb_control_msg_2:%d\r\n",ret);
     
        return -1;
    }
   // printf("ha sido inicializado\n");
}


static int lee_memoria(int bloque,int mem,int tam,char *_buf,int palabra)
{
       unsigned char buf[16];
       int ret,bucle=0,r=0,m;

       buf[0] = 0xa1;
       buf[1] = bloque;
       buf[2] = mem;
       buf[3] = 0x20;
       buf[4] = 0xa1;
       buf[5] = bloque;
       buf[6] = mem;
       buf[7] = 0x20;
       do
       {   //printf("entrando en bucle de inicializacion de lectura \n");
           ret = usb_control_msg(devh, 0x21, 0x09, 0x200, 0, buf, 0x8, 1000);
      //printf("ret: %d\n",ret);
           if (ret < 0)
           {
              printf("usb_control_msg_3:%d\r\n",ret);
              if (bucle < 0)
                 return -1;
              finaliza();
              sleep(1);
              while (inicia(0x1941,0x8021) < 0)
                 sleep(1);
              sleep(1);
           }
        r++;
       } while(ret < 0);
      // printf("lectura preparada\n");
         ret=usb_bulk_read(devh, endpoint, buffer, 512, 1000);
//printf("ret %d\n",ret);
//for (m=0;m<512;m++) printf(" %02x", buffer[m]); printf("\n");
      return lee_datos(tam,_buf,palabra);
}

static int lee_datos(int tam,char *_buf,int palabra)
{
    int n = 0,i,j,ret,erroneo=0;
    unsigned int valor,potencia;
    char buf[64];

    while(n < tam)
    {
        ret = usb_interrupt_read(devh, 1, buf, 32, 250);
        if (ret > 0)
        {
      //printf("retornó datos\n");
       if (ret > tam)
      ret = tam;
       if (_buf)
       {
      memcpy(_buf+n,buf,ret);
            }
            else
       {
               for (i = 0;i < ret;i+=palabra)
               {       
         valor = 0;
         potencia = 1;
         for (j = 0;j < palabra;j++)
         {               
            if (hexadecimal)
            {         
                         printf("%02X",(unsigned int)(unsigned char)buf[i+j]);
            }
            else
            {
               valor += (potencia * ((unsigned char)buf[i+j]));
               potencia *= 256;
            }
         }
         if (hexadecimal)
            printf(" ");
         else
            printf("%d ",valor);
               }
           printf("\r\n");
       }
            n += ret;
        }
   else
        {
            if (!n)
       {
               printf("usb_interrupt_read:%d\r\n",ret);
          erroneo++;
       }
            return n;
        }
    }
    return n;
}

static void vuelca()
{
int i,j,dp=1;       
 printf("volcado\n");
       for (j = 0;j < dp;j++)
           for (i = 0;i < 256;i+=32)
           {
              lee_memoria(j,i,32,NULL,1);
           }
}

int lectura(){
int presion,temp;
unsigned short  noffset;
int buftemp;
int mempos=0;
 escribemensaje("\xa1","\x00","\x00","\x20","\xa1","\x00","\x00","\x20");
   leemensaje(buf2);
   escribemensaje("\xa1","\x00","\x20","\x20","\xa1","\x00","\x20","\x20");
   leemensaje(buf2+32);
   escribemensaje("\xa1","\x00","\x40","\x20","\xa1","\x00","\x40","\x20");
   leemensaje(buf2+64);
   escribemensaje("\xa1","\x00","\x60","\x20","\xa1","\x00","\x60","\x20");
   leemensaje(buf2+96);
   escribemensaje("\xa1","\x00","\x80","\x20","\xa1","\x00","\x80","\x20");
   leemensaje(buf2+128);
   escribemensaje("\xa1","\x00","\xa0","\x20","\xa1","\x00","\xa0","\x20");
   leemensaje(buf2+160);
   escribemensaje("\xa1","\x00","\xc0","\x20","\xa1","\x00","\xc0","\x20");
   leemensaje(buf2+192);
   escribemensaje("\xa1","\x00","\xe0","\x20","\xa1","\x00","\xe0","\x20");
   leemensaje(buf2+224);
   escribemensaje("\xa1",buf+1,buf+2,"\x20","\xa1",buf+3,buf+4,"\x20");
   leemensaje(buf2+224);

 noffset = (unsigned char) buf2[30] + ( 256 * buf2[31] );
   if (mempos!=0) noffset = mempos;
   buftemp = 0;
   if (noffset!=0) buftemp = noffset - 0x10;
   buf[1] = ( buftemp >>8 & 0xFF ) ;
   buf[2] = buftemp & 0xFF;
   buf[3] = ( buftemp >>8 & 0xFF ) ;
   buf[4] = buftemp & 0xFF;
  escribemensaje("\xa1",buf+1,buf+2,"\x20","\xa1",buf+3,buf+4,"\x20");
  leemensaje(buf2+224);

//ret = usb_control_msg(devh, 0x21, 0x0a, 0x000, 0, buf, 0x0, 1000);
ret = usb_control_msg(devh, 0x21, 0x09, 0x200, 0, buf, 0x8, 1000);
// usleep(8*1000);
ret = usb_interrupt_read(devh, 0x00000081, buf, 0x0000020, 1000);
memcpy(buf2+256, buf, 0x0000020);
temp=( (unsigned char) buf2[274] + (unsigned char) buf2[275] *256);
printf("temperatura %5d\n",temp);
temp=( (unsigned char) buf2[277] + (unsigned char) buf2[278] *256);
printf("temperatura exterior %5d\n",temp);
presion= (unsigned char) buf2[279] + ( 256*buf2[280]);
printf("presion %5d\n",presion);

}

void escribemensaje( char msg1[1],char msg2[1],char msg3[1],char msg4[1],char msg5[1],char msg6[1],char msg7[1],char msg8[1] ) {
   char tbuf[1000];
   tbuf[0] = msg1[0];
   tbuf[1] = msg2[0];
   tbuf[2] = msg3[0];
   tbuf[3] = msg4[0];
   tbuf[4] = msg5[0];
   tbuf[5] = msg6[0];
   tbuf[6] = msg7[0];
   tbuf[7] = msg8[0];
   ret = usb_control_msg(devh, 0x21, 0x0a, 0x000, 0, tbuf, 0x0, 1000);
   // usleep(28*1000);
}

void leemensaje(char *buffer) {
   char tbuf[1000];
   usb_interrupt_read(devh, 0x81, tbuf, 0x20, 1000);
   memcpy(buffer, tbuf, 0x20);
   // usleep(82*1000);
}

static void carga_registro(unsigned char *registro)
{
   unsigned short dato;
        dato   = *((unsigned short *)(registro+2));
        i_temp   = ((float)(dato&0x7fff))/10;
   if ((dato &0x8000))
      i_temp = -i_temp;
        i_hum    = (unsigned int)registro[1];
        dato   = *((unsigned short *)(registro+5));
        e_temp   = ((float)(dato&0x7fff))/10;
   if ((dato &0x8000))
      e_temp = -e_temp;
        e_hum    = (unsigned int)registro[4];
         presion  = ((float)(*(unsigned short *)(registro+7)))/10;
   
        direccion= ((unsigned int)registro[12]*225)/10;
        viento   = ((float)((registro[9])))/10;
        racha    = ((float)((registro[10])))/10;
        contadorlluvia = registro[13] + registro[14]*256 + registro[15]*65536; /* ojo es un supuesto que es de 3 bytes */
}



Desconectado colo

  • Sol
  • *
  • 6
Re: Dataloggerestaciones Watson 8681,1081 con un router asus wl500gpv2 y un pendrive
« Respuesta #1 en: Jueves 10 Septiembre 2009 14:51:53 pm »
Fantástico Trabajo
:aplause: :aplause:
te lo has currado, si señor...