Error en sprintf; lectura incorrecta de una variable

Buenas tardes


Disculpen las molestias y las posibles faltas al reglamento del foro pues aún soy nuevo y un poco inexperto en Arduino :sweat_smile:, pero la verdad he investigado sobre el comando "sprintf(); y me he topado con un problema en la ejecución de un código para un proyecto personal que no sé cómo resolver.

necesito enviar una variable de 3 dígitos de manera que las unidades queden "001", los decimales "010" y las centésimas "100". Me refiero, los números menores a 100 quedan antecedidos por ceros.

para probar el envío de la variable y los ceros, he hecho este código en Arduino Uno (pero lo pienso pasar a un arduino NANO):

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10,11); //Pin 10 TX , Pin 11 RX connected to--> Bluetooth TX,RX

int val;//valor escrito en el puerto serial

const char  MI= 'x'; //Marca Inicial para diferenciar los valores en el receptor

const char  Mc= '0';//ceros que anteceden a los numeros menores de 100

char buffer[4];// Variable "buffer" que almacenara la variable procesada para enviarla por el bluetooth

void setup() {

Serial.begin(9600);

 mySerial.begin (38400);

delay(1000);

Serial.println("digite el codigo");

Serial.println("                             ");//texto de inicio
}

void loop() {

  if (Serial.available()>0){

  val = Serial.read();// lector del puerto serial

  if (val<10){//condicional para unidades

  sprintf(buffer,"%c%c%c%d",MI,Mc,Mc,val); // concadeno la "x" con dos "0" y el valor del Serial / "x001", "x002... "009".

  mySerial.print(String(buffer));// envio por bluetooth la variable procesada

  Serial.print("digito:");//escribo en el Serial para saber el digito enviado

  Serial.print(String(buffer));//miro por el serial la variable procesada

  Serial.println();//dejo un espacio

  }
  
  // repito la acción con pocos cambios para las demas condiciones.

  
  else if(val>9&&val<100){

     sprintf(buffer,"%c%c%d",MI,Mc,val);// concadeno la "x" con un solo "0" y el valor del Serial / "x010", "x011"... "099".

  mySerial.print(String(buffer));

  Serial.print("digito:");

  Serial.print(String(buffer));

  Serial.println();

    }

  else if(val>100){

     sprintf(buffer,"%c%d",MI,val);// concadeno la "x" con el valor del Serial / "x100", "x101"... "x999".

  mySerial.print(String(buffer));

  Serial.print("digito:");

  Serial.print(String(buffer));

  Serial.println();

    }

  }
  
}

el problema es que cuando escribo algo en el Serial me manda 3 líneas (en vez de solo una) y me lee mal el valor escrito.

Por ejemplo: si escribo " 1 " me muestra lo siguiente:

1


digito:x049
digito:x013
digito:x010

en vez de solo "digito:x001". ¿Alguien me puede explicar por qué sucede esto y como lo puedo corregir? :disappointed_relieved:

Muchisimas gracias por su atención :grin: :grinning:

2018-10-09.png

manejo_por_serial_sprintf.ino (1.68 KB)

Mira detenidamente tu código.

Primero compruebas si hay datos en el puerto serie con available y acto seguido lees SOLO UN BYTE utilizando read.

¿Qué ocurre cuando mandas un número por consola?

En tu ejemplo pones "1". El arduino no recibe una cadena con un 1 si no lo que recibe es el código ASCII del carácter '1', es decir 0x49. Además en la consola tienes puesto que envie el "retorno de carro" y el "salto de línea", con lo que además has recibido dos bytes más extra: 0x13 y 0x10.

¿Qué pasa si mandas "99". Como lo haces byte a byte recibiras una secuencia de 4 bytes. El valor ascii de 9 dos veces, mas el retorno de carro y el salto de línea.

Si deseas recibir un número podrías utilizar la función readString. En pseudo-código se parecerá a algo como esto:

String cadena;

void loop()
{
  if ( Serial.available() )
  {
    cadena = Serial.readString(); // Leo la cadena enviada por consola.
    var = cadena.toInt(); // la convierto en un número.
    sprintf(buffer,"digitio: %03d", var); // La escribo formateada.
  }

En el ejemplo he formateado la cadena en sprintf utilizando "%03d", esto hará que la función utilize 3 caracteres rellenando con 0 los que no tienen valor.

Te aconsejo que le eches un vistazo a la referencia de String, Serial, y sprintf.

Muchisimas gracias por la ayuda, y si, leeré más sobre los comandos. porque aun no entiendo bien el alcance de muchos :sweat_smile: 8)
mil gracias, llevo un mes tratando de solucionar los problemas de ese proyecto y ya con este espero sea el último