Hi, here is a sketch that runs with the nRF Blinky app for Android and iOS,
nRF Blinky on the App Store (app on appstore)
GitHub - NordicSemiconductor/IOS-CoreBluetooth-Mock: Mocking library for CoreBluetooth framework. (code)
https://play.google.com/store/apps/details?id=no.nordicsemi.android.nrfblinky&hl=en&gl=US (app on google play)
GitHub - NordicSemiconductor/Android-nRF-Blinky: nRF Blinky is an application developed targeting an audience of developers who are new to Bluetooth Low Energy (code)
I wrote this because I could not find a complete example of radio communication between arduino and a mobile device including both an arduino sketch and a complete android and iOS app. If there is such an example elsewhere please tell me so.
For the description & what you can do with it please see comments at top of the sketch.
All remarks very welcome.
/*
Implementation of the Nordic Semiconductor LBS : Led and Button Service for Arduino BLE
This is a simple application that can serve as a template, it performs two actions: turning a LED on the arduino on and off,
and sending back from the arduino the status of a button.
See https://github.com/NordicSemiconductor/Android-nRF-Blinky
and https://github.com/NordicSemiconductor/IOS-CoreBluetooth-Mock/
Since you have an example of communication in each direction, you can extend to do anything you want.
Also, if like me you are a total newby to programming on Android and iOS, you have a complete example app with a user interface
that works, and you can just go in and modify as needed.
My suggestion: start by adding a display on your app of all the sensor data of the arduino. Modify the button-status code so it
returns the accelerometer and whatever other sensors you have (if you have a BLE Sense you have temperature, barometric...)
First, display those as numbers. Then, introduce beautiful graph display using the tons of iOS/Android libraries available.
For Services and Characteristics UUID's you have a choice:
1) Use existing services/characteristics, as in this example by sunim931: https://forum.arduino.cc/t/bluetooth-communications/902610/2
2) Create your own services/characteristcs, they are free to create as long as the arduino and the app are in agreement.
Tested on Arduino Nano 33 BLE & nRF Blinky app on Iphone SE 2020 (iOS 17) and Samsung Tab A (Android 4.4)
Yes, it works fine on an old tablet, no need for android 5! get that old android out of the drawer!
Known bugs: on iOS the name of the device shows up as "Unknown Device", everything else works fine.
On Android, it's all fine including the name, so I assume it's a bug of the iOS app and not a problem with the sketch.
Does not require any wiring because the button is simulated by a timer, add real button if you wish
By David Bonner 2024 - arduino ID: dbonner
*/
#include <ArduinoBLE.h>
//----------------------------------------------------------------------------------------------------------------------
// BLE UUIDs these are defined by NRF Blinky app
//----------------------------------------------------------------------------------------------------------------------
#define BLE_UUID_NORDIC_LBS "00001523-1212-EFDE-1523-785FEABCD123" // Nordic Semiconductor test service with a LED and a button
#define BLE_UUID_LED_STATE "00001525-1212-EFDE-1523-785FEABCD123"
#define BLE_UUID_BUTTON_STATE "00001524-1212-EFDE-1523-785FEABCD123"
//----------------------------------------------------------------------------------------------------------------------
// BLE
//----------------------------------------------------------------------------------------------------------------------
#define BLE_DEVICE_NAME "Nano33BLE" // put your device name here
#define BLE_LOCAL_NAME "Nano33BLE"
BLEService ledAndButtonService(BLE_UUID_NORDIC_LBS);
BLEUnsignedCharCharacteristic ledState(BLE_UUID_LED_STATE, BLEWrite);
BLEUnsignedCharCharacteristic buttonState(BLE_UUID_BUTTON_STATE, BLENotify);
bool debug = 1;
unsigned int t, oldt;
unsigned char buttonVal;
void setup() {
t = oldt = 0;
buttonVal = 0;
//if(debug){Serial.begin( 9600 ); while ( !Serial );}
if (debug) Serial.begin(9600);
if (debug) Serial.println("BLE Example - Nordic LBS service");
// For the LED turning on/off from the app
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
if (!BLE.begin()) {
if (debug) Serial.println("Waiting for BLE to start");
delay(100);
}
// set advertised local name and service UUID
BLE.setDeviceName(BLE_DEVICE_NAME);
BLE.setLocalName(BLE_LOCAL_NAME);
BLE.setAdvertisedService(ledAndButtonService);
// BLE add characteristics
ledAndButtonService.addCharacteristic(ledState);
ledAndButtonService.addCharacteristic(buttonState);
// add service
BLE.addService(ledAndButtonService);
// set the initial value for the characeristic
ledState.writeValue(0);
buttonState.writeValue(0);
// start advertising
BLE.advertise();
}
void loop() {
BLEDevice central = BLE.central();
// if a central is connected to the peripheral:
if (central) {
// print the central's BT address:
if (debug) Serial.print("Connected to central: ");
if (debug) Serial.println(central.address());
// turn on LED to indicate connection:
digitalWrite(LED_BUILTIN, HIGH);
// while the central remains connected:
while (central.connected()) {
// turn the LED on or off
unsigned char ledval;
ledState.readValue(ledval);
if (ledval) digitalWrite(LED_BUILTIN, HIGH);
else digitalWrite(LED_BUILTIN, LOW);
// report to the central when a button is pressed
// I wanted the sketch to work with no wiring so the button is simulated by a timer
// Every 2 seconds the app will switch between button PRESSED & RELEASED
// Replace by a digital read of a pin in the code below if you want a real button
t = millis();
if ((t - oldt) > 2000) {
if (debug) {
Serial.print("changing button state to ");
Serial.println(buttonVal);
}
oldt = t;
buttonState.writeValue(buttonVal);
buttonVal = !buttonVal;
}
}
} else {
// turn off the LED
digitalWrite(LED_BUILTIN, LOW);
}
}