Guardar Serial.readBytes en una variable String y usar String Remove

Tengo un problema al momento de usar el método de String Remove.

Estoy leyendo un numero de 18 dígitos con un hand-held barcode scanner IDM24X (SICK) el cual esta conectado a un arduino mega 2560 por medio del puerto serie y dicho numero lo quiero guardar en una variable que se llama Hilo para después de que sea guardada eliminar los primeros y últimos 6 dígitos y me despliegue y guarde de nuevo en la misma variable los 6 dígitos del centro del dato original leído por el scanner.

Anexo el void loop del código.

Nota: este código se esta guardando en un arduino uno puesto que despues de realizar esta operacion se continuara con otra parte del proyecto anexando ambas partes.

void loop() {
    if (Serial.available()) {
   delay(3000);    
   Hilo = Serial.readBytes(dato1,30);{
   Serial.print(Hilo);
   lcd.setCursor(4,0);
   lcd.print(Hilo);
   delay(3000);
   lcd.clear();
   
      Serial.print(\n\n"Remover los primeros y ultimos 6 digitos");
      lcd.setCursor(0,0);
      lcd.print("Remover los primeros y ultimos 6 digitos");
   Hilo.remove(0, 6);
   Hilo.remove(6, 12); 
   Serial.print(Hilo);
   lcd.setCursor(0,1);
   lcd.print(Hilo);
   delay(3000);
   lcd.clear();
    }
   }
  }

Nota: la variable Hilo se esta declarando como una variable String al inicio osea...(String Hilo :wink:
y el puerto serie se inicializa a 115200 baudios.

Espero me puedan ayudar mi conocimiento y las investigaciones que he hecho en internet ya no han podido solucionar mi duda.
Muchas gracias.

PD. en el monitor serial me despliega únicamente un numero 19 y el texto que se manda a imprimir un lado.

Te recomiendo que leas mis últimos posts de este tópico que cree.

Yo lo he solucionado eso en vez de con remove, voy leyendo cachos de la trama y me quedo con lo importante. Eso sí, la trama debe tener la misma configuración. Luego actualizo mi ultimo post que he hecho algún cambio. Dame una hora

Gracias he leído unos de tus post pero no he podido comprender como solucionar mi problema, esperare a que lo modifiques como dijiste, quedo en espera de tu respuesta.
Saludos.

Te he dicho que esperes una hora pero...... Al ritmo que lleva la camarera del hotel en el que estoy será algo más.

If (camarera_recoge_2o_plato) {
       CamareraRead(postres);
    } else{ 
        Cefere0.se aburre
}

Me aburro mucho....
Aquí tampoco hay pokemon a.... Seguiré con CoC jjjj

Vamos al lío.

En mi caso tengo 3 arduinos que me envian datos a un Mega.

estos datos, los elijo yo. Necesito enviar estos datos:

-Un numero (estado) que me dice el estado en que esta el Uno
-un contador A
-un contador B
-un contador C.

Que pasa, el estado es un unico digito, pero los contadores pueden tener de 1 a 5 digitos. para enviar esto hago una cadena a la que llamo dato de esta manera:

Aqui se me presenta el primer problema, si un contador hoy tiene 1 digio y mañana tiene 3, no puedo tener un codigo que me decodifique correctamente la trama enviada. Para solucionar eso hago lo siguiente:

Primero paso mis variables (int y unsigned long) a String (las variables las tenia creadas fuera de este void para usarlas cuando quiera)

Pestado = String(estado, DEC);
PcontA = String(contA, DEC);
PcontB = String(contB, DEC);
PcontC = String(contC, DEC);

Luego creo otra variable para saber cuantos bytes me ocupa cada String

  PestadoLong = Pestado.length();
  PconALong = PcontA.length();
  PcontBLong = PcontB.length();
  PcontCLong = PcontC.length();

una vez se cuanto me ocupa cada uno, voy a forzar que me ocupen una cantidad fija de caracteres (bytes)

  while (PestadoLong < 2){         // Ajuste del tamano del dato
    Pestado = '0' + Pestado;        // Concatena un "0" adelante del dato
    PestadoLong = Pestado.length(); // Realiza la operacion de obtencion de tamano nuevo del dato
  } 


  while (PcontALong < 6){         // Ajuste del tamano del dato
    PcontA = '0' + PcontA;        // Concatena un "0" adelante del dato
    PcontALong = PcontA.length(); // Realiza la operacion de obtencion de tamano nuevo del dato
  } 

con los otros 2 contadores lo mismo

En mi caso he decidido que estado ocupe 2 bytes y los estados ocupen 6. Aqui aclaro que si la maquina que he hecho dura hasta que cualquiera de los 3 contadores llegue a 999.999 monedas introducidas me daré con un canto en los dientes (En el peor caso 1/2 millon de Euros) Seguro que antes se ha roto todo por viejo.

Por lo que tengo: 2 Bytes + 6 Bytes + 6 Bytes +6 Bytes

Para enviar esto y tenerlo fácil de decdificar le añado algunos bytes de más:

String dato = Pestado + 'a' + PcontA + 'b' + PcontB + 'c' + PcontC + 'd';

Hablando en bytes seria esto: 2a6b6c6d. Total 24 bytes

luego lo envío:

 Serial.println(data);

Sí, ya se que tu recibes el dato y no lo generas, pero asi se entiende bien

Sigo... Ahora el receptor:

Primero le digo que empiece a leer el puerto serial.

 while (Serial1.available()>0){

Lo que me llega es de este tipo: "XXaYYYYYYbWWWWWWcMMMMMMd"

Ahora le digo que me lea la trama hasta la 'a'

Pestado_1 = Serial1.readStringUntil('a').toInt();

y ya de paso con .toInt() paso lo que hay a la izquierda de la 'a' a una variable tipo int

con lo que tengo Pestado_1=XX y en el buffer me queda: "YYYYYYbWWWWWWcMMMMMMd"

repetimos proceso, leo hasta la 'b' y me lo guardo como int:

contA_1 = Serial1.readStringUntil('b').toInt();

Ahora ya tengo:

Pestado_1=xx
contaA=YYYYYY

y me sobra: "WWWWWWcMMMMMMd"

repetimos proceso, leo hasta la 'c' y me lo guardo como int:

contB_1 = Serial1.readStringUntil('c').toInt();

Ahora ya tengo:

Pestado_1=xx
contA=YYYYYY
contB=WWWWWW

y me sobra: "MMMMMMd"

y volvemos a repetir:
leo hasta la 'd' y me lo guardo como int:

contC_1 = Serial1.readStringUntil('d').toInt();

Ahora ya tengo:

Pestado_1=xx
contA=YYYYYY
contB=WWWWWW
contB=MMMMMM

y ya no me sobra nada.

Una vez descompuesta la trama hago lo que me de la gana con cada variable.

En tu caso, este procedimiento te puede valer SIEMPRE Y CUANDO la trama que recibas sea siempre con el mismo formato. creo que me he explicado jjjjjj

Hilo = Serial.readBytes(dato1,30);

Según esta línea, asumiré lo siguiente: que estas son las variables globales:

String Hilo;
byte dato1[30];

En esa línea de código ocurre lo siguiente:

  • Lee el búfer del serial hasta vaciarlo, o hasta los 30 bytes; lo leído se almacena en el array dato1.
  • El String Hilo tendrá almacenado "18" (según lo que dijiste).

Quizá venga la pregunta: por qué Hilo tiene un número de dos dígitos y no de dieciocho?
Simple: readBytes, por declaración, devuelve el número de bytes leídos; no los bytes leídos; por eso es válido hacer esto:

byte cuenta = Serial.readBytes(dato1,30);

Claro, aún así no es mentira eso de que lee bytes, pero... a dónde va lo leído? Al primer parámetro de la función (array dato1).

Bueno pues... cómo corrijo eso?
Podrías utilizar la función readString en su lugar, solo que se tardará el tiempo de un "timeout" (por defecto, 1 segundo). Así:

Hilo = Serial.readString();
// Ahora puedes ahorrarte el array dato1

Espero que esto te haya ayudado bastante... :wink:

eso parece bastante mas fácil que mi opción jjjj

Asi es cefere0 parece mas fácil la otra manera que comenta lucario448 pero igual las 2 me fueron útiles antes de leer lo que puso lucario448 ya había comprendido lo que me habías explicado respecto a recibir datos y estaba pensando como aplicarlo para mi programa mientras seguía leyendo lo que escribías.

lucario448 muchas gracias creo que lo que tu me comentaste es mas fácil al menos para mis conocimientos acerca de arduino, te agradezco mucho tu colaboración, modificare mi codigo y les hago saber cual fue el resultado.
Saludos.

Me ha funcionado perfecto muchísimas gracias. :slight_smile: :slight_smile: :slight_smile: :slight_smile:

Si as así, entonces agrega [SOLUCIONADO] al título (editando el primer post del hilo).

Elpractitioner:
PD. en el monitor serial me despliega únicamente un numero 19 y el texto que se manda a imprimir un lado.

Y yo decía que 18. El byte extra debió ser '\n' o '\r' (cambio de línea)