Problema concatenando Strings

Hola a todos

He leído bastante el foro durante los últimos meses pero es la primera vez que escribo.

En general, todas las dudas se resuelven navegando y buscando por el foro, pero esta vez no ha habido suerte.

Mi duda es la siguiente, tengo un programa que tiene que enviar unos cuantos parametros concatenados por GPRS mediante POST. La parte que me está fallando es el momento de concatenar varias cadenas.

He usado la librería String, de reciente inclusión en el core, y he probado a usar el operador '+=' y la suma, y ninguno me funciona con ciertas cadenas.

Al principio todo va bien, pero llega a una cadena, que parece resetear el String, y devuelve en blanco.

Os pasteo el trozo de código que uso para testeo:

/*
 Programa para leer datos del GPS, parsearlos y enviarlos por GPRS con el formato del servicio web de Iternova.
 Formato de la cadena a enviar:
 ID=555&h=ad27065efe037b4aa291633ce3767904&lt=90.0000000&lg=-000.0000000&rt=1980/01/06,00:19:50&v=000.00&c=1&s=1&sm=1
 ID   - Identificacion del GPS
 h    - Hash de seguridad
 lt   - latitud  (en º)
 lg   - longitud  (en º)
 rt   - tiempo real (año/mes/dia,hora:minutos:segundos)
 v    - velocidad en kmph
 c    - estado de la cuchilla del quitanieves
 s    - estado del esparcidor de sal
 sm   - estado del esparcidor de salmuera
 
 */ 
 
 #include <ctype.h>
 #include <md5.h>
 #include <SimpleTimer.h>
 

 
 
 int ledPin = 13;                  // LED test pin
 int rxPin = 9;                    // RX PIN 
 int txPin = 8;                    // TX PIN
 int onModulePin = 2;              // the pin to switch on the module (without press on button) 

 
 //Variables de configuración!!!
 String clave = "1234567";    //clave para calcular MD5
 int ID = 569 ;         //ID del GPS
 int tiempo = 5;      //tiempo en segundos entre captura de puntos GPS
 
 
 
 


 SimpleTimer timer;
 MD5 md5Hasher;
 
 //datos a enviar, lo hacemos global para poder concatenar en diferentes
 //ejecuciones del timer (por si falla el envio...)
 String datos; 
 
 
 
 void setup() {
      
     Serial.begin(19200);          //puerto serie para GPRS
   
  
   //configuracion de eventos por tiempo
  timer.setInterval(tiempo*1000, EventoGPS);
  
 }
 

 //Bucle principal, solo activa el temporizador que dispara nuestra función
 void loop() {
   timer.run();
  }
  
  
//Funcion que extrae los datos del objeto GPS y los devuelve en un string
//con el formato adecuado para concatenarlo para el envío.

String extraePosicionGPS()
{
  String temp;
   
   temp = String("&lt=34.7643930&lg=-01.7489403");
  
  return temp; //para test sin GPS
  
    
}



//Funcion que extrae los datos del objeto gps y los devuelve en un string
//con el formato adecuado para concatenarlo para el envío.
//esta NO devuelve el nombre del parámetro antes (&rt=) para poder pasarselo
//directamente al MD5

String extraeTiempoGPS ()
{  
   String temp;
   
   temp = String("2010/9/10,13:35:15");
  
  return temp; //para test sin GPS
}
  

//Funcion que devuelve el valor de la velocidad ya con formato de envio

String extraeVelocidadGPS ()
{
  String temp;
   
   temp = String("&v=99.74");
  
  return temp; //para test sin GPS
 
  
}  
  
   
  
//funcion que lee el valor del gps

bool leeGPS()
{
  
  return true; //para test sin GPS
}
  



//funcion que transforma un float en String.
//Copiada del ejemplo de la libreria TinyGPS!

String floatToString(double number, int digits)
{
  String cadena;
  
  // Handle negative numbers
  if (number < 0.0)
  {
     Serial.print('-');
     number = -number;
  }

  // Round correctly so that print(1.999, 2) prints as "2.00"
  double rounding = 0.5;
  for (uint8_t i=0; i<digits; ++i)
    rounding /= 10.0;
  
  number += rounding;

  // Extract the integer part of the number and print it
  unsigned long int_part = (unsigned long)number;
  double remainder = number - (double)int_part;
  //Serial.print(int_part);
  cadena += int_part;

  // Print the decimal point, but only if there are digits beyond
  if (digits > 0)
    cadena += ".";
    //Serial.print("."); 

  // Extract digits from the remainder one at a time
  while (digits-- > 0)
  {
    remainder *= 10.0;
    int toPrint = int(remainder);
    cadena += toPrint;
    //Serial.print(toPrint);
    remainder -= toPrint; 
  } 
  return cadena;
}

 
 //Hace el hash MD5 de la cadena que recibe y lo devuelve en otra cadena
 String MD5hash (String input)
 {
      String resultado_hash;     
      char str[32];
      char str2[32];
      md5_hash_t hash;
      
      input.toCharArray(str,50);
      md5Hasher.ComputeHash(&hash, str);
      MD5::ToHexString(hash, str2);
      resultado_hash=String(str2);
      return resultado_hash;
 }
 
 
 
 
 
 
 
 //Funcion PRINCIPAL!!
//Funcion que se ejecuta cada "tiempo" segundos, lee del GPS, //formatea la información y la envía por GPRS
//al servidor

 void EventoGPS()
 {
   String posicion, tiempo, velocidad;
   
   String envio;
   String reemplazo;
   String cadena_hash, resultado_hash;
   static boolean envioOK=true;
   static int num_fallos=0;
   
   
   if (leeGPS()) 
   {
      posicion = extraePosicionGPS();
      tiempo = extraeTiempoGPS();
      velocidad = extraeVelocidadGPS();
      Serial.println("obtenidos valores:");
      Serial.println(posicion);
      Serial.println(tiempo);
      Serial.println(velocidad);
      
      if (true)
      {
          //hacemos el hash de la clave mas la fecha y hora.
          cadena_hash=clave;
          cadena_hash += tiempo;
          resultado_hash = MD5hash (cadena_hash);
          Serial.println(resultado_hash);
          
          Serial.println("creamos la trama");
          
          envio = "ID=";
          envio = envio + ID;
          envio = envio + "&h=";
          envio = envio + resultado_hash;
          Serial.println(envio);
          envio = envio + posicion;
          Serial.println(envio);
          envio = envio + "&rt=";
          envio = envio + tiempo;
          Serial.println(envio);
          envio = envio + velocidad;
          Serial.println(envio);
          envio = envio + "&c=1&s=0&sm=1";      
          Serial.println(envio);
          
          datos=envio; //enviamos solo una trama
       
      
       }
     }
 
 }

El resultado de la consola serie que da es el siguiente:

obtenidos valores:
&lt=34.7643930&lg=-01.7489403
2010/9/10,13:35:15
&v=99.74
D092F194115C896710F7A525832374B6
creamos la trama
ID=569&h=D092F194115C896710F7A525832374B6

&rt=2010/9/10,13:35:15

&c=1&s=0&sm=1

Parece que al concatenar las cadenas "posicion" y "velocidad" el String se va al carajo... a pesar de que el Serial.print de estas cadenas se ve correctamente.

Ando muy perdido, ¿alguien puede arrojar algo de luz en mi problema?

Muchas gracias de antemano!

Yo uso la libreria string asi:

dataString.append("Esto es ");
dataString.append("Una prueba");

He probado a cambiar las instrucciones en varias maneras:

cadena += cadenaAñadida
cadena = cadena + cadenaAñadida
cadena.concat (cadenaAñadida)

Siempre el mismo resultado... no funciona.

En esta versión no existe "append", se ha sustituido por "concat" y de hecho, si miras en la librería, "concat" solo hace "cadena += argumento"... así que estamos en las mismas...

¿Puede ser un bug de la librería? ¿Debería pasarlo al foro general en inglés?

A veces incluso estas operaciones parece que acceden a partes de memoria que no corresponden, sacando en los println basura o incluso valores de otras variables. :-[

PD: Creo que no había especificado que estoy usando la librería String presente en el IDE 0019, es decir, la que ya va incluida en el core.

Pues no me habia enterado que ha salido la V.19

En el peor de los casos puedes usar la del v.18 que es la que yo uso asi.

Lo que si he visto en la pag. de arduino es que pone que algo nuevo estan preparando???

veremos a ver...

Un saludo.