BLECharacteristic *pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);
This is an excellent tutorial on the topic. Thank you for providing this information and for all of the good work.
Unfortunately, the AppInventor application appears to use a BLE extension (20201223) that was specially built to work around an issue. That extension is not available online. I've tried using the available extension (which was dated August 2020) but it won't connect. I will need to take this example application, duplicate it to get the library that's attached to it, and then rewrite pieces for my needs. Hopefully, the BLE connection issue will be resolved soon in a new AppInventor extension.
I have tracked BLE releases at
I see a download link there for the latest.
However the latest version 20201223 is for Testing, it is not as yet released.
Thanks ABG. I had already seen that page and there is no link to a 20201223 release of the BluetoothLE extension. There's a link that is labeled as such, but it leads to a thread that does not have the extension. It may have had it at one time, but it no longer does.
ChrisWard, I figured it was for testing only since it wasn't published at the standard location. However, the existing published extension doesn't work much at all with my BLE peripheral, whereas a test app I had downloaded that uses the test extension connects fairly well. So I am willing to be a guinea pig.
I have asked if we can make it a formal release..........
Thank you, Juan! This is really helpful.
Unfortunately, I am having trouble using the RegisterForStrings method. For some reason, StringsReceived is never triggered. This happens for both examples 6 and 7. I did not change anything in the code except for upgrading the BLE extension to the latest release, which I have attached. If I do ReadForStrings then everything works fine so I am not sure what is the issue here. I am using Samsung Galaxy A8s. Could you give me some advice?
Thank you!
Jerry
edu.mit.appinventor.ble-20200828.aix (195.3 KB)
14A.- Send a message longer than 20 characters. MTU.
p110i_esp32_ble_mtu.aia (203.7 KB)
-
The BLE extension sends the messages in 20-byte packets, this is called MTU (Minimum Transmission Unit). The size of these packets can be changed using the RequestMTU block, but this size change would have to be changed in the Block code and on the device code.
-
We are going to see a code to send a long text in 20-byte packets that will be concatenated in the ESP32 code, that is, 20-byte packets will be sent and they will be joined in the code until the complete text is obtained.
-
We will send this text:
La cigüeña voló a su nido.\nEl "Niño" provocó grandes inundaciones.\nEl señor Sánchez no es de Cádiz.\nThe stork flew to its nest.\nThe "Niño" caused great floods.\nMr. Sánchez is not from Cádiz.\n -
We will split the text into 15-character, this is because language characters such as ü, ñ, ó, á, need two bytes, if we send:
La cigüeña voló
-
we have cut 15 characters, but we are sending 18 bytes, since ü, ñ, ó need 2 bytes. We are actually sending a 20-byte packet, the indicated 18 bytes and 2 more bytes to complete the 20.
-
Those 15 characters will reach the ESP32 and will be displayed on the Serial Monitor:
Serial.print (valor);
-
As these packages arrive, they will be shown.
-
In addition, in another variable called valor_return, all the characters that arrive will be added.
-
When the "#" character arrives, the valor_return variable will be reset.
// Juan A. Villalpando
// http://kio4.com/arduino/160_Wemos_ESP32_BLE.htm
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
String valor;
String valor_return = "";
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string value = pCharacteristic->getValue();
if (value.length() > 0) {
valor = "";
for (int i = 0; i < value.length(); i++){
valor = valor + value[i];
}
Serial.print(valor); // Presenta valor.
valor_return = valor_return + valor;
}
pCharacteristic->setValue(valor_return.c_str()); // Valor return.
if(valor_return.indexOf("#") != -1){valor_return = "";}
}
};
void setup() {
Serial.begin(115200);
BLEDevice::init("MyESP32");
BLEServer *pServer = BLEDevice::createServer();
BLEService *pService = pServer->createService(SERVICE_UUID);
BLECharacteristic *pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setCallbacks(new MyCallbacks());
pService->start();
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->start();
}
void loop() {
// put your main code here, to run repeatedly:
}
oooooooooooooooooOOOOOOOOOOOOOOooooooooooooooooo
14B.- Send a message longer than 20 characters. MTU.
Simplified code.
p110i_esp32_ble_mtu2.aia (205.0 KB)
- By means of this code the characters are sent one by one.
// Juan A. Villalpando
// http://kio4.com/arduino/160_Wemos_ESP32_BLE.htm
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
String valor;
String valor_return = "";
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string value = pCharacteristic->getValue();
if (value.length() > 0) {
valor = "";
for (int i = 0; i < value.length(); i++){
valor = valor + value[i];
}
valor_return = valor_return + valor;
}
pCharacteristic->setValue(valor_return.c_str()); // Valor return.
if(valor_return.indexOf("#") != -1){Serial.print(valor_return); valor_return = "";}
}
};
void setup() {
Serial.begin(115200);
BLEDevice::init("MyESP32");
BLEServer *pServer = BLEDevice::createServer();
BLEService *pService = pServer->createService(SERVICE_UUID);
BLECharacteristic *pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setCallbacks(new MyCallbacks());
pService->start();
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->start();
}
void loop() {
// put your main code here, to run repeatedly:
}
15.- Two ESP32 with BLE send random temperature and humidity by Notification. Common Slider.
ESP32 with BLE generates (at random times) two random numbers temperatureBLE1 and humidityBLE2, and notifies them to the application.
Another ESP32 with BLE generates (at random times) two random numbers temperatureBLE2 and humidityBLE2, and notifies them to the application.
App sends a value to the two ESP32s through a Slider.
- Code for ESP32 with BLE1:
// Juan A. Villalpando
// http://kio4.com/arduino/160_Wemos_ESP32_BLE.htm
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
String valor;
long previousMillis_BLE1 = 0;
int interval_BLE1 = 1000;
BLEServer* pServer = NULL;
BLECharacteristic* pCharacteristic = NULL;
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string value = pCharacteristic->getValue();
if (value.length() > 0) {
valor = "";
for (int i = 0; i < value.length(); i++){
// Serial.print(value[i]); // Presenta value.
valor = valor + value[i];
}
Serial.println("*********");
Serial.print("valor = ");
Serial.println(valor); // Presenta valor.
}
}
};
///////////////////////////////////////////////////
void setup() {
Serial.begin(115200);
// Create the BLE1 Device
BLEDevice::init("MyESP32_BLE1");
// Create the BLE Server
pServer = BLEDevice::createServer();
BLEService *pService = pServer->createService(SERVICE_UUID);
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY |
BLECharacteristic::PROPERTY_INDICATE
);
pCharacteristic->setCallbacks(new MyCallbacks());
pService->start();
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->start();
}
void loop() {
unsigned long currentMillis = millis();
if(currentMillis - previousMillis_BLE1 > interval_BLE1) {
float TemperatureBLE1 = random(10,60000)/1000.0; // 3 decimals
float HumidityBLE1 = random(5,99000)/1000.0; // 3 decimals
String temperatureBLE1 = String(TemperatureBLE1,3);
String humidityBLE1 = String(HumidityBLE1,3);
String tem_hum_BLE1 = temperatureBLE1 + "," + humidityBLE1;
std::string value = pCharacteristic->getValue();
pCharacteristic->setValue(tem_hum_BLE1.c_str()); // Notify.
pCharacteristic->notify();
previousMillis_BLE1 = currentMillis;
interval_BLE1 = random(500,1000);
}
}
- Code for ESP32 with BLE2:
// Juan A. Villalpando
// http://kio4.com/arduino/160_Wemos_ESP32_BLE.htm
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
String valor;
long previousMillis_BLE2 = 0;
int interval_BLE2 = 1000;
BLEServer* pServer = NULL;
BLECharacteristic* pCharacteristic = NULL;
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string value = pCharacteristic->getValue();
if (value.length() > 0) {
valor = "";
for (int i = 0; i < value.length(); i++){
// Serial.print(value[i]); // Presenta value.
valor = valor + value[i];
}
Serial.println("*********");
Serial.print("valor = ");
Serial.println(valor); // Presenta valor.
}
}
};
///////////////////////////////////////////////////
void setup() {
Serial.begin(115200);
// Create the BLE2 Device
BLEDevice::init("MyESP32_BLE2");
// Create the BLE Server
pServer = BLEDevice::createServer();
BLEService *pService = pServer->createService(SERVICE_UUID);
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY |
BLECharacteristic::PROPERTY_INDICATE
);
pCharacteristic->setCallbacks(new MyCallbacks());
pService->start();
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->start();
}
void loop() {
unsigned long currentMillis = millis();
if(currentMillis - previousMillis_BLE2 > interval_BLE2) {
float TemperatureBLE2 = random(10,60000)/1000.0; // 3 decimals
float HumidityBLE2 = random(5,99000)/1000.0; // 3 decimals
String temperatureBLE2 = String(TemperatureBLE2,3);
String humidityBLE2 = String(HumidityBLE2,3);
String tem_hum_BLE2 = temperatureBLE2 + "," + humidityBLE2;
std::string value = pCharacteristic->getValue();
pCharacteristic->setValue(tem_hum_BLE2.c_str()); // Notify.
pCharacteristic->notify();
previousMillis_BLE2 = currentMillis;
interval_BLE2 = random(500,2000);
}
}
16.- RegisterForBytes. Notification. ESP32 sends random numbers.
p110_esp32_ble_notifica_byte.aia (202.3 KB)
To send information from ESP32 to the application I prefer to use Strings, but in this example I will use Bytes.
- ESP32 creates every 500 ms, random numbers from 1 to 99999 and notifies the number using 4 bytes:
pCharacteristic->setValue((uint8_t*)&aleatorio, 4);
- App receives the notification of those 4 bytes and converts it to an integer.
// Juan A. Villalpando
// http://kio4.com/arduino/160_Wemos_ESP32_BLE.htm
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
BLEServer* pServer = NULL;
BLECharacteristic* pCharacteristic = NULL;
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
void setup() {
Serial.begin(115200);
BLEDevice::init("ESP32");
// Create the BLE Server
pServer = BLEDevice::createServer();
// Create the BLE Service
BLEService *pService = pServer->createService(SERVICE_UUID);
// Create a BLE Characteristic
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_NOTIFY
);
// Start the service
pService->start();
// Start advertising
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
BLEDevice::startAdvertising();
}
void loop() {
// notify changed value
int aleatorio = random(1,99999); // Crea el numero aleatorio.
String alea = (String) aleatorio; // Lo convierte en String.
// pCharacteristic->setValue(alea.c_str()); // Envia STRING
Serial.println(aleatorio);
pCharacteristic->setValue((uint8_t*)&aleatorio, 4); // Envia 4 BYTES
pCharacteristic->notify();
delay(500);
}
Example:
aleatorio = 18144
4 Bytes = (224 70 0 0)
224 + 70 * 256 = 18144
Has "RegisterForStrings" and "StringsRecieved" been removed? Examples (eg 6) with these don't work and the block view shows a popup "This block is not defined" for both of these blocks.
Check version:
If you get this...
delete...
Read this...
http://kio4.com/arduino/160_Wemos_ESP32_BLE.htm
17.- RegisterForStrings. Notification. ESP sends random numbers. VUmeter simulation.
p160_Wemos_ESP32_VUmeter.aia (208.4 KB)
- ESP sends (NOTIFY) two random numbers separated by commas (as Strings) with a random delay, example:
4,9 - App gets String. Split.
izq = 4
der = 9
and
draws the background color on the Labels.
// Juan A. Villalpando
// http://kio4.com/arduino/160_Wemos_ESP32_BLE.htm
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
BLEServer* pServer = NULL;
BLECharacteristic* pCharacteristic = NULL;
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
void setup() {
Serial.begin(115200);
BLEDevice::init("ESP32");
// Create the BLE Server
pServer = BLEDevice::createServer();
// Create the BLE Service
BLEService *pService = pServer->createService(SERVICE_UUID);
// Create a BLE Characteristic
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_NOTIFY
);
// Start the service
pService->start();
// Start advertising
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
BLEDevice::startAdvertising();
}
void loop() {
// notify changed value
int izq = random(0,11); // Crea el numero aleatorio izq.
int der = random(0,11); // Crea el numero aleatorio der.
String alea = (String) izq + "," + (String) der; // Lo convierte en String.
Serial.println(alea);
pCharacteristic->setValue(alea.c_str()); // Envia STRING
pCharacteristic->notify();
int random_delay = random(500,2000);
delay(random_delay);
}
18.- Multiconnect. Connect two mobiles at the same time to an ESP32.
These examples can be a bit longer, so I have put it in another topic:
I have two ESP32 DEV V1 board with lora and gps parts. I want to creat app from mit app inventor. I finish Bluetooth connect with app
I want take the data from esp32. I had find firebase, but only can use Wi-Fi connect.
I want to ask how can I take the data with Bluetooth ? Thanks for help.
Hello.
Can someone help me?
I have created the following app and Arduino code.
Everything works, except for the text that is always displayed before [" and after "] in the output.
In the serial monitor of the Arduino IDE, the characters are not.
Where could the error lie?
Translated with google translator !
// Juan Antonio Villalpando.
// http://kio4.com/arduino/160_Wemos_ESP32_BLE.htm
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
String readBT;
String sendBT = "";
int move = 2;
int oldmove;
int speed = 5;
int oldspeed;
int OnOff = 0;
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
class MyCallbacks : public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string value = pCharacteristic->getValue();
if (value.length() > 0) {
readBT = "";
for (int i = 0; i < value.length(); i++) {
readBT = readBT + value[i];
}
if (readBT == "load") {
sendBT = ("Speed: " + (String)speed + " % / Weg: " + (String)move + " cm");
pCharacteristic->setValue(sendBT.c_str()); // Return status
}
if (readBT == "on") {
OnOff = 1;
//Serial.print(OnOff);
}
if (readBT == "off") {
OnOff = 0;
//Serial.print(OnOff);
}
if (readBT == "s+" && OnOff == 1 && speed < 100) {
speed = (speed) + 5;
//Serial.print(speed);
}
if (readBT == "s-" && OnOff == 1 && speed > 5) {
speed = (speed)-5;
//Serial.print(speed);
}
if (readBT == "m+" && OnOff == 1 && move < 22) {
move = (move) + 2;
//Serial.print(move);
}
if (readBT == "m-" && OnOff == 1 && move > 2) {
move = (move)-2;
//Serial.print(move);
}
if ((speed != oldspeed) || (move != oldspeed)) {
sendBT = "Speed: " + (String)speed + " % / Weg: " + (String)move + " cm";
pCharacteristic->setValue(sendBT.c_str()); // Return status
oldspeed = speed;
oldmove = move;
Serial.println(sendBT);
}
}
}
};
void setup() {
Serial.begin(115200);
BLEDevice::init("MyESP32");
BLEServer *pServer = BLEDevice::createServer();
BLEService *pService = pServer->createService(SERVICE_UUID);
BLECharacteristic *pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE);
pCharacteristic->setCallbacks(new MyCallbacks());
//pCharacteristic->setValue("Gestartet.");
pService->start();
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->start();
}
void loop() {
}
Thanks that worked.
Hello, I have been trying to follow this guide but without success. My phone can scan and recognize the ESP32 but it could not connect. I am using Android version 13 and Arduino IDE version 2.1.1.
When I followed the guide, the Neil Kolban's ESP32 library was conflicting with the built-in Arduino IDE ESP32 library. I tried to disable the built-in library but it did not work either. Also don't know where to find the BLE extension version 20201223, so I used the latest version (20230728). I also tried with the BLE-device-sort.aix.
The Arduino code that I tried:
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
void setup() {
BLEDevice::init("Here_ESP32");
BLEServer *pServer = BLEDevice::createServer();
BLEService *pService = pServer->createService(SERVICE_UUID);
BLECharacteristic *pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setValue("Connected.");
pService->start();
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->start();
}
void loop() {}
I am using ESP-WROOM-32 instead of ESP-WROOM-32D.
Can anybody help please?
Thank you!