Adsense HTML/JavaScript

Thursday, March 17, 2022

BLE between Nano RP2040 Connect and XIAO BLE Sense, using ArduinoBLE in Arduino Framework.

 Last post a simple ArduinoBLE between Nano RP2040 Connect (Peripheral LED) and XIAO BLE Sense (Central LedControl), this is further exercise in reverse role, with additional feature displaying on OLED.

Seeed XIAO BLE Sense:
XIAOBLE_CallbackLED_OLED.ino,
act as BLE Peripheral, control LED and OLED display base on BLE received data.

Arduino Nano RP2040 Connect:
RP2040Con_LedControl_OLED.ino,
act as BLE Central, read button (the yellow wire) and get user input from Serial, send to Peripheral to control LED and display on OLED.



XIAOBLE_CallbackLED_OLED.ino
/*
  Run on XIAO BLESensor:

  This example creates a BLE peripheral with service that contains a
  characteristic to control an LED and OLED. The callback features of the
  library are used.

  Modified from ArduinoBLE > Peripheral > CallbackLED example

*/

#include <ArduinoBLE.h>
#include <Arduino.h>
#include <U8x8lib.h>
#include <Wire.h>

#define MyLocalName "XIAO BLE"
#define MyStringChar_UUID "22a28815-c6bd-401b-a0f1-d47c42a0bd70"

U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);

BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214"); // create service

// create switch characteristic and allow remote device to read and write
BLEByteCharacteristic switchCharacteristic(
              "19B10001-E8F2-537E-4F6C-D104768A1214", 
              BLERead | BLEWrite);
BLEStringCharacteristic myStringCharacteristic(
              MyStringChar_UUID,
              BLERead | BLEWrite, 16);

const int ledPin = LED_BUILTIN; // pin to use for the LED

void setup() {
  u8x8.begin();
  u8x8.setFlipMode(1); //rotary 180

  u8x8.setFont(u8x8_font_chroma48medium8_r);
  u8x8.setCursor(0, 0);
  u8x8.print("XIAO BLE");
  
  Serial.begin(9600);

  //comment to skip Serial port waiting,
  //such that it can sork stand alone without computer.
  //while (!Serial);
  
  pinMode(ledPin, OUTPUT); // use the LED pin as an output

  // begin initialization
  if (!BLE.begin()) {
    Serial.println("starting BLE failed!");

    while (1);
  }

  // set the local name peripheral advertises
  BLE.setLocalName(MyLocalName);
  // set the UUID for the service this peripheral advertises
  BLE.setAdvertisedService(ledService);

  // add the characteristic to the service
  ledService.addCharacteristic(switchCharacteristic);
  ledService.addCharacteristic(myStringCharacteristic);

  // add service
  BLE.addService(ledService);

  // assign event handlers for connected, disconnected to peripheral
  BLE.setEventHandler(BLEConnected, blePeripheralConnectHandler);
  BLE.setEventHandler(BLEDisconnected, blePeripheralDisconnectHandler);

  // assign event handlers for characteristic
  switchCharacteristic.setEventHandler(BLEWritten, switchCharacteristicWritten);
  myStringCharacteristic.setEventHandler(BLEWritten, myStringCharacteristicWritten);
  // set an initial value for the characteristic
  switchCharacteristic.setValue(0);
  myStringCharacteristic.setValue("XIAO BLE");

  // start advertising
  BLE.advertise();

  Serial.println(("Bluetooth device active, waiting for connections..."));
}

void loop() {
  // poll for BLE events
  BLE.poll();
}

void blePeripheralConnectHandler(BLEDevice central) {
  // central connected event handler
  Serial.print("Connected event, central: ");
  Serial.println(central.address());
}

void blePeripheralDisconnectHandler(BLEDevice central) {
  // central disconnected event handler
  Serial.print("Disconnected event, central: ");
  Serial.println(central.address());
}

void switchCharacteristicWritten(BLEDevice central, 
                      BLECharacteristic characteristic) {
  // central wrote new value to characteristic, update LED
  Serial.print("Characteristic event, written: ");

  if (switchCharacteristic.value()) {
    Serial.println("LED on");
    digitalWrite(ledPin, !HIGH);
  } else {
    Serial.println("LED off");
    digitalWrite(ledPin, !LOW);
  }
}

void myStringCharacteristicWritten(BLEDevice central, 
                      BLECharacteristic characteristic) {
  // central wrote new value to characteristic, update LED
  Serial.println("mySttringCharacteristic event, written: ");

  Serial.println("myStringCharacteristic received: len=" + 
                  String(myStringCharacteristic.valueLength()));
  String valString = myStringCharacteristic.value();
  Serial.println(valString);

  u8x8.clear();
  u8x8.setCursor(0, 0);
  u8x8.print(valString);

  Serial.println();
}

RP2040Con_LedControl_OLED.ino
/*
  run on Aduino RP2040 NANO Connect

  This example scans for BLE peripherals until one with the advertised service
  "19b10000-e8f2-537e-4f6c-d104768a1214" UUID is found. Once discovered and connected,
  it will remotely control the BLE Peripheral's LED, when the button is pressed or released.

  And also get user input from Serial Monitor, send to BLE Peripheral

  modified from ArduinoBLE > Central > LedControl
*/

#include <ArduinoBLE.h>

// variables for button
const int buttonPin = 2;
int oldButtonState = LOW;

#define MyLocalName "XIAO BLE"
#define MyStringChar_UUID "22a28815-c6bd-401b-a0f1-d47c42a0bd70"

void setup() {
  Serial.begin(9600);
  while (!Serial);

  // configure the button pin as input
  pinMode(buttonPin, INPUT_PULLUP);

  // initialize the BLE hardware
  BLE.begin();

  Serial.println("BLE Central - LED control");

  // start scanning for peripherals
  BLE.scanForUuid("19b10000-e8f2-537e-4f6c-d104768a1214");
}

void loop() {
  // check if a peripheral has been discovered
  BLEDevice peripheral = BLE.available();

  if (peripheral) {
    // discovered a peripheral, print out address, local name, and advertised service
    Serial.print("Found ");
    Serial.print(peripheral.address());
    Serial.print(" '");
    Serial.print(peripheral.localName());
    Serial.print("' ");
    Serial.print(peripheral.advertisedServiceUuid());
    Serial.println();

    if (peripheral.localName() != MyLocalName) {
      return;
    }

    // stop scanning
    BLE.stopScan();

    controlLed(peripheral);

    // peripheral disconnected, start scanning again
    BLE.scanForUuid("19b10000-e8f2-537e-4f6c-d104768a1214");
  }
}

void controlLed(BLEDevice peripheral) {
  // connect to the peripheral
  Serial.println("Connecting ...");

  if (peripheral.connect()) {
    Serial.println("Connected");
  } else {
    Serial.println("Failed to connect!");
    return;
  }

  // discover peripheral attributes
  Serial.println("Discovering attributes ...");
  if (peripheral.discoverAttributes()) {
    Serial.println("Attributes discovered");
  } else {
    Serial.println("Attribute discovery failed!");
    peripheral.disconnect();
    return;
  }

  // retrieve the LED/OLED characteristic
  BLECharacteristic ledCharacteristic = peripheral.characteristic("19b10001-e8f2-537e-4f6c-d104768a1214");
  BLECharacteristic oledCharacteristic = peripheral.characteristic(MyStringChar_UUID);
  
  /*
  if (!ledCharacteristic) {
    Serial.println("Peripheral does not have LED characteristic!");
    peripheral.disconnect();
    return;
  } else if (!ledCharacteristic.canWrite()) {
    Serial.println("Peripheral does not have a writable LED characteristic!");
    peripheral.disconnect();
    return;
  }
  */

  while (peripheral.connected()) {
    // while the peripheral is connected

    // read the button pin
    int buttonState = !digitalRead(buttonPin);

    if (oldButtonState != buttonState) {
      // button changed
      oldButtonState = buttonState;

      if (buttonState) {
        Serial.println("button pressed");

        // button is pressed, write 0x01 to turn the LED on
        ledCharacteristic.writeValue((byte)0x01);
      } else {
        Serial.println("button released");

        // button is released, write 0x00 to turn the LED off
        ledCharacteristic.writeValue((byte)0x00);
      }
    }

    if (Serial.available() > 0){
      String stringIn = Serial.readString();
      Serial.println(stringIn);
      oledCharacteristic.writeValue(stringIn.c_str());
    }
  }

  Serial.println("Peripheral disconnected");
}


No comments:

Post a Comment