Tutorial for Arduino BLE : Nordic nRF Blinky Sketch

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);
  }
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.