Académique Documents
Professionnel Documents
Culture Documents
CONVERTIR TEXTO A
NÚMERO EN ARDUINO
19 JUNIO, 2017
En esta entrada vamos a ver cómo convertir una cadena de texto a número, bien sea entero
o flotante, en un microprocesador como Arduino.
Esta es una petición que vemos habitualmente en páginas y foros de Internet, y sobre la que
a veces existe confusión porque hay más de una forma de realizar la conversión, cada una con sus
ventajas y desventajas.
En esta entrada veremos las principales formas de convertir una cadena a un número entero
o flotante, y cuando resulta conveniente emplear una u otra.
La funciones DEBUG están únicamente para visualizar los resultados. Si usáis estos códigos, podéis
quitar las partes relativas a su definición y uso.
CONVERSIÓN CON LA CLASE
STRING
La primera opción que vamos a ver es emplear la clase String, que como sabemos es un
wrapper alrededor de un char array dinámico que se incluye en las librerías de Arduino.
La clase string dispone de las funciones toInt() y toFloat() que convierten, respectivamente,
la cadena de texto a un número entero o flotante.
5 void setup()
6 {
7 Serial.begin(9600);
8
9 long value;
10 value = text.toInt();
11 DEBUG(value);
12 }
13
14 void loop()
15 {
16 }
4
5 void setup()
6 {
7 Serial.begin(9600);
8
9 float value;
10 value = text.toFloat();
11 DEBUG(value);
12 }
13
14 void loop()
15 {
16 }
Aunque en la mayoría de los casos esto no supone ningún problema, en caso de tener que
lidiar con estas situaciones puede que prefiramos realizar la conversión “a mano” (ver más abajo
metodo Naive)
7 Serial.begin(9600);
8
9 long value;
10 value = atol(text);
11 DEBUG(value);
12 }
13
14 void loop()
15 {
16 }
4
5 void setup()
6 {
7 Serial.begin(9600);
8
9 long value;
10 value = atof(text);
11 DEBUG(value);
12 }
13
14 void loop()
15 {
16 }
En este caso, tenemos la desventaja de tener que trabajar con char array que, salvo en ciertos
casos muy concretos, normalmente será más engorroso que emplear la clase String.
Por tanto, salvo en contadas excepciones, lo normal es que prefiramos las funciones
anteriormente vistas en la clas String.
10 DEBUG(value);
11 }
12
13 void loop()
14 {
15 }
16
17 long naiveToInt(const char *charArray) {
18 long data = 0;
19 bool isNegative = false;
20 if (*charArray == '-')
21 {
22 isNegative = true;
23 ++charArray;
24 }
25
26 while (*charArray >= '0' && *charArray <= '9')
27 {
28 data = (data * 10) + (*charArray - '0');
29 ++charArray;
30 }
31
32 return isNegative ? -data : data;
33 }
El caso para un número en coma flotante es algo más complicado ya que, además de detectar
el símbolo negativo, debemos detectar el separador decimal (en el ejemplo ‘.’ o ‘,’). De esta forma
la conversión se realiza en dos etapas, una primera de la parte entera antes detectar el separador,
y una segunda para la parte entera tras la detección del separador.
1 #define DEBUG(a) Serial.println(a);
2
3 char *text = "-123.45";
4
5 void setup() {
6 Serial.begin(9600);
7
8 float value;
9 value = naiveToFloat(text);
10 DEBUG(value);
11 }
12
13 void loop()
14 {
15 }
16
17 float naiveToFloat(const char *charArray)
18 {
19 long dataReal = 0;
20 long dataDecimal = 0;
21 long dataPow = 1;
22 bool isNegative = false;
23
24 if (*charArray == '-')
25 {
26 isNegative = true;
27 ++charArray;
28 }
29
30 while ((*charArray >= '0' && *charArray <= '9'))
31 {
32 dataReal = (dataReal * 10) + (*charArray - '0');
33 ++charArray;
34 }
35
40 {
41 dataDecimal = (dataDecimal * 10) + (*charArray - '0');
42 dataPow *= 10;
43 ++charArray;
44 }
45 }
46
47 float data = (float)dataReal + (float)dataDecimal / dataPow;
El rendimiento del proceso es similar a la función atol y atof y, por extensión, a las funciones
de las clases String. Esto es debido a que esta implementación es similar a la empleada
internamente por las funciones atol y atof.
La mayor desventaja es, lógicamente, tener que añadir el código en lugar de emplearlo
cómodamente a partir de funciones existentes. No obstante, la sencillez de uso es similar.
Sin embargo en este caso tenemos la ventaja de controlar por completo el proceso. Como
muestra, en el ejemplo hemos hecho que se admita ‘.’ y ‘,’ como separador decimal, algo que no
podemos hacer con los procesos estándar.
Con sencillez podemos modificar el código para tener otro tipo de comportamiento, como
reaccionar de forma diferente a ciertos caracteres, procesar un archivo separado por comas, etc.