Para continuar la exploración de la tecnología BLE que comenzó nuestra compañera Rebeca Rodriguez Tencio acá, les presentamos este primer tutorial de dos relacionados. La idea es poder implementar una forma de enviar comandos a una tarjeta de prototipado via Bluetooth Low Energy (BLE) desde una App de un teléfono Móvil.
En esta primera parte implementaremos un servicio «Comando LED» en un microcontrolador compatible con Arduino 101 llamado TinyTILE (basado en el chip Curie de Intel)
En la segunda parte, implementaremos una App (Android y IOS) usando IONIC 3 que le envía comandos al micro-controlador mediante el sistema BLE del teléfono.
(!) Antes de seguir estas instrucciones asegúrese de entender las Condiciones de Uso de nuestro sitio.
Primero: Programemos el Curie
En resumen:
- Necesitaremos un protoboard, un LED, una resistencia de 150 Ohm, un TinyTILE y un cable USB a micro-USB y una PC
- El circuito es muy sencillo:
- En la PC instalamos los controladores de placa «Arduino/Genuino 101» en el IDE de ARDUINO (V.1.8.2)
- Menu: Tools > Board > Board Manager > Search «Curie» > Instalar V 2.0.2 o superior.
- Descargamos el programa (sketch) de ejemplo de mi repositorio de Github y lo abrimos con el IDE de ARDUINO.
- Instalamos el boceto de ejemplo en la placa
- Menu: Sketch > Upload
- Usamos una app para pruebas BLE denominada «BLE Scanner» para enviar comandos «ON» y «OFF»
- Nótese que hemos implementado una función «parpadear» que nos permite ver si el sketch arrancó adecuadamente.
Las siguientes imágenes ilustran el uso de BLE Scanner para enviar los comandos.
Seguidamente mostramos el código original del programa con los comentarios detallados sobre su funcionamiento. Es realmente sencillo; podemos resumirlo en:
- Definir un servicio BLE «ServicioBLE_Comando» (línea 5)
- Deinir una característica BLE «CaracteristiciaBLE_Comando» de tipo genérica, de lectura y escritura con mensajes de 20 bytes (línea 8)
- Darle un nombre al dispositivo «COMANDO LED» e inicializarlo, agregando el servicio y la característica (línea 19)
- Publicitamos el servicio (línea 23)
- Leemos eventos BLE en la característica (nuevos comandos) que luego son interpretados y ejecutados (líneas 31,33,57,61)
- Para esto convertimos el valor recibido a un String (línea 63)
#include <CurieBLE.h>
#define ledPin 13
//Definimos un servicio BLE
BLEService servicioBLE_Comandos("db938b80-f010-44b6-8aa9-1835adf9419a"); // create service
//Definimos una característica que pueda ser leida o escrita desde una central BLE, con capacidad de 20 bytes por mensaje.
BLECharacteristic caracteristicaBLE_Comandos("9906064e-9bbe-4eba-b415-bbd223f7d3d9", BLERead | BLEWrite, 20);
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
delay(500); //Esperamos un poco de tiempo (500ms) por si se puede habilitar la terminal serial.
parpadear(5,200);//Señalizamos con el LED que estamos iniciando el sketch
BLE.begin(); //Inicializamos el sistema Bluetooth Low Energy (BLE) del Curie
parpadear(2 ,100);//Señal de aviso de que la operación anterior fue exitosa
BLE.setLocalName("COMANDO LED"); //Definimos un nombre para publicitar nuestro dispositivo
BLE.setAdvertisedService(servicioBLE_Comandos);//Definimos el servicio que se va a publicitar
servicioBLE_Comandos.addCharacteristic(caracteristicaBLE_Comandos); //Agregamos la característica al servicio
BLE.addService(servicioBLE_Comandos); //Agregamos el servicio al dispositivo
BLE.advertise(); // Publicitamos el dispositivo
parpadear(3 ,100);//Señal de aviso de que la operación anterior fue exitosa
Serial.println("En este punto el dispositivo queda listo, publicitado y esperando conexiones...");
parpadear(10,50);//Señal de aviso de que SETUP se concluyó satisfactoriamente
}
void loop() {
BLE.poll(); // Obtenemos cualquier evento BLE que haya sido enviado al dispositivo
if (caracteristicaBLE_Comandos.written()) { //Si hay datos, ejecutamos el comando
leerYEjecutarComado();
} // ... caso contrario simplemente se termina el flujo de loop()
}
/**
* Este método lee el comando registrado en la característica BLE y lo ejecuta.
*/
void leerYEjecutarComado(){
String valorDelComando = obtenerValorDelComando();
if (valorDelComando.startsWith("ON")) {
Serial.println("LED on");
digitalWrite(ledPin, HIGH);
} else {
Serial.println("LED off");
digitalWrite(ledPin, LOW);
}
}
/**
* Extraer el valor del comando en formato String
*/
String obtenerValorDelComando(){
int longitudDelComando = caracteristicaBLE_Comandos.valueLength();
Serial.print("Longitud: ");
Serial.println(longitudDelComando);
const byte* val = caracteristicaBLE_Comandos.value();
String strValor = String((const char *)val).substring(0, longitudDelComando);
Serial.println("|" + strValor + "|");
return strValor;
}
void parpadear(int times, int milliseconds){
for(int i=0; i<times; i++){
digitalWrite(ledPin, HIGH);
delay(milliseconds);
digitalWrite(ledPin, LOW);
delay(milliseconds);
}
}
7,978 total views, 3 views today
Comentarios