Pages: [1]   Go Down
Author Topic: Función para partir y unir un float  (Read 1572 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Full Member
***
Karma: 0
Posts: 200
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Buenas.

Por necesidades varias necesito coger un float y guardarlo como dos int (para transmitirlo por modbus); luego tengo que coger esos dos ints y volver a componer el float.

Dicho de otra manera.
-Crear un float
-Meter los dos primero bytes en un int
-Meter los dos segundos bytes en otro int
-transmitirlos por modbus (eso ya lo tengo en marcha)
-volver a componer el float en base a los dos ints

He echado un vistazo a las operaciones

Code:
#include <WProgram.h>
template <class T> int EEPROM_writeAnything(int ee, const T& value)
{
    const byte* p = (const byte*)(const void*)&value;
    int i;
    for (i = 0; i < sizeof(value); i++)
  EEPROM.write(ee++, *p++);
    return i;
}

template <class T> int EEPROM_readAnything(int ee, T& value)
{
    byte* p = (byte*)(void*)&value;
    int i;
    for (i = 0; i < sizeof(value); i++)
  *p++ = EEPROM.read(ee++);
    return i;
}

y se que aqui tengo la respuesta, pero no lo saco.

¿Alguna manita?

Gracias.
Logged

Offline Offline
Edison Member
*
Karma: 23
Posts: 1375
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Si no funciona lo que te comento puedes utilizar la forma que se ha comentado alguna vez en el foro: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1207242838
Debería estar en español por aquí, pero no lo encuentro mirando por encima.

Prueba con esto, a ver que tal funciona.

Code:
int send(const float& value)
{
    const int* p = (const int*)(const void*)&value;
    for (int i = 0; i < sizeof(value)/sizeof(int); i++)
 MODBUS.SEND(*p++);
    return i;
}

int read(float& value)
{
    int* p = (int*)(void*)&value;
    for (int i = 0; i < sizeof(value)/sizeof(int); i++)
 *p++ = MODBUS.READ();
    return i;
}
« Last Edit: June 16, 2012, 07:34:35 pm by chiva » Logged

Mercadillo electrónico. Kit iniciación a Arduino, shield LCD a color y más cosas!

Euskadi
Offline Offline
God Member
*****
Karma: 16
Posts: 738
Arduinotarrak
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola,
También podrías declarar una  union, que es una estructura de C que puede contener varias cosas distintas. Una vez comenté esa posibidad en el foro: http://arduino.cc/forum/index.php/topic,69929.0.html

Logged

Offline Offline
Edison Member
*
Karma: 23
Posts: 1375
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola,
También podrías declarar una  union, que es una estructura de C que puede contener varias cosas distintas. Una vez comenté esa posibidad en el foro: http://arduino.cc/forum/index.php/topic,69929.0.html
Mira el primer enlace que he puesto smiley-lol
Logged

Mercadillo electrónico. Kit iniciación a Arduino, shield LCD a color y más cosas!

0
Offline Offline
Full Member
***
Karma: 0
Posts: 200
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ostras, union hace la fuerza
Voy a probarlo
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 200
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ya estoy de vuelta.

Con un servidor modbus en mi pc le puedo mandar el float partido en dos ints.
Esto lo hace bien y luego puedo recuperarlo de igual manera con el PC.

El problema viene cuando quiero volver a montar esos dos ints en un float y escribirlo en puerto serie.

El codigo que tengo es más o menos:


Code:

//fuera de setup y loop

unsigned int regs1[21];

union {
unsigned int ints[2];
float toFloat;
} foo;

void loop {

  foo.ints[0]=regs1[15];
  foo.ints[1]=regs1[16];

}


void contestar{

      Serial.println(foo.ints[0]);
      Serial.println(foo.ints[1]);
      Serial.println(foo.toFloat);
}


Eso está resumido.
Cuando llamo a "contestar" me aparece:
4059
16457
0.00

El float que debería aparecer es 3.141592654 (aprox)

Creo que el problema está en la implementación del float. Es decir: el pc ha mandado 2 ints que luego él sabe componer, pero arduino no.
¿Puede ser?
¿opiniones, ideas?
Logged

Euskadi
Offline Offline
God Member
*****
Karma: 16
Posts: 738
Arduinotarrak
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola,

Prueba con este ejemplo, el Serial.print a mí me da 3.141593
Code:

union
{
  unsigned int ints[2];
  float toFloat;
} foo;


void setup()
{
   Serial.begin(9600);
}   
   

   
void loop()
{
  // 3.141593
  foo.ints[0]=4059;
  foo.ints[1]=16457;

  Serial.println(foo.toFloat, 6); // con 6 decimales
  Serial.println(foo.ints[0]);
  Serial.println(foo.ints[1]);
  Serial.println("");
  delay(500);
}



« Last Edit: June 17, 2012, 10:54:24 pm by curro92 » Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 200
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Pues a mi me da...

Code:
0.000000
4059
16457

0.000000
4059
16457


Y ahora es cuando yo digo... es que no estoy usando Arduino, estoy usando una chipkit max32.
Pero... ¿No debería dar igual?

Un saludo.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sin mirar muhco tu codigo..
Y si enviás como dos intetegers directamente?? La parte entera como tal, y la real la "convertis" a un entero.. Algo parecido se usa para imprimir floats en LCDs..

mm. Ejemplo..

float = 2.25

entero = int(2.25); // entero = 2
enviar(entero);

real = (float - entero) * 100;  // real = 25
enviar(real);

Despues tenes que hacer algo parecido para recuperar el dato.
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 200
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Buenos dias.

1) No puedo usar el método de partir entero y decimal por que no puedo elegír la manera. Ya me viene el float en 4 bytes

2) Creo que ya se el motivo de que no funcione el union. Chipkit utiliza enteros de 4 bytes, con lo cual no sirve para la carambola. Intentaré hacer algo como:

Code:
union
{
  unsigned short shorts[2];   //o uint16_t
  float toFloat;
} foo;


void setup()
{
   Serial.begin(9600);
}   
   

   
void loop()
{
  // 3.141593
  foo.ints[0]=4059;
  foo.ints[1]=16457;

  Serial.println(foo.toFloat, 6); // con 6 decimales
  Serial.println(foo.ints[0]);
  Serial.println(foo.ints[1]);
  Serial.println("");
  delay(500);
}

Cuando pueda lo probaré.

Un saludo, y muchas gracias.
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 200
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Efectivamente.

int en Chipkit usa 4 bytes. Cuando he usado dos short para montar un float ha salido bien.

Muchas gracias compañeros.
Logged

Pages: [1]   Go Up
Jump to: