Ir al contenido


Foto

Tratamiento de un bloque de datos


  • Por favor identifícate para responder
23 respuestas en este tema

#1 mosco

mosco

    Member

  • Miembros
  • PipPip
  • 11 mensajes

Escrito 15 junio 2013 - 09:37

Hola a todos. Ya he preguntado exactamente lo mismo en otro foro pero a lo mejor por aquí hay alguien que me pueda ayudar.

Por un lado recibo en Ascii la direccion con 8 bytes de datos, desde la 0000000 hasta la 16000000 y por otro lado (tambien en Ascci) la intensidad de una señal con 2 bytes desde 00 hasta 99 (en la práctica este último valor pasará de 75). Cada direccion de 8 bytes llevará aparejado su valor de señal de 2 bytes. Esta señal de 2 bytes será maxima en un intervalo de direcciones. Tengo que saber la dirección media cuando la señal es maxima.

No se que hacer, si crear un fichero de texto para almacenar estos datos y luego hallar el valor/es maximo/s leyendo de nuevo los datos o hacerlo con algún tipo de base de datos.

¿Que debo hacer?.

Saludos.
  • 0

#2 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 15 junio 2013 - 01:42

Yo usaría un array de una estructura con el valor dirección y valor ya en numérico (WORD y BYTE). Luego recorres el array para llenar los datos y luego para analizarlos y hacer tus cálculos.



Saludos.
  • 0

#3 mosco

mosco

    Member

  • Miembros
  • PipPip
  • 11 mensajes

Escrito 15 junio 2013 - 05:17

Gracias por responder.
Se me olvido decir que las direcciones que recibimos no son consecutivas sino saltan de 4 en 4, es decir 00000000, 00000004, 00000008, ...
¿se puede usar un arreglo dinamico?
  • 0

#4 mosco

mosco

    Member

  • Miembros
  • PipPip
  • 11 mensajes

Escrito 16 junio 2013 - 03:20

He hecho esto pero no me graba los datos en fichero. Quiero ver los datos ordenados aunque el consejo de escafandra es bueno no tengo la experiencia  para hacerlo:



delphi
  1. procedure TForm1.Button10Click(Sender: TObject);
  2. var
  3.   i, j, ndirecciones, ndatos: integer;
  4.   begin
  5.     ndirecciones:= 100;
  6.     ndatos:= 0;                                    // Posiciones de azimut
  7.     Memo1.Clear;
  8.     dato:=#105;                                    //Izquierda 1ra vez
  9.     FileWrite(FHandle,PChar(dato)^,Length(dato));
  10.     try
  11.     for i:=0 to ndirecciones-1 do
  12.     begin
  13.       for j:=0 to 9 do
  14.         begin
  15.           Fileread(FHandle,PChar(dato)^,Length(dato));
  16.           memo1.Lines[0] := memo1.Lines[0] + dato;
  17.         end;
  18.       EnviaDatos('iwconfig wlan0 | grep -i "Link Quality" | cut -f2 -d ''='' | cut -f1 -d"/"');
  19.       RecibeDatosB;
  20. memo1.Lines[0] := memo1.Lines[0] + FuerzaSenialB;
  21.     end;
  22.   dato:=#112;
  23.   FileWrite(FHandle,PChar(dato)^,Length(dato));      //Paramos
  24.   Memo1.Lines.SavetoFile('serial.txt');
  25.   except On Exception Do
  26.     Showmessage('No se puede grabar archivo');
  27.   end;
  28.   end;


  • 0

#5 cadetill

cadetill

    Advanced Member

  • Moderadores
  • PipPipPip
  • 994 mensajes
  • LocationEspaña

Escrito 17 junio 2013 - 01:00

Hola mosco

Fíjate que siempre estás grabando en la posición 0 del Memo.

A parte de eso, en la 1er línea del memo tienes algo? Si es así, debería de grabarte algo. Sino, es que las funciones de lectura no te están funcionando bien. Esto podría ser porque FileRead es para leer de ficheros y, en tu código (o al menos en el que muestras), no estás abriendo ningún fichero (lo mismo con FileWrite).

Ejemplo de uso de FileRead sacado de la ayuda de Delphi



delphi
  1. procedure TForm1.Button1Click(Sender: TObject);
  2.  
  3. var
  4.   iFileHandle: Integer;
  5.   iFileLength: Integer;
  6.   iBytesRead: Integer;
  7.   Buffer: PChar;
  8.   i: Integer
  9. begin
  10.   if OpenDialog1.Execute then
  11.   begin
  12.     try
  13.       iFileHandle := FileOpen(OpenDialog1.FileName, fmOpenRead);
  14.       iFileLength := FileSeek(iFileHandle,0,2);
  15.       FileSeek(iFileHandle,0,0);
  16.       Buffer := PChar(AllocMem(iFileLength + 1));
  17.       iBytesRead := FileRead(iFileHandle, Buffer, iFileLength);
  18.       FileClose(iFileHandle);
  19.  
  20.       for i := 0 to iBytesRead-1 do
  21.       begin
  22.         StringGrid1.RowCount := StringGrid1.RowCount + 1;
  23.         StringGrid1.Cells[1,i+1] := Buffer[i];
  24.         StringGrid1.Cells[2,i+1] := IntToStr(Integer(Buffer[i]));
  25.       end;
  26.     finally
  27.       FreeMem(Buffer);
  28.     end;
  29.   end;
  30. end;



Fíjate que primero hace un OpenFile y, luego ya, cuando lo necesita, el FileRead

Saludos
  • 0

#6 mosco

mosco

    Member

  • Miembros
  • PipPip
  • 11 mensajes

Escrito 17 junio 2013 - 07:28

Gracias cadetill, esta tarde estudiaré el código que adjuntas.

Tal como esta el código que adjunté abre el fichero y lo escribe correctamente hasta el byte 77 aproximadamente y a partir de ahí es como si perdiera la sincronización. Y pierde la sincronización tanto de la direccion (entre paréntesis) como la recepcin de la fuerza de la señal que son los dos bytes a partir del paréntesis. Adjunto parte del comienzo del archivo que se graba en txt:



delphi
  1. (00080139)00(00120139)39(00160139)37(00200139)38(00240139)37(00280139)37(003209)(0380139)(00403739)(00440137(00480139)38(00520139)37(00560139)36(0600139)(3900640139)...



Saludos

PD: La direccion que son los 8 bytes dentro del parentesis parece que cambia de una forma rara pero no es asi, es correcto. Consiste en la informacion de 2 encoders de posicion, uno para el azimut y otro para la elevación. Tengo los 4 primeros bytes para la direccion de azimut que aumenta o disminuye cada 4 pasos del encoder y los 4 bytes de menos peso es la direccion de elevacion que aumenta o disminuye su valor cada 2 pasos de su encoder. Vemos en este trozo de archivo que he mostrado que el rotor que se está moviendo es el azimut en dirección de aumento de pasos.
  • 0

#7 Sergio

Sergio

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1.092 mensajes
  • LocationMurcia, España

Escrito 18 junio 2013 - 07:11

Supongo que "dato" es un pChar (no lo indicas) e imagino que al leer del fichero de byte en byte, en algún momento lees un char(0) y ese es el problema, que a partir de aquí, dato mide cero de longitud, y como lees en bloques de dato.length, pues eso, que deja de leer o algo así.

Pero bueno, pueden ser otras cosas, no indicas si el memo1 -en pantalla- se ve bien o mal, ni si lo que lees del FHandler te llega ya con los parentesis puestos o se ponen en alguna otra parte, o si lees del FHandler sin mas y lo copias a un txt "de un golpe" los valores aparecen bien o te llegan ya mal.

Quizas te llegen lecturas malas "genuinas" y no sea culpa de tu programa sino de los detectores esos que te envian los valores (igual alcanzan su rango maximo, coo si usases smallint y se desbordasen).

Faltan algunas pistas... *-)


  • 0

#8 mosco

mosco

    Member

  • Miembros
  • PipPip
  • 11 mensajes

Escrito 18 junio 2013 - 11:33

Gracias Sergio. Ayer conseguí adelantar muchísimo. Me lleno de alegría cuando se van resolviendo cosas y más cuando no se tiene demasiada experiencia.
He resuelto el problema haciendo varios cambios e implementaciones. Ahora escribe el fichero perfectamente de principio a fin con las direcciones y los datos. Incluso para dar mejor aspecto he añadido un Tmemo pequeñito donde se ve en tiempo real como avanza el valor de las direcciones (en este caso solo de azimut) y de la fuerza de la señal que llega en ese punto. Vean el código:



delphi
  1. procedure TForm1.Button10Click(Sender: TObject);
  2. var
  3.     a: string;
  4.     i, j, ndirecciones: integer;
  5.   begin
  6.     CrearFichero;
  7.     ndirecciones:= 200;
  8.     dato:=#105;                                    //Izquierda 1ra vez
  9.     FileWrite(FHandle,PChar(dato)^,Length(dato));
  10.     for i:=0 to ndirecciones-1 do
  11.     begin
  12.       Fileread(FHandle,PChar(dato)^,Length(dato));
  13.       if dato = '(' then
  14.         begin
  15.           memo2.Lines[0] := '(' ;
  16.           for j:=0 to 8 do
  17.           begin
  18.             Fileread(FHandle,PChar(dato)^,Length(dato));
  19.             memo2.Lines[0] := memo2.Lines[0] + dato;
  20.           end;
  21.           EnviaDatos('iwconfig wlan0 | grep -i "Link Quality" | cut -f2 -d ''='' | cut -f1 -d"/"');
  22.           RecibeDatosB;
  23.           memo2.Lines[0] := memo2.Lines[0] + FuerzaSenialB;
  24.           a:=memo2.Lines[0];
  25.         end;
  26.       EscribirDatos (a);
  27.     end;
  28.   dato:=#112;
  29.   FileWrite(FHandle,PChar(dato)^,Length(dato));      //Paramos
  30.   end;



Y vean un pedazo del archivo txt que se crea:



delphi
  1. (00080137)00(00120137)41(00160137)41(00200137)41(00240137)40(00280137)42(00320137)42(00360137)40(00400137)41(00440137)41(00480137)40(00520137)41(00560137)41(00600137)39(00640137)39(00680137)39(00720137)40...



La fuerza de la señal no varia casi nada porque el receptor no gira todavía con la antena. Cuando esté puesto en la antena el valor de los dos bytes de fuerza de señal tendrán mucha variación y entonces me enfrentaré a otro reto:  insertar el algoritmo para hallar la direccion donde la señal sea mas fuerte, para luego reorientar la antena a ese punto...

...pero va marchando.

Saludos a todos y nuevamente gracias por vuestra ayuda.
  • 0

#9 poliburro

poliburro

    Advanced Member

  • Administrador
  • 4.945 mensajes
  • LocationMéxico

Escrito 18 junio 2013 - 11:51


Saludos a todos y nuevamente gracias por vuestra ayuda.


Gracias por compartirnos la solución.
  • 0

#10 Sergio

Sergio

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1.092 mensajes
  • LocationMurcia, España

Escrito 19 junio 2013 - 01:46

Recorrer el fichero y detectar el mayor valor es sencillo: Lees la posicion entre parentesis, luego la lectura, y si es mayort que la anterior maxima, te quedas con ambos valores (posicion y valor), y asi hasta terminar el fichero.

Otra cosa es que quieras interpolar las intensidades usando coordenadas polares y localizar el maximo leyendo muy pocos puntos, eso tambien se puede, pero necesitas de mas matematicas que "max()", claro! Dimelo y te busco un sistema si lo necesitas.
  • 0

#11 mosco

mosco

    Member

  • Miembros
  • PipPip
  • 11 mensajes

Escrito 19 junio 2013 - 05:12

Sergio es como comentas en segundo lugar. La antena realizará un giro de 360 grados y en un intervalo de de 30 a 40 grados seguro que tendremos datos positivos en fuerza de la señal. Por ejemplo puedo obtener algo asi (pongo solo el valor de la fuerza de señal y no las direcciones):

7, 7, 9, 10, 9, 10, 10, 11, 11, 11, 12, 10, 11, 12, 12, 12, 10, 12, 12, 13, 13, 13, 11, 13, 12, 12, 10, 10 , 8.......

Necesito el algoritmo para centrar la antena justo en centro de máxima señal. He marcado en negrita donde a primera vista es mayor la fuerza de la señal y si el algoritmo me arrojara un resultado para el 13 que esta en el centro de los 3 que hay seguidos (me devolverá la direccion), estaría conforme con el resultado.

Saludos.
  • 0

#12 Sergio

Sergio

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1.092 mensajes
  • LocationMurcia, España

Escrito 19 junio 2013 - 08:19

¿Tienes todos esos valores en memoria o la elección ha de ser mientras se leen valores en serie?

La idea en cualquier caso es usar en lugar del 13 de la posicion i-esima para "valorarlo" y comparar con las demas posiciones, usas una combinacion de ese 13 con los 2 o 3 valores de antes y despues minorados mas conforme más te alejas de i:

Valor(i):= fuerza(i) + fuerza(i-1)*0.5 + fuerza(i+1)*0.5 + fuerza(i-2)*0.25 + fuerza(i+2)*0.25

Usando este valor y localizando el maximo, tienes el angulo para la antena sin problemas.

Dos cosas a tener en cuenta:

1) i es circular, el que va antes del 1 es el útimo, necesitarias  alguna funcion que de el elemento i+1 teniendo esto en cuenta.

2) Puedes sumar más terminos, solo disminuye a la mitad el coeficiente cada vez y listo (aunque 2 o 3 deberían bastarte si no se repite el maximo mas de 5 o 6 veces). En general, si elmaximo se repite N veces normalmente, suma desde i-N/2 hasta i+N/2 (aproximado).

3) Si tambien varia la altura azimut, la cosa puede complicarse un poco, aqui supongo que solo das una vuelta alrededor, no miras arriba y abajo a la misma vez.
  • 0

#13 mosco

mosco

    Member

  • Miembros
  • PipPip
  • 11 mensajes

Escrito 20 junio 2013 - 04:57

Sergio gracias por la explicacion. Intentando llevarla a la práctica me encuentro con un problemilla.
He de recorrer  los datos obtenidos para hallar el ultimo valor máximo y me encuentro con la primera duda:  El valor de fuerza de la señal lo tengo en dos caracteres ascci. Quiero pasarlos a una cadena de dos caracteres para aplicarles el StrToint('string de fuerza de la señal')  e ir almacenando en una variable para luego ir comparandola. Se que debe ser algo facil pero me puede.

Saludos.
  • 0

#14 cadetill

cadetill

    Advanced Member

  • Moderadores
  • PipPipPip
  • 994 mensajes
  • LocationEspaña

Escrito 21 junio 2013 - 12:14

Usa la función Chr para obtener el carácter correspondiente ;-)

Saludos
  • 0

#15 mosco

mosco

    Member

  • Miembros
  • PipPip
  • 11 mensajes

Escrito 21 junio 2013 - 07:14

Gracias cadetill, pero es pasar dos datos consecutivos tipo Char de un array a un solo valor entero.

Algunos post más arriba puse como quedaría el array. Tengo algo asi:
(00010002)27(00020002)27...

Ese 27 son 2 valores ascii (un string en definitiva) y lo quiero pasar a entero.

PD: La funcion Chr la tendré que utilizar para hacer la funcion inversa más tarde.

Saludos.
  • 0

#16 cadetill

cadetill

    Advanced Member

  • Moderadores
  • PipPipPip
  • 994 mensajes
  • LocationEspaña

Escrito 21 junio 2013 - 10:52

A ver si te entiendo, ¿quieres saber a qué carácter corresponde ese 27? Si es así, y suponiendo que lo tienes en una variable tipo cadena



delphi
  1. var
  2.   Tmp: string;
  3. begin
  4.   Tmp := '27';
  5.   Tmp := Chr(StrToInt(Tmp));



Eso si he entendido tu problema jejeje

Saludos
  • 0

#17 mosco

mosco

    Member

  • Miembros
  • PipPip
  • 11 mensajes

Escrito 22 junio 2013 - 02:02

Cadetill, he encontrado la funcion adecuada:

http://www.delphibas...L.asp?Name=Copy

La funcion copy usada asi:



delphi
  1. ......for k := 0 to length(arrayprincipal) do
  2.       begin
  3.         if arrayprincipal[k] = ')' then
  4.         begin
  5.           valor:=strtoint(copy(arrayprincipal, k+1, 2));....



Y asi de facil tendremos el correspondiente valor entero de dos valores ascii que estan en una cadena.

Saludos


  • 0

#18 cadetill

cadetill

    Advanced Member

  • Moderadores
  • PipPipPip
  • 994 mensajes
  • LocationEspaña

Escrito 22 junio 2013 - 03:00

Vale, tu problema era que no sabías cómo separar ese 27 de la cadena original :-)

Sí, la función copy es lo que necesitas :-)

Me alegra que lo hayas solucionado

Saludos
  • 0

#19 mosco

mosco

    Member

  • Miembros
  • PipPip
  • 11 mensajes

Escrito 28 junio 2013 - 02:30

Hola a todos. He realizado un procedimiento para calcular el valor de la direcion promedio donde se encuentran los datos de mayor señal. Compila bien pero da error en la ejecución:

          " is not a integer valid value

En el código del procedimiento que pongo a continuación una variable global que es:



delphi
  1. arrayprincipal: array[0..500] of string;



Acontinuación el codigo del procedimiento


delphi
  1. procedure  TForm1.ValorMaximo(orientacion:char);          //Funcion que halla el valor
  2. var                                                      //medio de la direccion en
  3.   k, l, n, valorEntero, tamanio, posicionMaximo:integer;  //donde la señal es mayor
  4.   senialMayor, promedioMinimo, promedioMaximo: integer;    //Se puede llamar tanto para
  5.   direccionMayor:array [1..8] of string;                  //azimut como para elevacion
  6.   direccionMenor:array [1..8] of string;
  7.   promedioMayorH:array [1..4] of string;
  8.   promedioMayorV:array [5..8] of string;
  9.   promedioMenorH:array [1..4] of string;
  10.   promedioMenorV:array [5..8] of string;
  11.   valorEnAscii: array [1..2] of string;
  12.   juntarCuatroChar:string;
  13.   begin
  14.     senialMayor:= 0;
  15.     posicionMaximo:=0;
  16.     for k := 1 to length(arrayprincipal) do
  17.       begin
  18.         if arrayprincipal[k] = ')' then
  19.         begin
  20.           valorEnAscii[1]:= arrayprincipal[k+1];
  21.           valorEnAscii[2]:= arrayprincipal[k+2];
  22.           valorEntero:= strtoint(valorEnAscii[1]+valorEnAscii[2]);
  23.             if valorEntero > senialMayor then
  24.               begin
  25.                 senialMayor:= valorEntero;
  26.                 tamanio:= 8;
  27.                 posicionMaximo:= k;
  28.                 for l:=1 to 8 do
  29.                   begin
  30.                     direccionMayor[tamanio]:=arrayprincipal[k-l];
  31.                     tamanio:=tamanio-1;
  32.                   end;
  33.               end;
  34.         end;
  35.       end;
  36.       if  orientacion = 'h' then                          //Direccion Horizontal
  37.       begin
  38.         for n:=1 to 4 do
  39.           begin
  40.             promedioMayorH[n]:=direccionMayor[n];
  41.           end;
  42.         promedioMaximo:=strtoint(promedioMayorH[1]+promedioMayorH[2]
  43.         +promedioMayorH[3]+promedioMayorH[4]);
  44.       end else
  45.       begin                                            //Direccion vertical
  46.         for n:=5 to 8 do
  47.           begin
  48.             promedioMayorV[n]:=direccionMayor[n];
  49.           end;
  50.         promedioMaximo:=strtoint(promedioMayorV[5]+promedioMayorV[6]
  51.         +promedioMayorV[7]+promedioMayorV[8]);
  52.         for k := posicionMaximo downto 0 do
  53.           begin
  54.           if arrayprincipal[k] = ')' then
  55.             begin
  56.               valorEnAscii[1]:= arrayprincipal[k+1];
  57.               valorEnAscii[2]:= arrayprincipal[k+2];
  58.               valorEntero:= strtoint(valorEnAscii[1]+valorEnAscii[2]);
  59.               if valorEntero = senialMayor then
  60.                   begin
  61.                     tamanio:=8;
  62.                     for l:=1 to 8 do
  63.                       begin
  64.                         direccionMenor[tamanio]:=arrayprincipal[k-l];
  65.                         tamanio:=tamanio-1;
  66.                       end;
  67.                   end;
  68.             end;
  69.           end;
  70.       end;
  71.         if  orientacion = 'h' then                        //Promedio vertical
  72.           begin
  73.             for n:=1 to 4 do
  74.               begin
  75.                 promedioMenorH[n]:=direccionMenor[n];
  76.               end;
  77.             promedioMinimo:=strtoint(promedioMenorH[1]+promedioMenorH[2]
  78.             +promedioMenorH[3]+promedioMenorH[4]);
  79.             juntarCuatroChar:=inttostr((promedioMaximo-promedioMinimo)div 2);
  80.             for n:=1 to 4 do
  81.               begin
  82.                 direccionPromedio[n]:=juntarCuatroChar[n];
  83.               end;
  84.             for l:=5 to 8 do
  85.               begin
  86.                 direccionPromedio[l]:= direccionMayor[l]; //Dejamos direccion vertical
  87.               end;
  88.           end
  89.         else                                              //Promedio Vertical
  90.           begin
  91.             promedioMinimo:=strtoint(promedioMenorV[5]+promedioMenorV[6]
  92.             +promedioMenorV[7]+promedioMenorV[8]);
  93.             juntarCuatroChar:=inttostr((promedioMaximo-promedioMinimo) div 2);
  94.             for l:=5 to 8 do
  95.               begin
  96.                 direccionPromedio[l]:= juntarCuatroChar[l];//Dejamos direccion vertical
  97.               end;
  98.             for l:=1 to 4 do
  99.               begin
  100.                 direccionPromedio[l]:= direccionMayor[l]; //Dejamos direccion azimut
  101.               end;
  102.   end;
  103.   end;



¿Donde esta el error?

Saludos
  • 0

#20 cadetill

cadetill

    Advanced Member

  • Moderadores
  • PipPipPip
  • 994 mensajes
  • LocationEspaña

Escrito 28 junio 2013 - 04:44

Deberías de debuggear el código, algún cambio de tipo (StrToInt) no está funcionando bien porque le estás pasando una cadena vacía

Saludos
  • 0




IP.Board spam blocked by CleanTalk.