Enviar una estructura de int, char/string y float con nRF24L01+, entre dos nano.

Hola a tod@s.

Quiero transmitir una estructura compuesta de int, char/string y float entre dos nanos con nRF24L01+.

El problema lo tengo cuando la estructura lleva algún char o string.

La necesidad de incluir datos tipo char o string es porque tengo que enviar un float de 15 decimales y no soy capaz de enviar más de 6. (datos gps, ejemplo: float 34.346719834578412)

Podría utilizar algún ‘truco’ como enviar la parte entera y convertir la decimal en un entero para dividirlo en dos (por cuestiones de overflow).

Seguro que hay alguna formas más ‘elegante’, correcta y eficiente de hacerlo.

El proyecto consiste en un drone controlado desde el pc con un joystick de 4 ejes, mapa, waypoints, grabar rutas, vuelo autónomo (versión 2.0) y tonterías de esas. (el programa lo desarrollo en VB).

La comunicación es bidireccional y funciona correctamente. Este verano hice el típico coche, también con estos módulos y lo controlaba sin problemas porque la información de sentido/giro/velocidad eran enteros.

Lo que intento transmitir es:

12,34.123456789012345, -1.123456789012345, 11.22, 11.22, 11.22, 11.22, 11.22, 11.22, 11.22, 11.22, 11.22

Aquí os dejo un ejemplo de las estructuras que he intentado usar para enviar/recibir:

struct estructuraDatos {
 int tipo;
 String param1;
 char param2[15];
 float param3;
 float param4;
 float param5;
 float param6;
 float param7;
 float param8;
 float param9;
 float param10;
};

nota: no pego código del transmisor/receptor porque el problema es sólo a la hora de enviar/recibir la estructura.
Cualquier ejemplo de la librería nRF24L01+ sirve para ilustrar la comunicación.

En cuanto cambio alguno a string (en receptor y emisor), recibo cosas como esta:

����\��n�d���e�����W�1���n��{���_�������_o�x���z7~.�ח��[�����{=>��N������/��w�}���{���X����7~w��{]���g���ۮ�п�g���k�"����1����_�6���^���+]���~�? 1�����3�ۚ��R�����W��o���{�w�P�^=�5������A����������}����Ǒ����zm������S}��

Lo ideal sería poder enviar el float con 15 decimales o en su defecto, ver la forma más sencilla de hacerlo.

Muchas gracias por vuestro tiempo y un saludo desde Murcia.

Primero los datos de lat y long son double, porque no usas double en lugar de float, lo intentaste?

Sino la forma elegante es con union y algo que contenga lo que quieres enviar (hablo de los bytes).

Ejemplo:

struct Sensores{
   float temperatura;
   float humedad;
   int   luz;
};
 
union Datos{
   Sensores dato;
   byte     b[sizeof(Sensores)]; 
}
origen, destino; 
 
 
void setup()
{
   Serial.begin(9600);
   delay(1000);
 
   
   origen.dato.temperatura = -103.38;
   origen.dato.humedad     = 84.06;
   origen.dato.luz         = 124;
 
   Serial.print("OrigenT=  ");   Serial.print(origen.dato.temperatura);
   Serial.print("\nOrigenH=  "); Serial.print(origen.dato.humedad);
   Serial.print("\nOrigenL=  "); Serial.print(origen.dato.luz);
 
   
   for(int i=0 ; i < sizeof(origen.dato) ; i++)
      destino.b[i] = origen.b[i];
 
      
   Serial.print("\n\nDestinoT=  "); Serial.print(destino.dato.temperatura);
   Serial.print("\nDestinoH=  ");   Serial.print(destino.dato.humedad);
   Serial.print("\nDestinoL=  ");   Serial.print(destino.dato.luz);
}
 
void loop()
{
}

Gracias por la respuesta.

En cuanto llegue a casa hago pruebas y posteo el resultado.

En cuanto a que es double y no float, los ejemplos que he visto usan funciones para convertir float a string.

También he leído en muchas webs al consultar los tipos de datos de arduino y tratan por igual float y double.

Un saludo.

Tratar por igual no significa que tu defnas un float y lo cargues con un double.
Primero que no puedes segundo la mantisa en el double es justamente el doble de float y ese es tu problema.

Hola de nuevo.

He modificado la estructura para enviar la latitud y longitud como double.
El truco es interpretar los datos recibidos.

Espero que sirva de ayuda a otros tantos como yo.

Según los ejemplos de la librería TinyGPS

if (gps.encode(c)) 
     {
       float flat, flon;  
       unsigned long age, date, time;
       ...
       ...

define flat y flon como float. Por eso te decía que eran float.

En muchas webs dicen que en arduino, float y double es lo mismo y no lo es, por cuestiones de precisión.

En el mismo programa de ejemplo de arriba, hay una función llamada printFloat, que refuerza la idea de que son float. Lo que realmente hace es enviar al puerto serie la parte entera, el punto decimal y los decimales que quieres.

Aparte de esto, otro de los errores que he cometido es dar por hecho que lo que veo en el puerto serie es realmente el valor de la variable.

Resulta que al hacer el típico Serial.print(variable); , ya sea float o double, SÓLO muestra 2 decimales por defecto.

La solución es hacerlo así: Serial.print(variable, num_decimales);

Ahora recibo todos los decimales que necesito.

Caso resuelto !!.

Muchas gracias, surbyte.

nota: no soy capaz de modificar el título original para añadir [SOLUCIONADO].

Bueno tu lo has dicho.

En tu caso me da gusto que sacaras las conclusiones que has sacado.
Cuando no sepas simplemente pones

Arduino float o Arduino double y buscas el playground, o busca la alternativa de Kike_GL en el ArduWiki sobre ambos, te darán buenas respuestas.
Esto dice de double y de float