Enviar y recibir números por puerto serie en Arduino Deja un comentario

En esta entrada vamos a ver cómo elegir números enteros o en coma flotante por puerto serie, dentro de esta serie de entradas destinada a profundizar en el uso del puerto serie.

Al igual que en la entrada anterior, donde vimos cómo recibir caracteres y cadenas de texto, si buscamos por internet veremos muchos códigos para realizar esta acción, con mayor o menor grado de acierto. Esto es debido a que existe más de una forma de realizar el proceso, cada uno con sus ventajas y desventajas.

En esta entrada presentaremos los principales métodos para recibir un número por puerto serie, y cuando resulta más conveniente emplear uno u otro.

 

La funciones DEBUG están únicamente para visualizar los resultados, cuando uséis este código podéis quitar las partes relativas a su definición y uso.

Igual que cuando vimos cómo recibir un único carácter, recibir un único dígito es muy sencillo y eficiente. De hecho, es prácticamente idéntico a recibir un carácter, pero posteriormente eliminamos el valor de ‘0’ para convertir el char a integer.

La eficiencia del método es máxima, ya que apenas contiene procesamiento. La mayor desventaja, lógicamente, es que únicamente podemos recibir un dígito. Aunque generalmente es insuficiente, puede ser útil para recibir una transmisión sencilla, como la opción de un menú o el número de parpadeos de un LED.

Si queremos recibir números de más de un dígito, que es lo normal, tenemos varias opciones disponibles. La primera que vamos a ver es emplear las funciones de la clase Serial, Serial.ParteInt() y Serial.ParseFloat().

Así, el siguiente ejemplo recibe un número entero.

Mientras que la recepción de un float sería la siguiente,

Esta forma de recepción es muy empleada porque resulta cómoda y sencilla de integrar en nuestro código. Sin embargo, tiene bastantes desventajas que hacen que sea desaconsejable su uso.

En general, es un método bastante lento. Además, es bloqueante, es decir, el programa queda parado esperando el número hasta que salta el timeout.

Por otro lado, si recibe un único salto de línea se devolverá un céro, lo cual es un problema en un buen número de aplicaciones.

Una forma mucho más adecuada es emplear las funciones de la clase String. Empleamos la función Serial.readStringUntil() para recibir una línea en un String, y después las funciones String.toInt() y String.toFloat() para convertir a número.

El ejemplo para número entero es siguiente.

Mientras que el ejemplo para coma flotante sería el siguiente.

La función es prácticamente igual de sencilla que el ejemplo anterior, pero normalmente es más eficiente. Además, tenemos mayor control porque podemos elegir cualquier carácter como separador (algo útil, por ejemplo, para dividir un texto separado por comas).

En general, debería ser vuestra primera opción para recibir números por puerto serie.

Igual que cuando al recibir cadenas de texto, si no podemos o no queremos usar la clase String podemos usar un char array y las funciones atoi() y atof() para conseguir funcionalidades similares, como vimos en a la hora de convertir texto en números.

La lectura de un integer sería la siguiente

Mientras que la lectura de un float se haría así.

Sin embargo, tenemos el inconveniente de tener que definir el tamaño del buffer por nosotros mismos, algo que no es necesario con la clase String.

La velocidad es similar a la conseguida con la clase String, ya que la clase String emplea las funciones atoi y atof internamente. De hecho, es levemente superior porque requiere un menor procesamiento.

Por su parte, la capacidad de control del proceso es similar a la que obtendríamos con la clase String.

Por tanto, en general preferiremos usar la clase String, y sólo usaremos estos métodos cuando no queramos o no podamos emplear la clase String.

Finalmente, tenemos el método “naive” que recordamos es la forma elegante de decir hacer el proceso “a mano”. Por lo menos resulta interesante para entender cómo funcionan los métodos anteriores internamente.

Aquí tenemos un código para hacer la recepción y conversión a un número entero.

El código necesario para recibir un número en coma flotante es ligeramente más largo.

El método naive no es mucho más rápido que las funciones atoi o atof y ,por extensión, que los métodos toInt() o toFloat() de la clase String(), ya que la implementación mostrada es similar a la empleada internamente por estas funciones.

La mayor ventaja es que tenemos un control total sobre el proceso. Por ejemplo, en el caso de nuestro proceso de conversión a número con coma flotante hemos permitido que admita ‘.’ y ‘,’ como separador decimal, sin una pérdida sustancial de eficiencia.

Pero en general, salvo que tengamos requisitos especiales que justifiquen la conversión a mano, tendremos eficiencias similares empleando las funciones de la clase String.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Enviar Whatsapp
Hola 👋
¿En qué podemos ayudarte?