En estos momentos ya sabremos hacer un montón de cosas con nuestras aplicaciones. Mandar un texto, mandar un número, definir instrucciones con un conjunto de datos. En fin, se podría decir que estamos empezando a crear un protocolo de comunicaciones personalizado.
En el post anterior nos quedamos con la forma de enviar datos desde nuestro robot a nuestras aplicaciones por Bluetooth. Ahora vamos a extender este apartado enviando datos a nuestroo robot, pero atendiendo a un caso muy especial.
Vamos a crear un lienzo en nuestra aplicación con App Inventor, y si ya hemos hecho algo con este componente, ya conoceremos que cada vez que apretamos encima del lienzo, la pulsación sobre la pantalla, está definida mediante dos números coordenados en la dirección X horizontal y en la dirección Y vertical.
Por lo que ahora en lugar de enviar un solo número, enviaremos dos de vez… Pero para no juntarlos, los vamos a separar con un carácter o símbolo… Podemos elegir el caracter que queramos, pero aquí vamos a utilizar la barra vertical “|“.
Es decir que cada vez que presionemos sobre el liezo se nos enviará un código definido con X##|Y##.
La manera de programar nuestra placa, será de la siguiente forma, en la que primero capturamos el primer entero a leer, eliminamos de la cadena hasta la posición del caracter que hemos utilizado como separador; hay que fijarse de que hay que sumar una unidad a la posición para que incluya ese carácter en el borrado; y después leemos el segundo caracter.
También hemos añadido una variable “tick” para identificar cuánto tiempo le cuesta a nuestro programa desarrollar el desglose de los datos, guardando el tiempo actual en la variable y haciendo la resta para que nos aparezca en pantalla.
¿Qué es lo que ocurre?
Pues tal y como aparece en la imagen, si le damos una sola vez, el programa nos funciona a la perfección… Pero qué ocurre si le damos muchas veces seguidas, acción muy común a la hora de jugar con el móvil… Pues ocurre que se juntan todos los mensajes en uno, y al unirse, los números que terminan de un primer mensaje se juntan con el primer número del siguiente mensaje. Por lo que tenemos un bonito bug.
Para solucionar este problema, lo que debemos hacer es identificar de alguna manera cuándo empieza y cuando termina cada uno de los mensajes. Así que para ello, vamos a iniciar cada mensaje de información con un caracter “<“ y terminaremos con un caracter de cierre “>”
Ante esta nueva caracteristica tendremos que modificar nuestro código de nuestra placa, para atender cada mensaje por separado. Y para ello, vamos a realizar una lectura en bucle, eliminando datos de nuestra cadena de texto, hasta que su longitud llegue a cero. Esto lo conseguiremos con un bucle repeat while.
- Eliminar el primer carácter “<“
- Leer el primer número del mensaje y almacenarlo en la variable X.
- Eliminar la cadena de texto hasta el primer delimitador “|“
- Leer el segundo número y almacenarlo en la variable Y.
- Eliminar lo que nos queda de cadena hasta encontrar el caracter “>“
- Repetir hasta que no queden datos en la cadena por leer.
En este momento ahora podremos ver que nuestro programa es capaz de desglosar todos los datos diferenciándolos por partes y así podremos evitar que nos ocurra el incidente anterior.
También podremos observar que el tiempo que tarda en realizar este proceso aumenta en 2 segundo… En realidad no es tanto si consideramos que estamos escribiendo texto por el monitor serie… Pero si le damos muchas veces será evidente que el tiempo que nuestra placa se queda pensando puede alcanzar un bloqueo y no atender a otros eventos. Por ahora no es preocupante.
#include <SoftwareSerial.h>; String BT_data; boolean estado_anterior; int tick; int X; int Y; SoftwareSerial comm(2,3); void setup() { Serial.begin(9600); comm.begin(9600); pinMode(10, INPUT); BT_data = (String)(""); estado_anterior = (boolean)(false); tick = (int)(0); X = (int)(0); Y = (int)(0); } void loop() { if (comm.available()) { tick = millis(); BT_data = (comm.readString()); Serial.println(BT_data); while (String(BT_data).length() > 0) { if (BT_data.startsWith("<")) { BT_data.remove(0,1); X = (BT_data.toInt()); Serial.println(X); BT_data.remove(0,((BT_data.indexOf("|")) + 1)); Y = (BT_data.toInt()); Serial.println(Y); BT_data.remove(0,((BT_data.indexOf(">")) + 1)); Serial.println(BT_data); } } Serial.print("Time: "); Serial.println((millis() - tick)); } if(digitalRead(2) != estado_anterior){ estado_anterior = digitalRead(2); if (estado_anterior == true) { comm.println("ON"); } else { comm.println("OFF"); } } }
One comment