Dear Beloved Arduino UNO R4 WiFi brothers and sisters:
Many questions here about how to make Bluetooth LE work on the Arduino UNO R4. Here I am sharing some sample code which has worked for me, for your kind copy/paste and evaluation:
I managed to modify some interesting bits of code in HTML to be run from the server (works only in Google Browser, as I cannot get Bluetooth activated in Firefox) via JavaScript - and then I used the LedControl software from the sample code brought by the Bluetooth BLE 0.2.1 library (thanks, @ptillish !) - and I got the following:
bluetooth.html:
<!DOCTYPE html>
<html>
<head>
<title>Bluetooth BLE Device Communication</title>
</head>
<body>
<button id="connectButton">Connect to Bluetooth Device</button>
<script>
if ('bluetooth' in navigator) {
/*
Error:TypeError: Failed to execute 'getPrimaryService' on 'BluetoothRemoteGATTServer':
Invalid Service name: '19B10000-E8F2-537E-4F6C-D104768A1214'.
It must be a valid UUID alias (e.g. 0x1234),
UUID (lowercase hex characters e.g. '00001234-0000-1000-8000-00805f9b34fb'), or
recognized standard name from https://www.bluetooth.com/specifications/gatt/services e.g.
'alert_notification'.
*/
/*
Error:SecurityError:
Origin is not allowed to access any service.
Tip: Add the service UUID to 'optionalServices' in requestDevice() options. https://goo.gl/HxfxSQ
*/
const bluetooth = navigator.bluetooth;
// Function to connect to the device
async function connectToDevice() {
rv = "Initiating Bluetooth ";
alert("Initiating Bluetooth");
try {
const device = await bluetooth.requestDevice({
filters: [{ name: 'LEDCallback' }],
optionalServices: ['19b10000-e8f2-537e-4f6c-d104768a1214'] // Add your service UUID here
});
rv += "A";
const server = await device.gatt.connect();
rv += "B";
// Replace these UUIDs with your Arduino's service and characteristic UUIDs
const service = await server.getPrimaryService('19b10000-e8f2-537e-4f6c-d104768a1214');
rv += "C";
const characteristic = await service.getCharacteristic('19b10001-e8f2-537e-4f6c-d104768a1214');
rv += "D";
singleshot = true;
if (singleshot) {
// Read the value of the characteristic
//characteristic.writeValue("Browser");
const value = await characteristic.readValue();
rv += "E";
const decodedValue = new TextDecoder().decode(value);
rv += "F";
document.body.innerHTML = '<home><body><h1>Fetched Value: ' + rv + ' '+ decodedValue + '</h1></body></home>';
} else {
// Enable notifications for the characteristic
await characteristic.startNotifications();
rv += "J";
// Set up a callback to handle incoming notifications
characteristic.addEventListener('characteristicvaluechanged', handleNotifications);
rv += "K";
document.getElementById('connectButton').disabled = true;
}
} catch (error) {
alert ('Error: ' + rv + ' ' + error);
}
}
function handleNotifications(event) {
const value = event.target.value;
const decodedValue = new TextDecoder().decode(value);
console.log('Received Value:', decodedValue);
// You can update your HTML to display the received value
document.getElementById('receivedValue').textContent = decodedValue;
}
// Attach the connectToDevice function to the button click event
const connectButton = document.getElementById('connectButton');
connectButton.addEventListener('click', connectToDevice);
} else {
console.log('Bluetooth is not supported by this browser.');
}
</script>
</body>
</html>
bluetooth_arduino.ino:
#include <ArduinoBLE.h>
BLEService ledService("19b10000-e8f2-537e-4f6c-d104768a1214");
BLECharacteristic switchCharacteristic("19b10001-e8f2-537e-4f6c-d104768a1214", BLERead | BLEWrite | BLENotify | BLEBroadcast, 20);
const int ledPin = LED_BUILTIN;
const char* stringArray[4] = {
"YapplyHoo",
"Superposition",
"QuantumLeap",
"Einsteinium"
};
void setup() {
Serial.begin(9600);
while (!Serial);
pinMode(ledPin, OUTPUT);
if (!BLE.begin()) {
Serial.println("Starting Bluetooth® Low Energy module failed!");
while (1);
}
BLE.setLocalName("LEDCallback");
BLE.setAdvertisedService(ledService);
ledService.addCharacteristic(switchCharacteristic);
BLE.addService(ledService);
BLE.setEventHandler(BLEConnected, blePeripheralConnectHandler);
BLE.setEventHandler(BLEDisconnected, blePeripheralDisconnectHandler);
switchCharacteristic.setEventHandler(BLEWritten, switchCharacteristicWritten);
switchCharacteristic.writeValue("Heureka");
BLE.advertise();
Serial.println("Bluetooth® device active, waiting for connections...");
}
int counter=0;
void loop() {
BLE.poll();
delay(1000);
Serial.print("."); // Timer tick
}
void blePeripheralConnectHandler(BLEDevice central) {
Serial.print("Connected event, central: ");
Serial.println(central.address());
}
void blePeripheralDisconnectHandler(BLEDevice central) {
Serial.print("Disconnected event, central: ");
Serial.println(central.address());
}
void switchCharacteristicWritten(BLEDevice central, BLECharacteristic characteristic) {
Serial.print("Characteristic event, written: ");
uint8_t characteristicValue[20];
int bytesRead = characteristic.readValue(characteristicValue, sizeof(characteristicValue));
Serial.print("Received bytes: ");
for (int i = 0; i < bytesRead; i++) {
Serial.print(characteristicValue[i], HEX);
Serial.print(" ");
}
Serial.println();
String receivedString = "";
for (int i = 0; i < bytesRead; i++) {
receivedString += (char)characteristicValue[i];
}
Serial.println("Value: " + receivedString);
characteristic.writeValue(stringArray[random(0, 4)]); // set initial value for this characteristic
}