Buscando por internet no encontré mucho acerca de como separar datos numéricos de un string. Por ello, he decidido publicar esta entrada, con el objetivo de aportar un poco más acerca de este tema.
A la hora de realizar proyectos en los que es necesario enviar o recibir datos, los strings son muy útiles, ya que podemos enviar varios datos seguidos de una manera muy sencilla. Para enviar un string en CCS a través de RS232, podemos utilizar la función printf(). Utilizando los formatos, podemos enviar los datos a través del string según sea necesario. Ej:
[...]
#use rs232(.....)
[...]
int8 var=234;
[...]
printf("Dato: %u\0",var);
[...]
Con este código, se enviará un string con terminación NULL de la siguiente manera: Dato: 234.
Los formatos principales para printf() son los siguientes:
%c caracter
%u entero sin signo
%d entero con signo
%lu entero largo sin signo
%ld entero largo con signo
%x hexadecimal
%lx hexadecimal largo
%f flotante con decimal truncado
%g flotante con decimal redondeado
%e flotante en notación científica
[...]
#use rs232(.....)
[...]
int8 var=234;
[...]
printf("Dato: %u\0",var);
[...]
Con este código, se enviará un string con terminación NULL de la siguiente manera: Dato: 234.
Los formatos principales para printf() son los siguientes:
%c caracter
%u entero sin signo
%d entero con signo
%lu entero largo sin signo
%ld entero largo con signo
%x hexadecimal
%lx hexadecimal largo
%f flotante con decimal truncado
%g flotante con decimal redondeado
%e flotante en notación científica
Pero... ¿Y para recibir un string y saber interpretarlo? Pues bien, utilizaremos una función para recoger el string y guardarlo en un array para posteriormente extraer el dato que nos interese.
Para poder guardar un string en un array, es necesario que el array tenga al menos una posición libre para guardar el carácter NULL, es decir, si la cadena tiene una longitud de 6 caracteres, será necesario guardarla en un array que tenga 7 posiciones. Para recoger el string del RS232 en un array, utilizaremos la función gets(). Veamos el siguiente ejemplo:
<String enviado: "Hola Mundo">
[...]
#use rs232(.....)
[...]
char arraystr[11];
[...]
gets(arraystr);
[...]
Como se puede observar, la cadena de texto "Hola Mundo" está formada por 10 caracteres: las cuatro letras de "Hola", el espacio y las cinco letras de "Mundo". Por este motivo tenemos que definir un array con 11 posiciones, con el objetivo de que quede una libre para el carácter NULL.
Una vez hemos guardado el string en el array, ya podemos manejarlo de manera sencilla. Al referirnos a la posición 0 del array, éste nos devolverá una 'H'; al referirnos a la posición 1, nos devolverá una 'o'; posición 2, 'l'; etc. Pero a nosotros nos interesa extraer un dato numérico, por lo tanto aplicaremos un algoritmo para realizar esta acción.
Tomaremos el siguiente string, del cual vamos a extraer el número 468 y guardarlo en una variable definida como int16 (entero de 16 bits)
<String enviado: "Dato: 468">
[...]
#use rs232(.....)
[...]
int8 i,cen,dec,und;
int16 dato;
const char tablaascii[10]={'0','1','2','3','4','5','6','7','8','9'};
char strdata[10];
[...]
gets(strdata);
for(i=0;i<10;i++){
if(strdata[6]==tablaascii[i]) cen=i;
if(strdata[7]==tablaascii[i]) dec=i;
if(strdata[8]==tablaascii[i]) und=i;
}
dato=(cen*100)+(dec*10)+und;
[...]
El algoritmo guarda en tres variables las cifras de las centenas, decenas y unidades del número, utilizando un bucle for(). Al referirnos a la posición 6 del array strdata, nos devolverá un '4', pero ojo, esto no es número, se trata de un carácter; por ello lo compararemos con el otro array tablaascii, el cual nos devuelve el carácter numérico de la posición que le especifiquemos; utilizamos para ello unos condicionales if(). De esta manera, si se igualan el carácter de la posición 6 del array strdata con la posición 4 del array tablaascii, se guardará en la variable cen la posición a la que se ha referido, es decir, la posición 4; quedando guardado como dato numérico.
Igualmente se hace con las decenas y las unidades; i toma todos los valores entre 0 y 9, definiendo así las cifras de las unidades, decenas y centenas.
Finalmente se unen las tres cifras en un único número de 16 bits: dato=(cen*100)+(dec*10)+und;
Este algoritmo puede utilizarse para extraer varios datos numéricos que enviemos a través de un string sean de la longitud que sean.
Para poder guardar un string en un array, es necesario que el array tenga al menos una posición libre para guardar el carácter NULL, es decir, si la cadena tiene una longitud de 6 caracteres, será necesario guardarla en un array que tenga 7 posiciones. Para recoger el string del RS232 en un array, utilizaremos la función gets(). Veamos el siguiente ejemplo:
<String enviado: "Hola Mundo">
[...]
#use rs232(.....)
[...]
char arraystr[11];
[...]
gets(arraystr);
[...]
Como se puede observar, la cadena de texto "Hola Mundo" está formada por 10 caracteres: las cuatro letras de "Hola", el espacio y las cinco letras de "Mundo". Por este motivo tenemos que definir un array con 11 posiciones, con el objetivo de que quede una libre para el carácter NULL.
Una vez hemos guardado el string en el array, ya podemos manejarlo de manera sencilla. Al referirnos a la posición 0 del array, éste nos devolverá una 'H'; al referirnos a la posición 1, nos devolverá una 'o'; posición 2, 'l'; etc. Pero a nosotros nos interesa extraer un dato numérico, por lo tanto aplicaremos un algoritmo para realizar esta acción.
Tomaremos el siguiente string, del cual vamos a extraer el número 468 y guardarlo en una variable definida como int16 (entero de 16 bits)
<String enviado: "Dato: 468">
[...]
#use rs232(.....)
[...]
int8 i,cen,dec,und;
int16 dato;
const char tablaascii[10]={'0','1','2','3','4','5','6','7','8','9'};
char strdata[10];
[...]
gets(strdata);
for(i=0;i<10;i++){
if(strdata[6]==tablaascii[i]) cen=i;
if(strdata[7]==tablaascii[i]) dec=i;
if(strdata[8]==tablaascii[i]) und=i;
}
dato=(cen*100)+(dec*10)+und;
[...]
El algoritmo guarda en tres variables las cifras de las centenas, decenas y unidades del número, utilizando un bucle for(). Al referirnos a la posición 6 del array strdata, nos devolverá un '4', pero ojo, esto no es número, se trata de un carácter; por ello lo compararemos con el otro array tablaascii, el cual nos devuelve el carácter numérico de la posición que le especifiquemos; utilizamos para ello unos condicionales if(). De esta manera, si se igualan el carácter de la posición 6 del array strdata con la posición 4 del array tablaascii, se guardará en la variable cen la posición a la que se ha referido, es decir, la posición 4; quedando guardado como dato numérico.
Igualmente se hace con las decenas y las unidades; i toma todos los valores entre 0 y 9, definiendo así las cifras de las unidades, decenas y centenas.
Finalmente se unen las tres cifras en un único número de 16 bits: dato=(cen*100)+(dec*10)+und;
Este algoritmo puede utilizarse para extraer varios datos numéricos que enviemos a través de un string sean de la longitud que sean.