|     Inicio    |   |         |  |   FOROS      |  |      |      
   Elastix - VoIP B4A (Basic4Android) App inventor 2 PHP - MySQL
  Estación meteorológica B4J (Basic4Java) ADB Shell - Android Arduino
  Raspberry Pi Visual Basic Script (VBS) FireBase (BD autoactualizable) NodeMCU como Arduino
  AutoIt (Programación) Visual Basic Cosas de Windows Webs interesantes
Translate:
Búsqueda en este sitio:


.

Tutorial del Internet de las Cosas y Bluetooth con el HM10
Juan Antonio Villalpando

Volver al índice del tutorial

____________________________

161.- HM-10. BLE. Arduino UNO. MLT-BT05.

- Vamos a realizar varios ejemplos con este módulo HM-10, es un BLE, un Bluetooth de baja energía.

- Este tutorial continua en: 161_HM10_BLE_Actualizar.htm

- Utilizaremos la Extensión BluetoothLE.

- En esta página podemos encontrar una extensión para que App Inventor pueda trabajar con BLE:

- http://iot.appinventor.mit.edu/#/bluetoothle/bluetoothleintro

BLE-with-new-ConnectDevice.aix (2019-06-27)

- Otra cosa importante es que cada vez que hagamos cambios en los códigos Deshabilitemos y Habilitemos el Bluetooth del móvil, para eso he puesto la extensión KIO4_Bluetooth.aix en estos ejemplos.

com.KIO4_Bluetooth.aix

- http://ai2.appinventor.mit.edu/reference/other/IoT.html

- Para que funcione BLE, el móvil debe tener activado el permiso de Ubicación (Location)
https://stackoverflow.com/questions/33045581/location-needs-to-be-enabled-for-bluetooth-low-energy-scanning-on-android-6-0

https://stackoverflow.com/questions/33043582/bluetooth-low-energy-startscan-on-android-6-0-does-not-find-devices/33045489#33045489

- Más información sobre el HM-10:
http://acoptex.com/project/302/basics-project-028d-bluetooth-40-hm-10-ble-module-at-acoptexcom/#sthash.vFzAsJm0.dpbs

- El bloque de solicitud de permisos.

- Si instalamos una vieja versión de esta la extensión BLE y más tarde instalamos una nueva en la misma aplicación, puede ocurrir que se mantengan las dos extensiones, y cuando volvamos a abrir la aplicación los bloque salgan de forma atenuada como indico en la imagen:

- Para solucionarlo debemos exportar nuestra aplicación, abrirla con un compresor de archivos, como en Winrar, y Eliminar el com.google.appinventor.components.runtime.BluetoothLE y volver a cargar esta aplicación.

- La librería <CurieBLE> funciona con Arduino 101, así que no la vamos a utilizar, ya que trabajaremos con Arduino UNO.

- La librería <ArduinoBLE>, tampoco me ha funcionado en Arduino UNO, funciona en Arduino MKR WiFi 1010, Arduino UNO WiFi Rev .2, Arduino Nano 33 IoT, y Arduino Nano 33 BLE.

- También probé la librería <BLEPeripheral>, tampoco me funcionó, es para Arduino Nano BLE y chips nRF8001, nRF51822.

_________________________________
1.- Módulo. Conexiones.

- Aunque este módulo se vende como HM-10, es realidad es un BT05, es un clon, de tal manera que algunas de sus propiedades son distintas al original HM-10.

- El HM-10 genuino tiene un cristal en la parte superior-izquierda.

- https://blog.yavilevich.com/2017/03/mlt-bt05-ble-module-a-clone-of-a-clone/

- https://blog.yavilevich.com/2018/04/should-you-throw-away-your-cc41-hm-10-clones-now-that-android-8-is-here/

- https://circuitdigest.com/microcontroller-projects/how-to-flash-the-firmware-on-cloned-hm-10-ble-module-using-arduino-uno

- Aunque esto es un módulo BLE, Bluetooth de Baja Energía, para que trabaje como tal debería trabajar en SLEEP es decir en modo dormido, cuando ocurra un evento, despertar, notificar la información y volver a dormir. Otra característica con la que debería trabajar es en Stan-Alone, es decir trabajar en solitario, sin estar conectado al Arduino.

- En este tutorial trabajará siempre despierto y conectado al Arduino UNO.

 

MLT-BT05
Servicios: UUID central y periférico FFE0, FFE1

CC2541

- Lo podríamos alimentar mediante el terminal 3.3 V de Arduino, pero lo vamos a alimentar a 5 V.

- En caso que lo alimentemos con esos 5 V, debemos poner un división de tensión en RXD ya que debemos rebajar los 5 V que tendremos en el terminal TX de Arduino a 3,3 V, como se observa en la imagen, que es lo que admite la entrada RXD.

- El terminal de salida TXD lo podemos conectar directamente al RX de Arduino, ya que aunque salgan 3,3 V la entrada RX de Arduino puede reconocer ese nivel de tensión.

- También podríamos haber conectado el módulo a los terminales 0-RX y 1-TX de Arduino, pero en este caso he preferido utilizar otros terminales (aunque esto conlleva la utilización de la librería SoftwareSerial)

 

_________________________________
2.- Obtención de UUID Service y UUID Characteristic.

- Los BLE funcionan de forma distinta a los Bluetooth clásicos. Necesitan unos identificadores denominados UUID.

- Vamos a ver los identificadores de nuestro módulo, para ello bajamos de la Play de Google e instalamos en nuestro móvil la aplicación nRF Connect.

- Conectamos el HM-10 al Arduino. No hace falta vincular los Bluetooth BLE.

- Vamos a esta app, pulsamos Scan y obtendremos el nombre del dispositivo, en mi caso MLT-BT05

- Pulsamos sobre él, vamos a CLIENT y observamos los UUID Servicio y Characteristic.

Servicio: 0000ffe0-0000-1000-8000-00805f9b34fb

Characteristic: 0000ffe1-0000-1000-8000-00805f9b34fb

- Observa las Propiedades: NOTIFY, READ, WRITE. También observamos "WRITE NO RES..." esto significa que la Propiedad WriteWithResponse no está activada, así que no funcionará el bloque de la extensión "WriteWithResponse".

- "WRITE NO RESPONSE", envía la respuesta mediante Notificación, es decir mediante RegisterForStrings.

_________________________________
3.- El HM-10. Obtención de final de mensaje. App Inventor envía información.

- Vamos a obtener el caracter fin de mensaje.

- Para ello instalamos esta app en App Inventor.

p110_UNO_HM10_ble_enviar.aia

_________________________________
- Diseño.

- Vamos a enviar: abcdefghijk

_________________________________
- Bloques.

_________________________________
- Arduino UNO.

envia_BLE_LED13.ino

// Juan A. Villalpando
// http://kio4.com/arduino/161_HM10_BLE.htm

#include <SoftwareSerial.h>
// El TXD del módulo al pin 2 (RX) del Arduino.
// El RXD del módulo al pin 3 (TX) del Arduino.
SoftwareSerial HM10(2, 3);

#define LED13  13
byte caracter = "";  
// char caracter = "";  
String mensaje = "";

void setup(){
  Serial.begin(9600);
  HM10.begin(9600);
  pinMode(LED13, OUTPUT);
}

void loop(){
  if(HM10.available()) { 
  caracter = HM10.read();
  Serial.println(caracter);
  mensaje = mensaje + caracter;

  if(caracter == NULL ) { 
     Serial.println(mensaje); 
     if (mensaje.indexOf("on13")>= 0){digitalWrite(LED13, HIGH);}
     if (mensaje.indexOf("off13")>= 0){digitalWrite(LED13, LOW);}   
     mensaje = "";
     delay(100);
     }
  } 
}

- Observa que hemos puesto los caracter como byte

byte caracter = "";
// char caracter = "";

- Obtendremos el código ASCII de cada caracter.

- Además obtendremos el código 0, correspondiente al caracter NULL, esto indica fin de mensaje, es decir la extensión Bluetooth envía un fin de mensaje mediante el caracter NULL.

- Ahora vamos a establecer caracter como char, cambia esta línea de esta forma:

// byte caracter = "";
char caracter = "";

- Observaremos que obtenemos los caracteres y al final el 0 correspondiente al NULL, que no es visible.

- Esto ocurre porque la extensión BluetoothLE envía por defecto un caracter NULL cada vez que envía un mensaje de cadena WriteString(con bytes no lo añade).

- Si no quisiéramos que enviara un caracter NULL cada vez que envía un mensajes, deberíamos asignar un falso al siguiente bloque:

NullTerminateStrings = falso

_________________________________
4.- MTU = 20.

- BLE maneja envía los mensajes en paquetes de 20 bytes, es decir 19 caracteres + NULL, si intentas enviar más caracteres en el mismo mensaje, no se mostrarán.

- Envía este mensaje: 1234567890123456789012345

- Observarás que no se muestra en el Monitor Serie.

- A continuación envia este: abcde

- Observarás que se muestra el mensaje anterior y el nuevo.

- Así que, en principio, no hacemos la idea de que podemos enviar mensajes de 19 caracteres (ya que la extensión agrega el NULL).

- En la Extensión BLE hay un bloque para cambiar la cantidad de bytes MTU que se pueden enviar en un mensaje, pero eso depende también del receptor, por el momento nos quedamos con mensajes de 19 bytes

_________________________________
5.- Encender/Apagar el LED13.

- Continuamos con la misma aplicación de App Inventor y el mismo código de Arduino con char caracter = "";

- Vamos a escribir on13 y off13, observaremos que se enciende y apaga el LED13.

- La variable menaje va acumulando los caracteres que van llegando, cuando llega el caracter NULL, realiza el código existente en el interior del if.

- menaje.indexOf("on13") >= 0, comprueba si el mensaje contiene la cadena "on13".

_________________________________
6.- Encender/Apagar el LED13 y LED12 mediante el mismo mensaje.

- Si quisiéramos encender o apagar el LED12 y el LED13 en el mismo mensaje, escribiríamos...

on13 off12

- Podemos escribirlo al revés: off12 on13 y también separado por coma: on13,off12

- Previamente modificaríamos el código del Arduino.

- Se apagará/encenderá los LED13 y LED12 según el texto enviado contenga: on13 off13 on12 off12

 
	  if (mensaje.indexOf("on13")>= 0){digitalWrite(LED13, HIGH);} 
	  if (mensaje.indexOf("off13")>= 0){digitalWrite(LED13, LOW);}
	  if (mensaje.indexOf("on12")>= 0){digitalWrite(LED12, HIGH);} 
	  if (mensaje.indexOf("off12")>= 0){digitalWrite(LED12, LOW);}
envia_BLE_mismo_tiempo.ino

// Juan A. Villalpando
// http://kio4.com/arduino/161_HM10_BLE.htm

#include <SoftwareSerial.h>
// El TXD del módulo al pin 2 (RX) del Arduino.
// El RXD del módulo al pin 3 (TX) del Arduino.
SoftwareSerial HM10(2, 3);

#define LED13  13
byte caracter = "";  
// char caracter = "";  
String mensaje = "";

void setup(){
  Serial.begin(9600);
  HM10.begin(9600);
  pinMode(LED13, OUTPUT);
}

void loop(){
  if(HM10.available()) { 
  caracter = HM10.read();
  Serial.println(caracter);
  mensaje = mensaje + caracter;

  if(caracter == NULL ) { 
     Serial.println(mensaje); 
	  if (mensaje.indexOf("on13")>= 0){digitalWrite(LED13, HIGH);} 
	  if (mensaje.indexOf("off13")>= 0){digitalWrite(LED13, LOW);}
	  if (mensaje.indexOf("on12")>= 0){digitalWrite(LED12, HIGH);} 
	  if (mensaje.indexOf("off12")>= 0){digitalWrite(LED12, LOW);} 
     mensaje = "";
     delay(100);
     }
  } 
}

- Siempre deberíamos tener cuidado de que el mensaje sea menos de 20 bytes.

_________________________________
7.- Enviamos un número desde la Aplicación al Arduino y éste nos devuelve el doble y el triple.

p110_UNO_HM10_ble_enviar_recibe.aia

- Enviamos por Bluetooth al Arduino + HM10 un número entero. Arduino nos devuelve el doble y el triple de ese número.

- Utilizaremos el Bloque RegisterFromStrings.

- Utilizamos el bloque WriteStrings.

_________________________________
- Diseño.

_________________________________
- Bloques.

_________________________________
- Arduino UNO.

envia_BLE_recibe.ino

// Juan A. Villalpando
// http://kio4.com/arduino/161_HM10_BLE.htm

#include <SoftwareSerial.h>
// El TXD del módulo al pin 2 (RX) del Arduino.
// El RXD del módulo al pin 3 (TX) del Arduino.
SoftwareSerial HM10(2, 3);

#define LED13  13
// byte caracter = "";  
char caracter = "";  
String mensaje = "";
int doble;
int triple;

void setup(){
  Serial.begin(9600);
  HM10.begin(9600);
  pinMode(LED13, OUTPUT);
}

void loop(){
  if(HM10.available()) { 
  caracter = HM10.read();
  mensaje = mensaje + caracter;
 
  if(caracter == NULL ) { 
     Serial.println(mensaje); 
     doble = 2 * mensaje.toInt();
     triple = 3 * mensaje.toInt();
     Serial.println(doble); 
     String mensaje = (String) doble + "," + (String) triple;
     HM10.write(mensaje.c_str()); 
     mensaje = "";
     delay(100);
     }
  } 
}			

- El código anterior a veces falla, este parece que funciona mejor...

envia_BLE_recibe.ino

// Juan A. Villalpando
// http://kio4.com/arduino/161_HM10_BLE.htm

#include <SoftwareSerial.h>
// El TXD del módulo al pin 2 (RX) del Arduino.
// El RXD del módulo al pin 3 (TX) del Arduino.
SoftwareSerial HM10(2, 3);

#define LED13  13
// byte caracter = "";  
char caracter = "";  
String mensaje = "";
int doble;
int triple;

void setup(){
  Serial.begin(9600);
  HM10.begin(9600);
  pinMode(LED13, OUTPUT);
}

void loop(){
  if(HM10.available()) { 
  caracter = HM10.read();
  mensaje = mensaje + (String) caracter;
  
  if(caracter == NULL) { 
     Serial.println(mensaje); 
     doble = 2 * mensaje.toInt();
     triple = 3 * mensaje.toInt();
     Serial.println(doble);
     mensaje = ""; 
     delay(100);
     String mensaje_hm10 = (String) doble + "," + (String) triple;
     HM10.print(mensaje_hm10.c_str()); 
     }
  } 
}      	

_________________________________
8.- En la Aplicación obtenemos temperatura y humedad automáticamente.

p110_UNO_HM10_ble_temperatura.aia

- Registramos String mediante el bloque RegisterForStrings, de manera que recibiremos automáticamente valores del Arduino cuando éstos cambien.

- En este ejemplo los valores cambiarán aleatoriamente cada segundo.

- Obtendremos valores aleatorios de temperatura y humedad y los ajustaremos para presentarlos separadamente.

- En stringValues recibimos esta lista de un elemento: ["34,76"]

- Mediante seleccionar elemento 1 de la lista obtenemos: 34,76

- Mediante lista desde registros csv lo convertimos a lista de dos elementos: ["34","76"]

_________________________________
- Diseño.

_________________________________
- Bloques.

_________________________________
- Arduino UNO.

BLE_temperatura.ino

// Juan A. Villalpando
// http://kio4.com/arduino/161_HM10_BLE.htm

#include <SoftwareSerial.h>
// El TXD del módulo al pin 2 (RX) del Arduino.
// El RXD del módulo al pin 3 (TX) del Arduino.
SoftwareSerial HM10(2, 3);

String temperatura;
String humedad;

void setup(){
  Serial.begin(9600);
  HM10.begin(9600);
}

void loop(){
  temperatura = (String) random(18,42);
  humedad = (String) random(40,98);
  
  String mensaje = temperatura + "," + humedad;
  HM10.print(mensaje.c_str());

  delay(1000);
}

_________________________________
9A.- Consulta dos Pulsadores conectados al Arduino.

p110_UNO_HM10_ble_temperatura.aia (Es la misma aplicación que la del ejemplo anterior).

- Conectamos dos pulsadores en los terminales 7 y 8 del Arduino como muestra la imagen.

- Obtendremos el estado de los pulsadores, activados o no activados.

- Utilizaremos el bloque RegisterForStrings, para que el chequeo se realice automáticamente.


_________________________________
- Arduino UNO.

BLE_pulsadores.ino

// Juan A. Villalpando
// http://kio4.com/arduino/161_HM10_BLE.htm

#include <SoftwareSerial.h>
// El TXD del módulo al pin 2 (RX) del Arduino.
// El RXD del módulo al pin 3 (TX) del Arduino.
SoftwareSerial HM10(2, 3);

#define push7 7   // PushButton 7.
#define push8 8   // PushButton 8.
String status_push7;
String status_push8;
String status;

void setup(){
  Serial.begin(9600);
  HM10.begin(9600);
  pinMode(push7, INPUT);
  pinMode(push8, INPUT);
}

void loop(){
  if (digitalRead(push7) == HIGH) {status_push7 = "Push7 ON";} else {status_push7 = "Push7 OFF";}
  if (digitalRead(push8) == HIGH) {status_push8 = "Push8 ON";} else {status_push8 = "Push8 OFF";}
  status = status_push7 + "," + status_push8;
  HM10.print(status.c_str());

  delay(100);
}

_________________________________
9B.- Consulta un pulsador. En este caso solo envía información cuando cambia el estado del pulsador.

p110_HM10_ble_LED.aia

_________________________________
- Diseño.

_________________________________
- Bloques.

 

BLE_pulsador.ino

// Juan A. Villalpando
// http://kio4.com/arduino/161_HM10_BLE.htm

#include <SoftwareSerial.h>
// El TXD del módulo al pin 2 (RX) del Arduino.
// El RXD del módulo al pin 3 (TX) del Arduino.
SoftwareSerial BLE1(2, 3);

int valor = true;
int valor_anterior = false;

void setup(){
  Serial.begin(9600);
  BLE1.begin(9600);
  pinMode(7,INPUT);
}

void loop(){
  valor = digitalRead(7);
  if (valor == HIGH &&  valor_anterior != HIGH) { 
   Serial.println("Pulsado");
   valor_anterior = valor;
   BLE1.print("1");
   delay(10);
   } 
   if (valor == LOW && valor_anterior != LOW) { 
   Serial.println("NO");
   valor_anterior = valor;
   BLE1.print("0");
   delay(10);
   }   
}

 

_________________________________
10.- App envía tres valores mediante Deslizadores. Arduino HM-10 los recibe y devuelve una cadena con esos tres valores.

p110_HM10_ble_LED.aia

- Mediante Deslizadores enviamos tres números, por ejemplo: 40,84,119

- Arduino los recibe, los separa y los presenta en el Monitor Serie.

- Además vuelve a reenviarlo con este formato: R=40,V=84,A=119

- Recuerda que el tamaño de los paquetes de envío debe ser menos a 20 bytes.

_________________________________
- Diseño.

_________________________________
- Bloques.

_________________________________
- Arduino UNO.

BLE_tres_valores.ino

// Juan A. Villalpando
// http://kio4.com/arduino/161_HM10_BLE.htm

#include <SoftwareSerial.h>
// El TXD del módulo al pin 2 (RX) del Arduino.
// El RXD del módulo al pin 3 (TX) del Arduino.
SoftwareSerial HM10(2, 3);

char caracter = "";  
String mensaje = "";
String red;
String green;
String blue;
int ind1;
int ind2;
int ind3;

void setup(){
  Serial.begin(9600);
  HM10.begin(9600);
}

void loop(){
  if(HM10.available()) { 
  caracter = HM10.read();
  // Serial.println(caracter);
  mensaje = mensaje + caracter;

  if(caracter == NULL ) { 
      Serial.println(mensaje); 
        ind1 = mensaje.indexOf(',');
        red = mensaje.substring(0, ind1);
        ind2 = mensaje.indexOf(',', ind1+1 );
        green = mensaje.substring(ind1+1, ind2);
        ind3 = mensaje.indexOf(',', ind2+1 );
        blue = mensaje.substring(ind2+1);

        Serial.print("red = ");
        Serial.println(red);
        Serial.print("green = ");
        Serial.println(green);
        Serial.print("blue = ");
        Serial.println(blue);
        Serial.println();
        String retorno = "R=" + red + ",V=" + green + ",A=" + blue;
        HM10.print(retorno.c_str());
     mensaje = "";
     delay(50);
     }
  } 
}

_________________________________
11.- Encender/Apagar 3 LEDs. Obtener el estado de los tres LEDs.

p110_UNO_HM10_3LED.aia

- Conectamos tres LEDS al Arduino.

- Desde la App encendemos/apagamos los LEDs y podemos obtener sus estados.

_________________________________
- Diseño.

_________________________________
- Bloques.

- Para poder obtener retorno de información utilizamos el bloque RegisterForStrings.

_________________________________
- Arduino UNO.

- He puesto dos formas de comprobar la menaje enviada, mediante la igualdad == y mensaje.indexOf() >=0

- Recuerda que se deben enviar mensajes de menos de 20 bytes.

BLE_tres_LEDs.ino

// Juan A. Villalpando
// http://kio4.com/arduino/161_HM10_BLE.htm

#include <SoftwareSerial.h>
// El TXD del módulo al pin 2 (RX) del Arduino.
// El RXD del módulo al pin 3 (TX) del Arduino.
SoftwareSerial HM10(2, 3);

#define LED11  11
#define LED12  12
#define LED13  13

char caracter = "";  
String mensaje = "";
String estado = "";

void setup() {
  Serial.begin(9600);
  HM10.begin(9600);
  pinMode(LED11, OUTPUT);
  pinMode(LED12, OUTPUT);
  pinMode(LED13, OUTPUT);
}

void loop(){
  if(HM10.available()) { 
  caracter = HM10.read();
  // Serial.println(caracter);
  mensaje = mensaje + caracter;

  if(caracter == NULL ) { 
     Serial.println(mensaje); 
     if (mensaje == "on11") {digitalWrite(LED11,HIGH); estado = "LED11 ON";}
     if (mensaje == "off11"){digitalWrite(LED11,LOW); estado = "LED11 OFF";}
     if (mensaje == "on12") {digitalWrite(LED12,HIGH); estado = "LED12 ON";}
     if (mensaje == "off12"){digitalWrite(LED12,LOW); estado = "LED12 OFF";} 
     if (mensaje.indexOf("on13") >= 0){digitalWrite(LED13, HIGH); estado = "LED13 ON";}
     if (mensaje.indexOf("off13") >= 0){digitalWrite(LED13, LOW); estado = "LED13 OFF";}
     if (mensaje == "check"){
     estado ="";
     if (digitalRead(LED11) == HIGH) {estado = "on11,";} else {estado = "off11,";}
     if (digitalRead(LED12) == HIGH) {estado = estado + "on12,";} else {estado = estado + "off12,";}
     if (digitalRead(LED13) == HIGH) {estado = estado + "on13";} else {estado = estado + "off13";}
    }
     HM10.print(estado.c_str()); 
     mensaje = "";
     delay(100);
     }
  } 
}

_________________________________
12.- Arritmia. RegisterForStrings. Notify. Intervalo de emisión variable.

p110_UNO_HM10_corazon.aia

- En este ejemplo vamos a ver una simulación de corazón con arritmia, la aritmia en el corazón sucede cuando el intervalo de pulsación del corazón es muy variable. En realidad las pulsaciones del corazón nunca llevan en mismo ritmo, hay distintos intervalos entre pulsaciones. Si el intervalo de pulsación del corazón fuera constante, el sistema circulatorio colapsaría en pocos minutos y la persona o animal moriría.

- En la imagen de arriba observamos un ritmo normal de pulsación del corazón, aproximadamente de 75 pulsaciones por minuto. Se observa que entre una pulsación y otra hay distinto intervalo de tiempo, pero parecido, es lo normal.

- En la imagen de arriba observamos un corazón con aritmia. Se observa que entre una pulsación y otra el intervalo de tiempo es bastante diferente.

- Arduino generará números aleatorios con un nivel entre 90 y 100, esto será la altura de la señal.

- También generará números aleatorios entre 400 y 1600, esto será el ritmo de la señal, estos números se aplicarán a un delay, es decir crearemos un retardo variable según ese ritmo.

- Mediante Bluetooth esa pareja de números, por ejemplo 95,1257 se enviará a la Aplicación al ritmo indicado por el delay.

- La Aplicación funcionará con el bloque RegisterForStrings, de manera que no es necesario poner un Reloj para obtener la información enviada. Cada vez que cambia los valores de la variable mensaje.c_str(), la aplicación detecta ese cambio y lo recibe automáticamente.

- Nuestra aplicación también tendrá un Reloj, pero lo utilizaremos para dibujar la señal. No es necesario para recibir el mensaje.

_________________________________
- Diseño.

_________________________________
- Bloques.

_________________________________
- Arduino UNO.

BLE_aritmia.ino

// Juan A. Villalpando
// http://kio4.com/arduino/161_HM10_BLE.htm

#include <SoftwareSerial.h>
// El TXD del módulo al pin 2 (RX) del Arduino.
// El RXD del módulo al pin 3 (TX) del Arduino.
SoftwareSerial HM10(2, 3);

void setup(){
  Serial.begin(9600);
  HM10.begin(9600);
}

void loop(){
      String nivel = (String) random(90,100);
      int ritmo = random(400,1600);
      delay(ritmo);
      String mensaje = nivel + "," + (String) ritmo;
      Serial.println(mensaje);
      HM10.print(mensaje.c_str());
}

_________________________________
13.- Números flotantes, float.

p110_UNO_HM10_float.aia

- Enviamos un número desde la App al Arduino por Bluetooth. El Arduino realiza una operación matemática y devuelve un número float con 7 decimales. Este número float lo devuelve como String.

- La operación matemática que vamos a realizar es:

flotante = 7.101031f * mensaje.toFloat() / 3.303071f;

- No tiene ningún significado especial, solo es una operación para obtener un resultado con varios decimales.

- Observa que todos los factores son números flotantes.

- Aunque trabajamos con números con coma flotante, registramos mediante RegisterForStrings, ya que Bluetooth envía Strings.

_________________________________
- Diseño.

_________________________________
- Bloques.

_________________________________
- Arduino UNO.

BLE_float.ino

// Juan A. Villalpando
// http://kio4.com/arduino/161_HM10_BLE.htm

#include <SoftwareSerial.h>
// El TXD del módulo al pin 2 (RX) del Arduino.
// El RXD del módulo al pin 3 (TX) del Arduino.
SoftwareSerial HM10(2, 3);

char caracter = "";  
String mensaje = "";
float flotante = 1.0f;

void setup(){
  Serial.begin(9600);
  HM10.begin(9600);
  pinMode(LED13, OUTPUT);
}

void loop(){
  if(HM10.available()) { 
  caracter = HM10.read();
  mensaje = mensaje + caracter;
 
  if(caracter == NULL ) { 
     Serial.println(mensaje); 
     flotante = 7.101031f * mensaje.toFloat() / 3.303071f;
     Serial.println(flotante,7); // Muestra con 7 decimales.
     HM10.print(flotante,7); // Envía con 7 decimales.
     mensaje = "";
     delay(100);
     }
  } 
} 

______________________________
14.- Dos Bluetooth HM-10 envían temperatura y humedad a App Inventor.

p110_UNO_dos_HM10.aia

- Disponemos de dos Bluetooth HM-10 cada uno de ellos va a enviar los valores de temperatura y humedad. Estos serán números aleatorios.

- Podríamos conectar un HM-10 a un Arduino UNO y el otro HM-10 a otro Arduino UNO, pero vamos a hacerlo un poco más complicado...

- ...vamos a conectar los dos HM-10 al mismo Arduino UNO.

- Utilizaremos el bloque RegisterForStrings, cada vez que alguno de los dos genere un par de valores [temperatura,humedad] lo enviará automáticamente a al aplicación sin necesidad de utilizar Reloj.

- Además los intervalos de envío de datos será variable, para eso pondremos retardos con intervalos variables creados aleatoriamente.

_________________________________
- Diseño.

_________________________________
- Bloques.

_________________________________
- Arduino UNO.

Un_BLE.ino

// Juan A. Villalpando
// http://kio4.com/arduino/161_HM10_BLE.htm

#include <SoftwareSerial.h>
// El TXD del módulo al pin 2 (RX) del Arduino.
// El RXD del módulo al pin 3 (TX) del Arduino.
SoftwareSerial HM10(2, 3);

void setup(){
  Serial.begin(9600);
  HM10.begin(9600);
}

void loop(){
      float TemperatureBLE1 = random(10,60000) / 1000;
      String temperatureBLE1 = TemperatureBLE1.ToString();
	  
	  float HumidityBLE1 = random(5,99000) / 1000;
	  String humidityBLE1 = HumidityBLE1.ToString();

      int interval = random(400,1600);
      delay(interval);
      String mensaje = temperatureBLE1 + "," + humidityBLE1;
      Serial.println(mensaje);
      HM10.print(mensaje.c_str());
}

- Este es el código para que funcionen los dos módulos. En la parte de envío he utilizado dos métodos distintos.

Dos_BLE.ino

// Juan A. Villalpando
// http://kio4.com/arduino/161_HM10_BLE.htm

#include <SoftwareSerial.h>
// El TXD del módulo al pin 2 (RX) del Arduino.
// El RXD del módulo al pin 3 (TX) del Arduino.
SoftwareSerial BLE1(2, 3);
// El TXD del módulo al pin 4 (RX) del Arduino.
// El RXD del módulo al pin 5 (TX) del Arduino.
SoftwareSerial BLE2(4, 5);

long previousMillis_BLE1 = 0;
long previousMillis_BLE2 = 0;
int interval_BLE1 = 1000;
int interval_BLE2 = 1000;

void setup(){
  Serial.begin(9600);
  BLE1.begin(9600);
  BLE2.begin(9600);
}

void loop(){
  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis_BLE1 > interval_BLE1) {
  previousMillis_BLE1 = currentMillis;  
  SendTo_BLE1();
  interval_BLE1 = random(500,1000);
  }

  if(currentMillis - previousMillis_BLE2 > interval_BLE2) {
  previousMillis_BLE2 = currentMillis;  
  SendTo_BLE2();
  interval_BLE2 = random(500,2000);
  }
}

void SendTo_BLE1(){
  float TemperatureBLE1 = random(10,60000)/1000.0; // 3 decimals
  float HumidityBLE1 = random(5,99000)/1000.0;

  Serial.print(TemperatureBLE1,3);
  Serial.print(",");
  Serial.println(HumidityBLE1,3);
  BLE1.print(TemperatureBLE1,3);
  BLE1.print(",");
  BLE1.print(HumidityBLE1,3);  
}

void SendTo_BLE2(){
  float TemperatureBLE2 = random(10,60000)/1000.0; // 3 decimals
  float HumidityBLE2 = random(5,99000)/1000.0;
  
  String temperatureBLE2 = String(TemperatureBLE2,3);
  String humidityBLE2 = String(HumidityBLE2,3);

  String mensajeBLE2 = temperatureBLE2 + "," + humidityBLE2;
  Serial.println(mensajeBLE2);
  BLE2.print(mensajeBLE2.c_str());  
}

_________________________________
15.- Enviar mediante WriteBytes y WriteStrings.

p110_UNO_hm10_WriteBytes.aia

- Vamos a enviar una lista de números separados por coma con el bloque WriteBytes.

65,66,67,68,69,70

- Pasaremos estos números a lista. En esa lista se guardaran en forma de String:

["65","66","67","68","69","70"]

- Debemos pasarlo a otra lista_n convertido en números:

[65,66,67,68,69,70]

- También podemos enviar la información mediante WriteStrings.

_________________________________
- Diseño.

_________________________________
- Bloques.

_________________________________
- Arduino UNO.

WriteBytes_BLE.ino

// Juan A. Villalpando
// http://kio4.com/arduino/161_HM10_BLE.htm

#include <SoftwareSerial.h>
// El TXD del módulo al pin 2 (RX) del Arduino.
// El RXD del módulo al pin 3 (TX) del Arduino.
SoftwareSerial HM10(2, 3);

byte caracter = "";  
// char caracter = ' ';  

void setup(){
  Serial.begin(9600);
  HM10.begin(9600);
}

void loop(){
  if(HM10.available()) { 
  caracter = HM10.read();
  Serial.println(caracter); 
   }
} 

_________________________________
16.- Teclado en la aplicación envía un número de menos de 5 cifras a Arduino y se muestra en LCD-I2C.

p110_UNO_hm10_LCD.aia

Teclado.ino

// http://kio4.com/arduino/161_HM10_BLE.htm

#include <Wire.h>
// Pantalla LCD
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
// LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

#include <SoftwareSerial.h>
// El TXD del módulo al pin 2 (RX) del Arduino.
// El RXD del módulo al pin 3 (TX) del Arduino.
SoftwareSerial HM10(2, 3);

// byte caracter = "";  
char caracter = "";  
String mensaje = "";

void setup(){
  Serial.begin(9600);
  HM10.begin(9600);
  lcd.begin(16,2);// Columnas y filas de LCD.
}

void loop(){
  if(HM10.available()) { 
  caracter = HM10.read();
  // Serial.println(caracter);
  mensaje = mensaje + caracter;

  if(caracter == NULL ) { 
     Serial.println(mensaje); 
     mensaje = mensaje.substring(0, mensaje.length() - 1); // Delete last char   
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print(mensaje);
     mensaje = "";
     delay(100);
     }
  } 
}

_________________________________
- Diseño.

_________________________________
- Bloques.

______________________________
17.- HM-10 envía un texto largo a la aplicación.


p110_UNO_HM10_TextoLargo.aia

- El HM-10 envía cada cierto tiempo aleatorio (entre 500 y 1000 ms) cinco números aleatorios separados por coma.

- Además envía el caracter "#" indicando final de mensaje.

- Los números aleatorios tienen establecido el número de decimales como puedes ver en el código.

- Esta información el HM-10 la envía en paquetes de 20 caracteres.

- El código de la aplicación lee esos paquetes de caracteres, por ejemplo:

(19.650,729.62,4154.3)(,584.019,279.315,#)

- Observa que lo ha enviado en dos paquetes, ya que no puede enviar más de 20 caracteres (MTU).

- Estos paquetes llegan por la variable stringValues.

- La variable total va acumulando la información que va recibiendo hasta que el paquete contenga el caracter '#'

- En ese momento limpia la información que ha llegado y la pone de esta forma:

19.650,729.62,4154.3,584.019,279.315,#

- Mediante el bloque lista from csv row lo convierte en lista.

- Muestra cada elemento de la lista.

- Y borra las variable total para comenzar de nuevo a recibir paquetes.

_________________________________
- Diseño.

_________________________________
- Bloques.

_________________________________
- Arduino UNO.

Texto_Largo.ino

// Juan A. Villalpando
// http://kio4.com/arduino/161_HM10_BLE.htm

#include <SoftwareSerial.h>
// El TXD del módulo al pin 2 (RX) del Arduino.
// El RXD del módulo al pin 3 (TX) del Arduino.
SoftwareSerial BLE1(2, 3);

long previousMillis_BLE1 = 0;
int interval_BLE1 = 1000;

void setup(){
  Serial.begin(9600);
  BLE1.begin(9600);
}

void loop(){
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis_BLE1 > interval_BLE1) {
  previousMillis_BLE1 = currentMillis;  
  SendTo_BLE1();
  interval_BLE1 = random(500,1000);
  }
}

void SendTo_BLE1(){
  float x1 = random(10,60000)/1000.0; // 3 decimals
  float x2 = random(5,99000)/100.0; // 2 decimals
  float x3 = random(5,99000)/10.0; // 1 decimals
  float x4 = random(50,990000)/1000.0; // 3 decimals
  float x5 = random(500,990000)/1000.0; // 3 decimals

  BLE1.print(x1,3);
  BLE1.print(",");
  BLE1.print(x2,2);
  BLE1.print(",");
  BLE1.print(x3,1);
  BLE1.print(",");
  BLE1.print(x4,3);
  BLE1.print(",");
  BLE1.print(x5,3);
  BLE1.print(",");
  BLE1.print("#"); // End Of Message.
}

_____________________

- Otra manera sería enviar el último número mediante println()

BLE1.println(x5,3);
// BLE1.print(",");
// BLE1.print("#"); // End Of Message.


- Y modificar piece con \n, que significa fin de linea.

______________________________
18.- La aplicación envía un mensaje largo al HM-10.


p110_UNO_HM10_TextoLargo2.aia

- Al pulsar un Botón en la aplicación enviamos un texto largo al HM-10

uno, dos, tres cuatro, cinco, seis.
one, two, three, four, five, six.
un, deux, trois, quatre, cinq, six.
один, два, три, четыре, пять, шесть.
واحد إثنان ثلاثة أربعة خمسة ستة.
eins, zwei, drei, vier, fünf, sechs.

- Utilizaremos un Relos con un Intervalor de 10 ms.

_________________________________
- Diseño.

_________________________________
- Bloques.

_________________________________
- Arduino UNO.

Texto_Largo2.ino

// Juan A. Villalpando
// http://kio4.com/arduino/161_HM10_BLE.htm

#include <SoftwareSerial.h>
// El TXD del módulo al pin 2 (RX) del Arduino.
// El RXD del módulo al pin 3 (TX) del Arduino.
SoftwareSerial HM10(2, 3);

String texto;

void setup(){
  Serial.begin(9600);
  BLE1.begin(9600);
}

void loop(){
if(BLE1.available()) {
    texto = BLE1.readString();
    Serial.print(texto);
  }
}

_________________________________
19.- Comandos AT.

- Mediante los comandos AT podemos...

- Cambiar la clave del Bluetooth.
- Consultar su MAC.
- Consultar su versión.
- Consultar/Cambiar sus baudios.
- Consultar/Cambiar sus UUID.
- Consultar/Cambiar su nombre.

-
...

- Para que funcionen los comandos AT, el módulo BT debe estar desconectado de la aplicación pero conectado al Arduino, es decir el LED del módulo debe estar parpadeando. Enviamos los comando mediante el Monitor Serie o el programa HMPC Assistant que podemos bajar de la web de HM-10

- HMPC Assistant.

- Cargamos este Sketch.

Comandos_AT.ino

// Juan A. Villalpando
// http://kio4.com/arduino/161_HM10_BLE.htm

#include <SoftwareSerial.h>
// El TXD del módulo al pin 2 (RX) del Arduino.
// El RXD del módulo al pin 3 (TX) del Arduino.
SoftwareSerial HM10(2, 3);

void setup(){
  Serial.begin(9600);
  HM10.begin(9600);
}
 
void loop(){
  if(HM10.available()){Serial.write(HM10.read());}
 
  if(Serial.available()) {HM10.write(Serial.read());}
}

- Vamos al Monitor Serie y escribimos el comando que queramos ejecutar:

______________________
- Comandos AT

CC2540-BT05-AT-commands.pdf

User-Manual-3277305.pdf

Name: MLT-BT05; Baud: 9600, N, 8, 1; Pin code: 123456; Peripheral

********************************************************************
* Command             Description			           *
* ---------------------------------------------------------------- *
* AT                  Check if the command terminal work normally  *
* AT+RESET            Software reboot				   *
* AT+VERSION          Get firmware, bluetooth, HCI and LMP version *
* AT+HELP             List all the commands		           *
* AT+NAME             Get/Set local device name                    *
* AT+PIN              Get/Set pin code for pairing                 *
* AT+PASS             Get/Set pin code for pairing                 *
* AT+BAUD             Get/Set baud rate		                   *
* AT+LADDR            Get local bluetooth address		   *
* AT+ADDR             Get local bluetooth address		   *
* AT+DEFAULT          Restore factory default			   *
* AT+RENEW            Restore factory default			   *
* AT+STATE            Get current state				   *
* AT+PWRM             Get/Set power on mode(low power) 		   *
* AT+POWE             Get/Set RF transmit power 		   *
* AT+SLEEP            Sleep mode 		                   *
* AT+ROLE             Get/Set current role.	                   *
* AT+PARI             Get/Set UART parity bit.                     *
* AT+STOP             Get/Set UART stop bit.                       *
* AT+START            System start working.			   *
* AT+IMME             System wait for command when power on.	   *
* AT+IBEA             Switch iBeacon mode.	                   *
* AT+IBE0             Set iBeacon UUID 0.            	           *
* AT+IBE1             Set iBeacon UUID 1.            	           *
* AT+IBE2             Set iBeacon UUID 2.            	           *
* AT+IBE3             Set iBeacon UUID 3.            	           *
* AT+MARJ             Set iBeacon MARJ .            	           *
* AT+MINO             Set iBeacon MINO .            	           *
* AT+MEA              Set iBeacon MEA .            	           *
* AT+NOTI             Notify connection event .                    *
* AT+UUID             Get/Set system SERVER_UUID .            	   *
* AT+CHAR             Get/Set system CHAR_UUID .            	   *
* -----------------------------------------------------------------*
* Note: (M) = The command support slave mode only. 		   *
********************************************************************
  AT+ADVI  Intervalo de Advertiser

AT
OK
AT+HELP
AT+VERSION
MLT-BT05-V4.1
AT+NAMEMLT-BT05
+NAME=MLT-BT05
AT+PIN
+PIN=123456
AT+PASS
+PASS=123456
AT+BAUD
+BAUD=4 (4---------9600)
AT+LADDR
+LADDR=88:25:83:F1:04:B4
AT+ADDR?
+ADDR=88:25:83:F1:04:B4
AT+STATE
+STATE=2
AT+PWRM
+PWRM=1 (1:don’t auto sleep)
AT+POWE
+POWE=2 (2: 0dbm)
AT+SLEEP (Para despertarlo enviar más de 80 caracteres aleatorios)
AT+ROLE
+ROLE=0 (0: Peripheral)
AT+NOTI
+NOTI=0 (Permitir o no notificaciones)
AT+UUID (Para establecer o ver su UUID)
+UUID=0xFFE0
AT+CHAR
+CHAR=0xFFE1
AT+ADVI
+ADVI=0 (0--- 100 ms) (Intervalo de Advertiser)

Valores por defecto:
+MARJ=0xFFE0
+MINO=0xFFE1
+ADVI=0 [Tiempo de Advertisen modo iBeacon]
+IBEA=0 [Establecer/Quitar/Consultar modo iBeacon]
+NOTI=0
+PWRM=1
______________________________
20.- Ejemplo de iBeacon.

AT+MARJ0x1A2B Establezca el número principal de iBeacon en 0x1A2B (hexadecimal) (Desde:  0x0001~0xFFFE, Defectot: 0x FFE0)

AT+MINO0xF1E2 Establezca el número menor de iBeacon en 0xF1E2 (hexadecimal) (Desde:  0x0001~0xFFFE, Defecto: 0x FFE1)

AT+ADVI5 Establezca el intervalo publicitario en 5 (546.25 milisegundos)

AT+ADTY3 Hacer no conectable (ahorrar energía)

AT+IBEA1 Habilita el modo iBeacon [Estaba en AT+IBEA0]

AT+DELO2 iBeacon solo de transmisión (ahorre energía)

AT+PWRM0 [Ahora auto-sleep. Estaba en AT+PWRM1]

- Una vez establecidos los parámetros anteriores, vamos a la Play de Google y bajamos esta aplicación para ver el funcionamiento de nuestro iBeacon.

https://play.google.com/store/apps/details?id=com.bridou_n.beaconscanner&hl=es

- Observa la distancia en metros, los números menor y mayor, la UUID. 0x004C indica que es un desarrollo de Apple.

- El UUID que tiene asignado este iBeacon es: 74278BDA-B644-4520-8F0C-720EAF059935

- Lo podemos cambiar mediante:

AT+IBE074278BDA
AT+IBE1B6444520
AT+IBE28F0C720E
AT+IBE3AF059935

- Para consultar:

AT+IBE0
AT+IBE1
AT+IBE2
AT+IBE3

- La extensíón BLE no funciona apropiadamente con iBeacon, funcionan los bloques ScanAdvertisement, AdvertiserNames y AdvertiserAddress.

- Con iBeacon el módulo Bluetooth no debe estar conectado con ningún dispositivo ni debe conectar.

- Para salir del modo iBeacon:

AT+IBEA1

https://stackoverflow.com/questions/38759929/hm-10-at-commands-using-beacon-way-to-broadcast-sensors-data

__________

- UUID.

- Podemos cambiar los UUID mediante esta orden. Los números que podemos cambiar son los que están en negrita.

- Servicio:

AT+UUIDxxxxyyyyzzzz

Servicio: 0000xxxx-0000-1000-8000-00805-F9B34FB
Characteristic Read: 0000yyyy-0000-1000-8000-00805-F9B34FB
Characteristic Write: 0000zzzz-0000-1000-8000-00805-F9B34FB

Por defecto está así: FFE0, FFE1, FFE2

Servicio: 0000FFE0-0000-1000-8000-00805-F9B34FB
Characteristic Read: 0000FFE1-0000-1000-8000-00805-F9B34FB
Characteristic Write: 0000FFE2-0000-1000-8000-00805-F9B34FB

- Characteristic

AT+CHAR Get/Set system CHAR_UUID .

________

- PIO.

- PIO son los terminales del módulo, en este módulo los terminales no están conectados y no funciona la orden AT+MODE2 para pasarlo a modo PIO, mediante PIO este módulo podría funcionar en Stan-alone, pero este modelo no puede. El HM-10 original sí puede funcionar en modo PIO.

_________________________________________________

- Actualización del firmware. PIO.

- En el siguiente tutorial vamos a ver la forma de actualizar el firmware para trabajar con PIO

161_HM10_BLE_Actualizar.htm


______________________________________________
- Generador de UUID para BLE.

- Cada servicio, característica y descriptor tiene un UUID (Universally Unique Identifier). Un UUID es un número único de 16 bytes.

- Hay algunos UUID normalizados: SIG (Bluetooth Special Interest Group).

- Pero podemos crearnos unos UUID personales para nuestra aplicación: UUID generator.

https://github.com/pcbreflux/espressif/blob/master/esp32/arduino/sketchbook/ESP32_Eddystone_URL_deepsleep/ESP32_Eddystone_URL_deepsleep.ino

_______________________________

- Mi correo:
juana1991@yahoo.com
- KIO4.COM - Política de cookies. Textos e imágenes propiedad del autor:
© Juan A. Villalpando
No se permite la copia de información ni imágenes.
Usamos cookies propias y de terceros que entre otras cosas recogen datos sobre sus hábitos de navegación y realizan análisis de uso de nuestro sitio.
Si continúa navegando consideramos que acepta su uso. Acepto    Más información