Autor Tema: Ayuda : Float a int32 con decimales  (Leído 2041 veces)

0 Usuarios y 3 Visitantes están viendo este tema.

Desconectado stiventronic

  • PIC10
  • *
  • Mensajes: 5
Ayuda : Float a int32 con decimales
« en: 27 de Marzo de 2016, 23:57:22 »
Buenas a tod@s me acabo de registrar en este foro ya que veo que el contenido que aqui se maneja me ha servido de gran ayuda y orientación, y el motivo del post es que requiero de su talento de orientacion ... bueno al grano :

se que se han tratado temas similares pero aun no logro el resultado deseado ... el asunto  es que tengo una aplicacion embebida con un PIC 18f4550 de microchip, el compilador ccs 5.045, la aplicacion me permite conectarme mediante USB al PC, enviar y recibir datos con Labview 2015, en el ordenador debo monitorear el valor de un sensor de temperatura infrarrojo el MLX90614 que se comunica al PIC mediante I2C, todo este rollo ya esta montado en protoboard y funcionando, tengo comunicacion envio y recibo cadenas de bytes, el inconveniente que tengo es que solo he logrado enviar los datos del sensor de temperatura MLX90614 al PC sin decimales, a continuacion muestro una parte del codigo y lo que he tratado para pasar la variable float donde se almacenan los datos del sensor a un arreglo de bytes para enviarlo por USB y mostrarlo en Labview.

//////////////////////////////////////////////////////////////////

   disable_interrupts(INT_TIMER0);
   enable_interrupts(INT_USB);
   enable_interrupts(GLOBAL);
   usb_init_cs();
   kbd_init();
   lcd_init();
   tempc = 240.7;
   dir_tempc = &tempc;
   
   intento[0] = *(&tempc);
   intento[1] = *(&tempc + 1);
   intento[2] = *(&tempc + 2);
   intento[3] = *(&tempc + 3);

//////////////////////////////////////////////////////////////////

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Ayuda : Float a int32 con decimales
« Respuesta #1 en: 28 de Marzo de 2016, 00:35:52 »
No enteindo cual es tu pregunta, o que queres hacer, que esperas recibir del lado de la PC ?, por que no enviar el float directo a la PC y que este se encarge de "modificarlo"

Sino lo que podes hacer es usar el sprintf() para pasar el float a string, y enviar el string. Ademas no recuerdo si CCS y XC8 se manejan con el formato IEEE 754, o tiene su propio formato. Por que recuerdo si no mal recuerdo para facilitar el calculo en los micros vi en un documento de Microchip que tenian en otro lugar el bit de signo.

Citar
el inconveniente que tengo es que solo he logrado enviar los datos del sensor de temperatura MLX90614 al PC sin decimales

Es que al enviar los 4 bytes que conforman el float, estas enviando el exponente, el signo y la mantisa. En resumen estas enviando todo, tal ves luego en la PC no estas armandolo bien.
CCS usa el estilo de Microchip (32bits), segun el manual de CCS, para que se entienda:

IEEE 754 ( lo que manejan las PC y esta normalizado ) :

Código: [Seleccionar]
  +-+--------+-----------------------+
 |S|  Exp   |  Mantisa              |
 +-+--------+-----------------------+
 31 30    23 22                    0

Microchip/CCS:

Código: [Seleccionar]
  +--------+-+-----------------------+
 |  Exp   |S| Mantisa               |
 +--------+-+-----------------------+
 31     24   22                    0

Y que tal ves por eso no puedas hacer una conversion directa, como para ponerlo en el "float" de la PC.
Las razones para usar el modelo de Microchip son obvias, el exponente es de 8 bits  y entra en un registro justo de esa forma. Pero podrias llegar a tener problemas con la compatibilidad.


EDIT: Me base en el manual de CCS, que muestra que:

1 : 0x7F 0x00 0x00 0x00
-1: 0x7F 0x80 0x00 0x00

Segun el manual de XC8, este cumple con el IEEE 754, como es el unico que posee y puedo probar, decidi probarlo y si, en la version de 32bits cumple con el formato IEEE 754, que qeuda:

1 : 0x3F 0x80 0x00 0x00
-1: 0xBF 0x80 0x00 0x00
« Última modificación: 28 de Marzo de 2016, 00:48:50 por KILLERJC »

Desconectado stiventronic

  • PIC10
  • *
  • Mensajes: 5
Re:Ayuda : Float a int32 con decimales
« Respuesta #2 en: 28 de Marzo de 2016, 01:27:56 »
No enteindo cual es tu pregunta, o que queres hacer, que esperas recibir del lado de la PC ?, por que no enviar el float directo a la PC y que este se encarge de "modificarlo"

Bueno, lo que pretendo hacer es enviar la variable tempc que es tipo float (32 bit) mediante la comunicacion USB y para ello tendria que pasar esa variable BYTE por BYTE  (4 Bytes), e intentado con punteros y no me funciona ... ejemplo :

 float tempc = 240.7         // Visualizo esta variable en proteus como microchip float y en hexadecimales equivale a : 0x8670B333
 float *dir_tempc = &tempc    // Guardo la direccion de registro para acceder a sus datos
 int intento[4];                 // Variable donde almaceno BYTE por BYTE el valor de float tempc
 
 // es aqui donde no se si es la forma correcta de pasar los datos :

   intento[0] = *(&dir_tempc);
   intento[1] = *(&dir_tempc + 1);
   intento[2] = *(&dir_tempc + 2);
   intento[3] = *(&dir_tempc + 3);

 Lo del tema de formatos "microchip float" y "IEEE754" lo puedo manejar con labview, lo que necesitaria en este caso seria esto:

si float tempc = 240.7    // en hexadecimal equivale a : 0x8670B333  <---- estos datos son los que necesito pasar al arreglo int intento[4]
                                       // deberia quedar asi :  intento[0] = 33  ; intento[1] = B3 ; intento[2] = 70 ; intento[3] = 86 
                                       // vez que son 4 Bytes que son la composicion del float

eso es lo que pretendo y muchas gracias por tu colaboracion

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Ayuda : Float a int32 con decimales
« Respuesta #3 en: 28 de Marzo de 2016, 01:56:43 »
OK, tu problema esta en la definicion del puntero.. Existen 2 formas que hagas esto:

1era - Usando punteros:

Es la menos recomendada, por que es mas complejo y no tiene sentido complicarse la vida.
Como decia tu problema esta en la definicion de tu puntero, lo definiste como un puntero a float, asi que sumarle 1 significa avanzar 4 bytes. Y vos necesitas avanzar byte a byte.
Entonces lo declaro como un uint8_t ( entero de 8 bits sin signo ), y necesito castear el puntero como un puntero de a 8 bits, por que &tempc es un puntero a float lo cual no coincide con la definiciones de dir_tempc, finalmente accedo a los lugares, esta ves si byte a byte.

Código: C
  1. float tempc = 240.7
  2. uint8_t *dir_tempc = (uint8_t *)&tempc;         // Creacion del puntero y casteado a 8 bits sin signo
  3. int intento[4];
  4.  
  5.  // es aqui donde no se si es la forma correcta de pasar los datos :
  6.  
  7.    intento[0] = *dir_tempc;
  8.    intento[1] = *(dir_tempc + 1);
  9.    intento[2] = *(dir_tempc + 2);
  10.    intento[3] = *(dir_tempc + 3);


2da - Usar una union

Esta es la ideal de paso te ahorras ese array llamado "intento", aunque aca lo puse para que veas como podes sacar los valores, me refiero a como acceder a los mismo:

Código: C
  1. union dato {        // Defino la union, y sus componentes
  2.         float   f;
  3.         uint8_t b[4];
  4. };
  5.  
  6. union dato tempc;            // Asigno el formato de la union a tempc, es decir recien aca creo a tempc.
  7.  
  8. tempc.f = 240.7;             // Cargo el valor como si fuera un flotante a traves de f.
  9.  
  10. // Ahora accedo byte a byte a traves de "b" es decir asi:
  11.  
  12.    intento[0] = temp.b[0]
  13.    intento[1] = temp.b[1]
  14.    intento[2] = temp.b[2]
  15.    intento[3] = temp.b[3]

En ves de enviar intento, envias temp.b[0] en adelante.
Ademas con la union no significa que tempc va a ocupar 8 bytes ( 4 float y 4 de los bytes ), sino que utiliza los bytes del mismo float, es decir ocupa simplemente 4 bytes. y ademas te ahorras a intento[]
« Última modificación: 28 de Marzo de 2016, 02:01:39 por KILLERJC »

Desconectado stiventronic

  • PIC10
  • *
  • Mensajes: 5
Re:Ayuda : Float a int32 con decimales
« Respuesta #4 en: 28 de Marzo de 2016, 02:11:31 »
Que buen dato buen hombre, ya lo probe y efectivamente funciono, ahora sigue transformarlo en labview de eso me encargo  yo, y despues te cuento como termina todo, aqui adunto una foto del progreso actual, montaje en protoboard y DAQ con labview PC. y muchas gracias nuevamente aunque programo en PIC C Compiler tu ejemplo fue bastante claro y lo adapte sin inconvenientes.

Desconectado elgarbe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2178
Re:Ayuda : Float a int32 con decimales
« Respuesta #5 en: 28 de Marzo de 2016, 06:24:25 »
Buenas, he luchado con ese tema no hace mucho y una alternativa es castearlo directamente a un uint8_t que es lo que espera la funcion de envío del USB:

(uint8_t *) tempc

y, por supuesto, informar que son 4 bytes los que vas a enviar.

Saludos
-
Leonardo Garberoglio

Desconectado stiventronic

  • PIC10
  • *
  • Mensajes: 5
Re:Ayuda : Float a int32 con decimales
« Respuesta #6 en: 30 de Marzo de 2016, 00:59:39 »
 Muchas gracias por su colaboracion, realmente son personas muy utiles y con grandes conocimientos, espero serles de ayuda asi como ustedes lo son, finalmente finalice con exito el proyecto  :-/ :-/ :-/

Dejo un adjunto de como luce finalmente.