Tratamiento de un bloque de datos
#1
Escrito 15 junio 2013 - 09:37
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.
#2
Escrito 15 junio 2013 - 01:42
Saludos.
#3
Escrito 15 junio 2013 - 05:17
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?
#4
Escrito 16 junio 2013 - 03:20
procedure TForm1.Button10Click(Sender: TObject); var i, j, ndirecciones, ndatos: integer; begin ndirecciones:= 100; ndatos:= 0; // Posiciones de azimut Memo1.Clear; dato:=#105; //Izquierda 1ra vez FileWrite(FHandle,PChar(dato)^,Length(dato)); try for i:=0 to ndirecciones-1 do begin for j:=0 to 9 do begin Fileread(FHandle,PChar(dato)^,Length(dato)); memo1.Lines[0] := memo1.Lines[0] + dato; end; EnviaDatos('iwconfig wlan0 | grep -i "Link Quality" | cut -f2 -d ''='' | cut -f1 -d"/"'); RecibeDatosB; memo1.Lines[0] := memo1.Lines[0] + FuerzaSenialB; end; dato:=#112; FileWrite(FHandle,PChar(dato)^,Length(dato)); //Paramos Memo1.Lines.SavetoFile('serial.txt'); except On Exception Do Showmessage('No se puede grabar archivo'); end; end;
#5
Escrito 17 junio 2013 - 01:00
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
procedure TForm1.Button1Click(Sender: TObject); var iFileHandle: Integer; iFileLength: Integer; iBytesRead: Integer; Buffer: PChar; i: Integer begin if OpenDialog1.Execute then begin try iFileHandle := FileOpen(OpenDialog1.FileName, fmOpenRead); iFileLength := FileSeek(iFileHandle,0,2); FileSeek(iFileHandle,0,0); Buffer := PChar(AllocMem(iFileLength + 1)); iBytesRead := FileRead(iFileHandle, Buffer, iFileLength); FileClose(iFileHandle); for i := 0 to iBytesRead-1 do begin StringGrid1.RowCount := StringGrid1.RowCount + 1; StringGrid1.Cells[1,i+1] := Buffer[i]; StringGrid1.Cells[2,i+1] := IntToStr(Integer(Buffer[i])); end; finally FreeMem(Buffer); end; end; end;
Fíjate que primero hace un OpenFile y, luego ya, cuando lo necesita, el FileRead
Saludos
#6
Escrito 17 junio 2013 - 07:28
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:
(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.
#7
Escrito 18 junio 2013 - 07:11
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...
#8
Escrito 18 junio 2013 - 11:33
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:
procedure TForm1.Button10Click(Sender: TObject); var a: string; i, j, ndirecciones: integer; begin CrearFichero; ndirecciones:= 200; dato:=#105; //Izquierda 1ra vez FileWrite(FHandle,PChar(dato)^,Length(dato)); for i:=0 to ndirecciones-1 do begin Fileread(FHandle,PChar(dato)^,Length(dato)); if dato = '(' then begin memo2.Lines[0] := '(' ; for j:=0 to 8 do begin Fileread(FHandle,PChar(dato)^,Length(dato)); memo2.Lines[0] := memo2.Lines[0] + dato; end; EnviaDatos('iwconfig wlan0 | grep -i "Link Quality" | cut -f2 -d ''='' | cut -f1 -d"/"'); RecibeDatosB; memo2.Lines[0] := memo2.Lines[0] + FuerzaSenialB; a:=memo2.Lines[0]; end; EscribirDatos (a); end; dato:=#112; FileWrite(FHandle,PChar(dato)^,Length(dato)); //Paramos end;
Y vean un pedazo del archivo txt que se crea:
(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.
#9
Escrito 18 junio 2013 - 11:51
Saludos a todos y nuevamente gracias por vuestra ayuda.
Gracias por compartirnos la solución.
#10
Escrito 19 junio 2013 - 01:46
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.
#11
Escrito 19 junio 2013 - 05:12
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.
#12
Escrito 19 junio 2013 - 08:19
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.
#13
Escrito 20 junio 2013 - 04:57
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.
#14
Escrito 21 junio 2013 - 12:14
Saludos
#15
Escrito 21 junio 2013 - 07:14
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.
#16
Escrito 21 junio 2013 - 10:52
var Tmp: string; begin Tmp := '27'; Tmp := Chr(StrToInt(Tmp));
Eso si he entendido tu problema jejeje
Saludos
#17
Escrito 22 junio 2013 - 02:02
http://www.delphibas...L.asp?Name=Copy
La funcion copy usada asi:
......for k := 0 to length(arrayprincipal) do begin if arrayprincipal[k] = ')' then begin 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
#18
Escrito 22 junio 2013 - 03:00
Sí, la función copy es lo que necesitas :-)
Me alegra que lo hayas solucionado
Saludos
#19
Escrito 28 junio 2013 - 02:30
" is not a integer valid value
En el código del procedimiento que pongo a continuación una variable global que es:
arrayprincipal: array[0..500] of string;
Acontinuación el codigo del procedimiento
procedure TForm1.ValorMaximo(orientacion:char); //Funcion que halla el valor var //medio de la direccion en k, l, n, valorEntero, tamanio, posicionMaximo:integer; //donde la señal es mayor senialMayor, promedioMinimo, promedioMaximo: integer; //Se puede llamar tanto para direccionMayor:array [1..8] of string; //azimut como para elevacion direccionMenor:array [1..8] of string; promedioMayorH:array [1..4] of string; promedioMayorV:array [5..8] of string; promedioMenorH:array [1..4] of string; promedioMenorV:array [5..8] of string; valorEnAscii: array [1..2] of string; juntarCuatroChar:string; begin senialMayor:= 0; posicionMaximo:=0; for k := 1 to length(arrayprincipal) do begin if arrayprincipal[k] = ')' then begin valorEnAscii[1]:= arrayprincipal[k+1]; valorEnAscii[2]:= arrayprincipal[k+2]; valorEntero:= strtoint(valorEnAscii[1]+valorEnAscii[2]); if valorEntero > senialMayor then begin senialMayor:= valorEntero; tamanio:= 8; posicionMaximo:= k; for l:=1 to 8 do begin direccionMayor[tamanio]:=arrayprincipal[k-l]; tamanio:=tamanio-1; end; end; end; end; if orientacion = 'h' then //Direccion Horizontal begin for n:=1 to 4 do begin promedioMayorH[n]:=direccionMayor[n]; end; promedioMaximo:=strtoint(promedioMayorH[1]+promedioMayorH[2] +promedioMayorH[3]+promedioMayorH[4]); end else begin //Direccion vertical for n:=5 to 8 do begin promedioMayorV[n]:=direccionMayor[n]; end; promedioMaximo:=strtoint(promedioMayorV[5]+promedioMayorV[6] +promedioMayorV[7]+promedioMayorV[8]); for k := posicionMaximo downto 0 do begin if arrayprincipal[k] = ')' then begin valorEnAscii[1]:= arrayprincipal[k+1]; valorEnAscii[2]:= arrayprincipal[k+2]; valorEntero:= strtoint(valorEnAscii[1]+valorEnAscii[2]); if valorEntero = senialMayor then begin tamanio:=8; for l:=1 to 8 do begin direccionMenor[tamanio]:=arrayprincipal[k-l]; tamanio:=tamanio-1; end; end; end; end; end; if orientacion = 'h' then //Promedio vertical begin for n:=1 to 4 do begin promedioMenorH[n]:=direccionMenor[n]; end; promedioMinimo:=strtoint(promedioMenorH[1]+promedioMenorH[2] +promedioMenorH[3]+promedioMenorH[4]); juntarCuatroChar:=inttostr((promedioMaximo-promedioMinimo)div 2); for n:=1 to 4 do begin direccionPromedio[n]:=juntarCuatroChar[n]; end; for l:=5 to 8 do begin direccionPromedio[l]:= direccionMayor[l]; //Dejamos direccion vertical end; end else //Promedio Vertical begin promedioMinimo:=strtoint(promedioMenorV[5]+promedioMenorV[6] +promedioMenorV[7]+promedioMenorV[8]); juntarCuatroChar:=inttostr((promedioMaximo-promedioMinimo) div 2); for l:=5 to 8 do begin direccionPromedio[l]:= juntarCuatroChar[l];//Dejamos direccion vertical end; for l:=1 to 4 do begin direccionPromedio[l]:= direccionMayor[l]; //Dejamos direccion azimut end; end; end;
¿Donde esta el error?
Saludos
#20
Escrito 28 junio 2013 - 04:44
Saludos