Puerto Serie GPS U-Blox, Arduino, payload>buffer

Buenas, ante todo agradecer la ayuda a todos los usuarios del foro y creadores, que conseguis poco a poco que todo sea mucho más accesible y facil de entender.

A continuación os hago una consulta que lleva varios días dandome vueltas y no entiendo el motivo...

Tengo el GPS Ublox 6M, modelo GY-GPS6MV2, conectado al Arduino UNO. Lo he conectado al puerto serial y realizo la lectura del puerto serie con el siguiente código:

#include <SoftwareSerial.h>
int i=0;
byte v[91];

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

void loop() {
  if(Serial.available()>0){  
      for(i=0;i<92; i++){
        v[i]=Serial.read();
      }
      Serial.print("nnEl mensaje es ");Serial.print("n");
      for (i=0;i<92;i++){ 
      Serial.print(v[i],HEX);
      }
  }
}

El mensaje que he configurado tiene 92 bytes, del GPS al Arduino se envía lo siguiente:

0000 B5 62 01 07 54 00 20 06 2F 0F E1 07 02 0E 16 2D
0010 16 07 F8 FF 3E 02 51 62 01 00 00 00 06 00 94 13
0020 C5 FC 3E 48 8A 15 69 77 01 00 63 C4 00 00 00 C4
0030 92 85 80 59 73 5E 00 00 00 00 00 00 00 00 00 00
0040 00 00 00 00 00 00 00 00 00 00 20 4E 00 00 80 A8
0050 12 01 0F 27 00 00 84 D3 11 00 6A 96

Y lo que recibo es...

El mensaje es
B5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B

El mensaje es
62175402062FFE172E162D167F8FF3E251621000609413C5FC3E488A1569771063C4000C492858059735E0000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B

Al ver eso... me di cuenta, que el problema era el tamaño que agrego... que lo que envio supera el buffer del arduino y el tamaño no debe ser siempre 92, ya que el buffer lo mismo a almacenado más o menos en cada pasada, por lo que se me ocurrió hacer la siguiente prueba para comprobar que es lo que le llega realmente...

#include <SoftwareSerial.h>
int i=0, capacidad;
byte v[91];

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

void loop() {
  if(Serial.available()>0)
  {
    Serial.print("nLa capacidad a leer del buffer es:");
    capacidad=Serial.available();Serial.print(capacidad); Serial.print("n");
     
      for(i=0;i<capacidad; i++){
        v[i]=Serial.read();
      }
     
    Serial.print("Vamos a imprimir lo leido hasta el tamano de V= "); Serial.print(capacidad); Serial.print("n");
      for (i=0;i<capacidad;i++){     //Imprimir en pantalla el mensaje
        Serial.print(v[i],HEX);
      }
    Serial.println("");
  }
}

Y para mi sorpresa es que el paquete de datos que envia el GPS (los 92 bytes) lo recibe arduino en 3 bloques con los siguientes tamaños: 1,60 y 30 o 1 61 y 29 (varían según le parece...).
Y no entiendo el motivo. Se recibe de la siguiente forma:

La capacidad a leer del buffer es:1
Vamos a imprimir lo leido hasta el tamano de V= 1
B5

La capacidad a leer del buffer es:61
Vamos a imprimir lo leido hasta el tamano de V= 61
6217540606639FE172E16382A71803F2D6D3FBFF00609413C5FC3E488A1569771063C400076B58680E7405F00000000

La capacidad a leer del buffer es:29
Vamos a imprimir lo leido hasta el tamano de V= 29
00000000000204E0080A8121F270084D31107694

0000 B5 62 01 07 54 00 60 66 39 0F E1 07 02 0E 16 38
0010 2A 07 18 00 3F 02 D6 D3 FB FF 00 00 06 00 94 13
0020 C5 FC 3E 48 8A 15 69 77 01 00 63 C4 00 00 00 76
0030 B5 86 80 E7 40 5F 00 00 00 00 00 00 00 00 00 00
0040 00 00 00 00 00 00 00 00 00 00 20 4E 00 00 80 A8
0050 12 01 0F 27 00 00 84 D3 11 00 76 94

El GPS funciona bajo protocolo UBX en mi caso: 9600bps, 8 bits de datos, sin paridad y 1 bit de stop, que es el mismo bajo el que funciona Arduino por defecto: Serial.begin(9600,SERIAL_8N1).

Alguien podría ayudarme a entender porque ocurre esto o que es lo que no hago bien, si hay algun otro método... o algo para mensajes mayores del buffer.

Muchísimas gracias a todos.
Un saludo

El buffer de la UART esta definido en 64 bytes pero de este modo puedes cambiarlo

#define SERIAL_BUFFER_SIZE 256

prueba a ver si se resuelve?

Hola, muchas gracias por la respuesta. Lo he estado mirando, y nada...

Se modifica con la siguiente línea:

#define SERIAL_RX_BUFFER_SIZE 256

El compilador te avisa, que se ha redefinido la variable y te dice donde se guarda el archivo...
He probado en modificar directamente el archivo, que está en la ruta:

...arduino\hardware\avr\1.6.13\cores\arduino/HardwareSerial.h

Y nada... Aparece igual.

He probado con el siguiente código:

#include <SoftwareSerial.h>
#define SERIAL_RX_BUFFER_SIZE 256

int i=0;
byte v[91];
int lonBuffer; //Variable que guarda la capacidad del buffer

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

void loop() {
  while(Serial.available()>0)
  {  
    lonBuffer=Serial.readBytes(v,Serial.available());
    Serial.print("\n\nLa capacidad a leer del buffer es:");
    Serial.print(lonBuffer); Serial.print("\n");
    Serial.print("El vector Buffer es:");
      for (i=0;i<lonBuffer;i++){
        Serial.print(v[i],HEX);
      } 
  }
}

Y seguimos igual... No se si hago algo mal, pero he mirado, buscado y nada...

Seguiré luchando!
Muchísimas gracias por la respuesta!! aprendí algo que no sabia ;).

Para que defines SoftwareSerial y luego no lo usas?
comenta esa primera línea no usada.

Prueba a 115k según he visto acá (link).
Luego hay otro ejemplo mas completo.

Intenta a ver si el ejemplo inicial te resuelve el problema para lo que debes cambiar tambien la velocidad en el GPS.

Buenas, gracias por tu respuesta, aprendí algo más sobre el Puerto serie y Arduino, que no tenía muy claro. Pero no he conseguido solucionar mi problema :(.

He realizado el programa aumentando la vel como dices, y nada, ni velocidad en GPS, ni en arduino, ni na... Me imprime muchos caracteres "F" y no aparece el mensaje completo...

Lo que sí me he dado cuenta es que aunque amplie el buffer a 256 (según he leido); no se amplia. Es decir, he creado el siguiente programa para que indique la cantidad de elementos que hay en el buffer:

#define _SS_MAX_RX_BUFF 256 //Amplia el buffer del SoftwareSerial simulado (Software)
#define SERIAL_RX_BUFFER_SIZE 256  //Amplia el buffer de RX (Hardware)
#define SERIAL_TX_BUFFER_SIZE 256 //Amplia el buffer de TX (Hardware)

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

void loop()
{
     Serial.print(Serial.available()); Serial.print(" ");
}

Aparece en un principio "0" y conforme escribo en el monitor serial caracteres, este número se aumenta... hasta que llego a 63 y ahí nos quedamos. Puede ser algo de esto...

Seguire... muchísimas gracias!!

Si llega a 63 es porque no te esta tomando el cambio de buffer y si incluyes 0 hasta 63 estas contando exactamente 64 bytes.

Esta por ahi.

Hola, JuanIsidoro.
Precisamente llevo unos días enfrascado en crear unos ArduTips sobre el tema de la comunicación Serial. Creo que allí estará retratado el problema que estás sufriendo aquí, pero para no hacerte esperar, prueba a ver así:

  if(Serial.available()){  
    Serial.readBytes(v, 91);
    Serial.print("nnEl mensaje es ");Serial.print("n");
    for (i=0;i<92;i++){
      Serial.print(v[i],HEX);
    }
  }

Surbyte, el cambio de buffer no lo ha detectado... no sé pq, no lo entiendo... no lo he podido conseguir.

Noter, me inspiraste!!! ajajajja, ya había usado esa función; y la emplee bien en su momento, con la salvedad que la usé con punteros y me dió un error asociado a otro problema y no le hice caso... Pensé que había metio la pata por otro lado y tenía apuntadao probar con la función:

Serial.readBytesUntil(character, buffer, length)

la cual termina si se detecta el carácter (un checksum), la longitud, o alcanza el tiempo de espera.

El caso, es que con esa función va perfecto! lee del buffer hasta alcanzar la longitud indicada! y sin problemas. Hoy voy a dormir más que tranquilo ajajajaj, que llevo varios días con esta pena y no entendía motivos...

Os dejo el código tal cual he empleado, por si otro puede obtener también beneficios ^^.

int i=0;
byte v[92]; //Vector byte de tamaño de elementos
void setup() {
Serial.begin(9600);
}

void loop() {
 if(Serial.available()){  
   Serial.readBytes(v, 92);
   Serial.print("\n\nEl mensaje es\n");
   for (i=0;i<92;i++){
     Serial.print(v[i],HEX); Serial.print(" "); 
   }
 }
}

Al emplearlo por el SoftwareSerial, funciona igual de bien ;).

Muchísimas gracias a todos, a seguir así!!