martes, 14 de febrero de 2017

Números decimales, variables tipo float y función print





Es habitual que a veces necesitemos hacer algunos cálculos precisos con las variables que estemos manejando en nuestro sketch, y precisemos el manejo de decimales. Por ejemplo pudiera ser que quisiéramos usar nuestro Arduino para medir voltajes gracias a las entradas analógicas que tenemos en nuestra placa.


Como vimos en la entrada que dedicamos a la resolución de los pines analógicos  podríamos conseguir distinguir variaciones de hasta 4.9 milivoltios en nuestras mediciones. Así que por qué no ponernos manos a la obra y fabricarnoslo.


Versión 1 - Regla de tres para obtener el valor de voltaje
Para ello solo tenemos que aplicar una regla de tres muy sencillita:

Sin embargo, cuando abrimos el monitor serie para evaluar los resultados, el resultado que nos devuelve es siempre  "0" y no lo que esperábamos visualizar: un valor comprendido entre 0-5 voltios.



la razón del error es probable que esté localizada en el cálculo que hemos hecho al dividir 5/1023, que aunque nosotros de forma lógica pensamos que debería ser un número 0.00488758553, nuestro Arduino razona de diferente manera y lo redondea a 0. Y claro cualquier número multiplicado por 0 es 0. Así que tendremos que arreglarlo.


Versión 2 - Manejo de decimales

Vamos a escribir lo mismo pero de diferente forma. En lugar de 5/1023, vamos e escribir 5.0/1023.0, para nosotros es exactamente lo mismo que 5/1023, pero escribiéndoselo así, nuestro Arduino piensa que lo que tiene entre manos tiene que dar como resultado un número decimal. Veamos el resultado.

Bastante mejor, pero no todo lo bien que quisiéramos, si ahora en lugar de limitarnos a querer saber si en la salida tenemos 0, 1, 2, 3, 4 ó 5 voltios, quisiéramos sacar toda la precisión que tiene nuestros pines analógicos, que son capaces de discriminar variaciones de tensión de 4,9 milivoltios, lo único que se nos ocurre es es cambiar la definición de nuestra variable voltaje.



Versión 3 - Uso de variable tipo float
Hasta ahora hemos utilizado números enteros en todos nuestros ejemplos. Sin embargo, es muy habitual que los cálculos matemáticos den como resultados números decimales y no enteros. Para manejarlos, Arduino nos permite utilizar dos tipos de variables: float y double.

Los float tienen una precisión de 6 o 7 dígitos decimales. Al contrario que en otras plataformas, donde tu podrías obtener mayor precisión usando una variable tipo double (por ejemplo, por encima de 15 dígitos), en Arduino los double tienen el mismo tamaño que los float. En Arduino se mantienen los dos tipos por compatibilidad con C y C++, pero es importante tener en cuenta que no hay diferencia entre ambos. Los dos permiten utilizar números decimales entre el intervalo 3.4028235e+38 y -3.4028235e+38.
Así que parece evidente lo que debemos hacer. Vamos a cambiar la definición de la variable voltaje de entero (int) a decimal (float). Con ello deberíamos resolver el problema.
Pero ojo, a pesar de haber declarado la variable voltaje como float, parece que hay algún error en alguna parte, el resultado solo contiene dos números decimales y no todos los que esperábamos.



El origen del error esta vez no proviene de los cálculos, ni de la declaración de las variables. El error proviene de la función que estamos usando para visualizar los datos a través del monitor serie. Por defecto print y println sólo muestran dos posiciones decimales.

Versión 4 - Números decimales, variables tipo float y función print

De modo que si queremos sacar tres decimales, el truco está en decírselo a la función print de forma explícita. Pare ello después de indicarle lo que queremos que pinte en el monitor serie, le pondremos el número de decimales con los que queremos que nos lo enseñe.



De este modo ahora, si que nuestro sketch nos mostrará las medidas que queríamos obtener.




Espero que hayamos podido explicar bien el problema y como resolverlo adecuadamente. En breve haremos una entrada un poco más técnica sobre la manipulación de los números decimales y el porqué restas tan simples como  5.1-0.1 nunca dan 5.


Y ya sabéis, si tenéis alguna sugerencia o duda, no tenéis más que mandarnos un correo a
e intentaremos responder a vuestra pregunta lo antes que podamos.