Xiao Sense Accelerometer Examples and Low Power

#include <ArduinoBLE.h>

#include <LSM6DS3.h>

#include <Wire.h>

const int buttonPin = 2;  // the number of the pushbutton pin

const int ledPin = 13;    // the number of the LED pin

const int NTC_PIN = A0;

int buttonState = 0;

float temperature = 0.0;

const float BETA = 3950; // should match the Beta Coefficient of the thermistor

const int usbPin = LEDG;

int usbState = 0;

// https://github.com/NordicSemiconductor/bluetooth-numbers-database/blob/master/v1/characteristic_uuids.json

// Pressure 2A6D

// Scientific Temperature Celsius 2A3C

// "Temperature","uuid": "2A6E"

// "Temperature Celsius",  "uuid": "2A1F"

//"Temperature Fahrenheit", "uuid": "2A20"

//"Temperature Measurement uuid": "2A1C"

// "Temperature uuid": "2A1D"

const char* blePeripheralName = "MyBLEDevice";

BLEService customService("2A3C");

BLEStringCharacteristic customCharacteristic("2A3C", BLERead | BLENotify, 1024);

LSM6DS3 myIMU(I2C_MODE, 0x6A); // IMU

#define int1Pin 2

uint8_t interruptCount = 0; // Amount of received interrupts

uint8_t prevInterruptCount = 0; // Interrupt Counter from last loop

void setup() {

  Serial.begin(9600);

  if (!BLE.begin()) {

    Serial.println("Starting BLE failed!");

    while (1);

  }

  BLE.setLocalName(blePeripheralName);

  BLE.setAdvertisedService(customService);

  customService.addCharacteristic(customCharacteristic);

  BLE.addService(customService);

  BLE.advertise();

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

  if (myIMU.begin() != 0) {

        Serial.println("IMU error");

    } else {

        Serial.println("IMU OK!");

    }

  myIMU.settings.gyroEnabled = 0; // Gyro currently not used, disabled to save power

  setupDoubleTapInterrupt();

  pinMode(int1Pin, INPUT);

  attachInterrupt(digitalPinToInterrupt(int1Pin), int1ISR, RISING);

 

  pinMode(LED_BUILTIN, OUTPUT);// initialize the LED pin as an output:

  pinMode(buttonPin, INPUT_PULLUP);// initialize the pushbutton pin as an input:

  pinMode(LEDR, OUTPUT);

  pinMode(LEDG, OUTPUT);

  pinMode(LEDB, OUTPUT);

  setLedRGB(false, false, true); // set blue led

}

void loop() {

  BLEDevice central = BLE.central();

  temperature = getNTCTemperature();

  usbState = digitalRead(usbPin);

  if (central) {

    Serial.print("Connected to central: ");

    Serial.println(central.address());

    while (central.connected()) {

      buttonState = digitalRead(buttonPin);

      Serial.println(buttonState);

      // Check if digital input is LOW (0)

      if ( buttonState == 0 ) {

        // Send an alert to the connected central device

        customCharacteristic.writeValue("Wire Disconnected!");

        digitalWrite(ledPin, HIGH);

      }

      else

      {

        digitalWrite(ledPin, LOW);

        customCharacteristic.writeValue("Wire Connected");

      }

      delay(1000); // Adjust the delay according to your requirements

    }

    digitalWrite(ledPin, HIGH);

    Serial.print("Disconnected from central: ");

    Serial.println(central.address());

  }

  Serial.print("\Iterrupt Counter: ");

  Serial.println(interruptCount);

  // if interrupt was received in this cycle

  if (interruptCount > prevInterruptCount) {

    Serial.println("\Interrupt received!");

    setLedRGB(false, true, false); // set green only

  }

  prevInterruptCount = interruptCount;

  if (interruptCount >= 3) {

    // Trigger System OFF after 3 interrupts

    goToPowerOff();

  }

  delay(500);

}

// NTC

float getNTCTemperature()

{

  int analogValue = analogRead(NTC_PIN);

  float celsius = 1 / (log(1 / (1023. / analogValue - 1)) / BETA + 1.0 / 298.15) - 273.15;

  Serial.print("Temperature: ");

  Serial.print(celsius);

  Serial.println(" ℃");

  return celsius;

}

// -------------------- System ------------------------- //

void goToPowerOff() {

  setLedRGB(false, false, false);

  Serial.println("Going to System OFF");

  setupDoubleTapInterrupt(); // not needed here, if already applied..

  delay(1000); // delay seems important to apply settings, before going to System OFF

  //Ensure interrupt pin from IMU is set to wake up device

  nrf_gpio_cfg_sense_input(digitalPinToInterrupt(int1Pin), NRF_GPIO_PIN_PULLDOWN, NRF_GPIO_PIN_SENSE_HIGH);

  // Trigger System OFF

  NRF_POWER->SYSTEMOFF = 1;

}

// -------------------- Interrupts ------------------------- //

void setupDoubleTapInterrupt() {

  uint8_t error = 0;

  uint8_t dataToWrite = 0;

  // Double Tap Config

  myIMU.writeRegister(LSM6DS3_ACC_GYRO_CTRL1_XL, 0x60); //* Acc = 416Hz (High-Performance mode)// Turn on the accelerometer

  myIMU.writeRegister(LSM6DS3_ACC_GYRO_TAP_CFG1, 0x8E);// INTERRUPTS_ENABLE, SLOPE_FDS// Enable interrupts and tap detection on X, Y, Z-axis

  myIMU.writeRegister(LSM6DS3_ACC_GYRO_TAP_THS_6D, 0x85);// Set tap threshold 8C

  myIMU.writeRegister(LSM6DS3_ACC_GYRO_INT_DUR2, 0x7F);// Set Duration, Quiet and Shock time windows 7F

  myIMU.writeRegister(LSM6DS3_ACC_GYRO_WAKE_UP_THS, 0x80);// Single & double-tap enabled (SINGLE_DOUBLE_TAP = 1)

  myIMU.writeRegister(LSM6DS3_ACC_GYRO_MD1_CFG, 0x08);// Double-tap interrupt driven to INT1 pin

}

void int1ISR()

{

  interruptCount++;

 ;

}

// -------------------- Utilities ------------------------- //

void setLedRGB(bool red, bool green, bool blue) {

  if (!blue) { digitalWrite(LEDB, HIGH); } else { digitalWrite(LEDB, LOW); }

  if (!green) { digitalWrite(LEDG, HIGH); } else { digitalWrite(LEDG, LOW); }

  if (!red) { digitalWrite(LEDR, HIGH); } else { digitalWrite(LEDR, LOW); }

}
1 Like