Xiao Sense Accelerometer Examples and Low Power

Hi,
I used non-mbed boards and was able to get this BLE foot step tracker (located on your foot) to work. I tested it and in deep sleep mode it uses 48 microamps and ~3 milliamps when awake. It wakes up with double tap. It runs on a rechargeable Lithium CR2020 battery. It works perfectly at first but, after sleeping for a few days it wont wake up again and I don’t know why. Hope this helps, and if you can figure out why it won’t wake up again please let me know.

PS sorry the code is not very pretty…

////##############################################################################
////#Seeed nRF52 Boards ----- !!!!!!!!!  ONLY VERSION 1.1.5 WORKS  !!!!!!!!!
/////https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json
////##############################################################################
//#include <Adafruit_SPIFlash.h>
#include <LSM6DS3.h>
#include <nrf52840.h>
#include <Wire.h>

#include <bluefruit.h>
#include <Adafruit_LittleFS.h>
#include <InternalFileSystem.h>

LSM6DS3 myIMU(I2C_MODE, 0x6A);  //I2C device address 0x6A


long previousMillisSLEEP = 0;  // last time steps checked level was checked, in ms
long currentMillisSLEEP = 0;

long previousMillisSTEPS = 0;

long previousSteps = 0;
long cadence = 0;
long previouscadence = 0;

long stopcount = 0;

long stepONE = 0;
long stepTWO = 0;
long stepTHREE = 0;
long stepFOUR = 0;
long stepFIVE = 0;
long stepSIX = 0;
long stepSEVEN = 0;
long stepEIGHT = 0;

long intervalONE = 0;
long intervalTWO = 0;
long intervalTHREE = 0;
long intervalFOUR = 0;
long intervalFIVE = 0;
long intervalSIX = 0;
long intervalSEVEN = 0;
long intervalEIGHT = 0;


float accX, accY, accZ, gX, gY, gZ;
const float accelerationThreshold = 26;  // threshold of significant in G's
int stepsTaken = 0;
int stepCount = 0;
int STOPcount = 0;
bool STEP = false;
bool UPDATED = false;
int updateClearCount = 0;
long currentMillisSTEPS = 0;
long changeInMilllisSTEPS = 0;
long previousMilllisFOOTONGROUND = 0;
long changeInMilllisFOOTONGROUND = 0;
long STARTMilllisSWING = 0;
long ENDMilllisSWING = 0;
long changeMilllisSWING = 0;

int stepcountforcadenceaverage = 0;
int totalcandenceforaverage = 0;

bool stepup = false;
bool topofstep = false;
bool xbool = false;
bool ybool = false;
bool zbool = false;
int countdetect = 0;
long totalmagnitude = 0;
int swingcount = 0;

const int SMOOTHING_WINDOW_SIZE = 80; // 25 samples

int _samples[SMOOTHING_WINDOW_SIZE];  // the readings from the analog input
int _curReadIndex = 0;                // the index of the current reading
int _sampleTotal = 0;                 // the running total
int _sampleAvg = 0;                   // the average

bool CONNECTEDtoble = false;

/* HRM Service Definitions
 * Heart Rate Monitor Service:  0x180D
 * Heart Rate Measurement Char: 0x2A37
 * Body Sensor Location Char:   0x2A38
 */
BLEService        hrms = BLEService(UUID16_SVC_HEART_RATE);
BLECharacteristic hrmc = BLECharacteristic(UUID16_CHR_HEART_RATE_MEASUREMENT);
BLECharacteristic bslc = BLECharacteristic(UUID16_CHR_BODY_SENSOR_LOCATION);
BLEService        RSC  = BLEService("1814");
BLECharacteristic RSCcharac = BLECharacteristic("2A53");

                 // remote clients will be able to get notifications if this characteristic changes

BLEDis bledis;    // DIS (Device Information Service) helper class instance
BLEBas blebas;    // BAS (Battery Service) helper class instance

uint8_t  bps = 0;



//Adafruit_FlashTransport_QSPI flashTransport;
//LSM6DS3 myIMU; // Default is I2C mode
//Create a instance of class LSM6DS3



// void QSPIF_sleep(void)
// {
//   flashTransport.begin();
//   flashTransport.runCommand(0xB9);
//   flashTransport.end();
// }

void setupWakeUpInterrupt()
{
  // Start with LSM6DS3 in disabled to save power
  myIMU.settings.gyroEnabled = 0;
  myIMU.settings.accelEnabled = 0;

  myIMU.begin();

  /* Values from the application note */
/*
  myIMU.writeRegister(LSM6DS3_ACC_GYRO_CTRL1_XL, 0x60);    // Turn on the accelerometer
                                                           // ODR_XL = 416 Hz, FS_XL = ±2 g
  myIMU.writeRegister(LSM6DS3_ACC_GYRO_TAP_CFG1, 0x8E);    // Enable interrupts and tap detection on X, Y, Z-axis
  myIMU.writeRegister(LSM6DS3_ACC_GYRO_TAP_THS_6D, 0x8C);  // Set tap threshold
  myIMU.writeRegister(LSM6DS3_ACC_GYRO_INT_DUR2, 0x7F);    // Set Duration, Quiet and Shock time windows
  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
*/

 /* Values that use the highest low power setting (52Hz) with resulting physical tap detection parameters that are
  * close as possible to the application note values.
  */
  
  myIMU.writeRegister(LSM6DS3_ACC_GYRO_CTRL1_XL, 0x30);    // Turn on the accelerometer
                                                           // ODR_XL = 52 Hz, FS_XL = ±2 g
  myIMU.writeRegister(LSM6DS3_ACC_GYRO_TAP_CFG1, 0x8E);    // Enable interrupts and tap detection on X, Y, Z-axis
  myIMU.writeRegister(LSM6DS3_ACC_GYRO_TAP_THS_6D, 0x8C);  // Set tap threshold
  myIMU.writeRegister(LSM6DS3_ACC_GYRO_INT_DUR2, 0x10);    // Set Duration, Quiet and Shock time windows
  myIMU.writeRegister(LSM6DS3_ACC_GYRO_WAKE_UP_THS, 0x80); // Single & double-tap enabled (SINGLE_DOUBLE_TAP = 1)
  myIMU.writeRegister(LSM6DS3_ACC_GYRO_CTRL6_G, 0x10);     // High-performance operating mode disabled for accelerometer
  myIMU.writeRegister(LSM6DS3_ACC_GYRO_MD1_CFG, 0x08);     // Double-tap interrupt driven to INT1 pin

  // Set up the sense mechanism to generate the DETECT signal to wake from system_off
  // No need to attach a handler, if just waking with the GPIO input.
  pinMode(PIN_LSM6DS3TR_C_INT1, INPUT_PULLDOWN_SENSE);

  return;
}

void setup()
{
  pinMode(LED_RED, OUTPUT);
  pinMode(LED_GREEN, OUTPUT);
  
  digitalWrite(LED_RED, LOW);
  digitalWrite(LED_GREEN, HIGH);

  // //QSPIF_sleep();
      // if (myIMU.begin() != 0) {
      //  Serial.println("Device error");
      // } else {
      //  Serial.println("aX,aY,aZ,gX,gY,gZ");
      // }

  ////////////////////////////////////////////////////////////////////
  //RED LIGHT TURNS ON WHEN THE DEVICE IS ON
  ////////////////////////////////////////////////////////////////////

  // Flash green to see power on, reset, and wake from system_off
  //digitalWrite(LED_RED, LOW);
  //delay(1000);
  //digitalWrite(LED_GREEN, HIGH);;

  // Minimizes power when bluetooth is used
  NRF_POWER->DCDCEN = 1;
  NRF_POWER->TASKS_LOWPWR = 1;
  uint32_t dcdcen = NRF_POWER->DCDCEN;
  // Enter LOWPWR mode (LOWPWR is recommended for most applications)
  //NRF_POWER->TASKS_LOWPWR = 1;
  

// Initialise the Bluefruit module
  //Serial.println("Initialise the Bluefruit nRF52 module");
  Bluefruit.begin();


  Bluefruit.setName("RUNSTREAM002");





  // Set the connect/disconnect callback handlers
  Bluefruit.Periph.setConnectCallback(connect_callback);
  Bluefruit.Periph.setDisconnectCallback(disconnect_callback);

  ///////////////////// Configure and Start the Device Information Service
  //Serial.println("Configuring the Device Information Service");
  //bledis.setManufacturer("Cyborg Syndicate, LLC");
  //bledis.setModel("RUNSTREAM Footpod");

  //bledis.begin();

  // Start the BLE Battery Service and set it to 100%
  //Serial.println("Configuring the Battery Service");
  blebas.begin();

  //const int VOL_PIN = A0;

  //enable battery measuring
  //pinMode(VBAT_ENABLE, OUTPUT);
//  pinMode(A6, INPUT);
////  int battery = analogRead(A6);
  //int batteryLevel = map(battery, 0, 1023, 0, 100);
  //int value = analogRead( VOL_PIN );
  //int volt = value * 3.3 / 1023.0;


    // Battery Level setup
  //pinMode(P0_31, OUTPUT);
  //digitalWrite(P0_31, LOW);
  //pinMode(VBAT_ENABLE, OUTPUT);
  pinMode(PIN_VBAT, INPUT);
  digitalWrite(PIN_VBAT, LOW);
  const double vRef = 3.3; // Assumes 3.3V regulator output is ADC reference voltage
  const unsigned int numReadings = 1024; // 10-bit ADC readings 0-1023, so the factor is 1024
  unsigned int adcCount = analogRead(PIN_VBAT);
  double adcVoltage = (adcCount * vRef) / numReadings;
  double vBat = adcVoltage*1510.0/510.0; // Voltage divider from Vbat to ADC
  double batlife = (adcVoltage/3.3)*100;

  //printf("adcCount = %3u = 0x%03X, adcVoltage = %.3fV, vBat = %.3f\n",
  //           adcCount, adcCount, adcVoltage, vBat);
  //int Vadc = analogRead(VBAT_ENABLE);

  //float batteryLevel = ((510e3 + 1000e3) / 510e3) * 2.4 * Vadc / 4096;

   //digitalWrite(VBAT_ENABLE, LOW);
  blebas.write(batlife);

  // Setup the Heart Rate Monitor service using
  // BLEService and BLECharacteristic classes
  //Serial.println("Configuring the Heart Rate Monitor Service");
  //setupHRM();

  setupRSC();


  // Setup the advertising packet(s)
  //Serial.println("Setting up the advertising payload(s)");
  startAdv();

  //Serial.println("Ready Player One!!!");
  //Serial.println("\nAdvertising");
}



void startAdv(void)
{
  // Advertising packet
  Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
  Bluefruit.Advertising.addTxPower();
  Bluefruit.autoConnLed(false);
  //digitalWrite(LED_RED, LOW);


  // Include HRM Service UUID
  //Bluefruit.Advertising.addService(hrms);


  Bluefruit.Advertising.addService(RSC);



  // Include Name
  Bluefruit.Advertising.addName();
  
  /* Start Advertising
   * - Enable auto advertising if disconnected
   * - Interval:  fast mode = 20 ms, slow mode = 152.5 ms
   * - Timeout for fast mode is 30 seconds
   * - Start(timeout) with timeout = 0 will advertise forever (until connected)
   * 
   * For recommended advertising interval
   * https://developer.apple.com/library/content/qa/qa1931/_index.html   
   */
  Bluefruit.Advertising.restartOnDisconnect(true);
  Bluefruit.Advertising.setInterval(32, 244);    // in unit of 0.625 ms
  Bluefruit.Advertising.setFastTimeout(30);      // number of seconds in fast mode
  Bluefruit.Advertising.start(0);                // 0 = Don't stop advertising after n seconds  
}




void loop()
{
      //Serial.println("main loop looping");

  // FreeRTOS will automatically put the system in system_on sleep mode here
  //delay(180000); // Measure idle loop power during this period

  
  //ALL LIGHTS TURN OFF JUST BEFORE DEVICE GOES TO SLEEP
  // Flash red before system_off sleep
  // digitalWrite(LED_RED, LOW);
  // delay(1000);
  // digitalWrite(LED_RED, HIGH);


  if(CONNECTEDtoble == true){

  //if ( Bluefruit.connected() ) {
    // pinMode(PIN_VBAT, INPUT);
    // digitalWrite(PIN_VBAT, LOW);
    // const double vRef = 3.3; // Assumes 3.3V regulator output is ADC reference voltage
    // const unsigned int numReadings = 1024; // 10-bit ADC readings 0-1023, so the factor is 1024
    // unsigned int adcCount = analogRead(PIN_VBAT);
    // double adcVoltage = (adcCount * vRef) / numReadings;
    // double vBat = adcVoltage*1510.0/510.0; // Voltage divider from Vbat to ADC
    // double batlife = (adcVoltage/3.3)*100;
    // printf("adcCount = %3u = 0x%03X, adcVoltage = %.3fV, vBat = %.3f, balife = %.1f\n",
    //          adcCount, adcCount, adcVoltage, vBat, batlife);
    // Serial.println(" connected ");

    //uint8_t hrmdata[2] = { 0b00000110, bps++ };           // Sensor connected, increment BPS value
    
    //CONNECTEDtoble = true;
    // Note: We use .notify instead of .write!
    // If it is connected but CCCD is not enabled
    // The characteristic's value is still updated although notification is not sent
    // if ( hrmc.notify(hrmdata, sizeof(hrmdata)) ){
    //   Serial.print("Heart Rate Measurement updated to: "); Serial.println(bps); 
    // }else{
    //   Serial.println("ERROR: Notify not set in the CCCD or not connected!");
    // }

    //reset sleep timer
    previousMillisSLEEP = currentMillisSLEEP;




    /////////////////////

      accX = myIMU.readFloatAccelX();
      accY = myIMU.readFloatAccelY();
      accZ = myIMU.readFloatAccelZ();
      gX = myIMU.readFloatGyroX();
      gY = myIMU.readFloatGyroY();
      gZ = myIMU.readFloatGyroZ();

      long magnitudeAcc = ((accX * accX) * (accY * accY) * (accZ * accZ));
      long magnitudeGyro = ((gX * gX) * (gY * gY) * (gZ * gZ));

      countdetect++;
     /*
      Serial.print(accX);
      Serial.print(" ");
      Serial.print(accY);
      Serial.print(" ");   
      Serial.print(accZ);
      Serial.print(" ");
      Serial.print(gX);
      Serial.print(" ");
      Serial.print(gY);
      Serial.print(" ");
      Serial.print(gZ);
      Serial.print(" ");
      Serial.print(magnitudeAcc);
      Serial.print(" ");
      Serial.print(magnitudeGyro);
      Serial.print(" ");
      Serial.print(_sampleAvg);
      Serial.println(" ");
     */
       // subtract the last reading:
       _sampleTotal = _sampleTotal - _samples[_curReadIndex];
  
       // read the sensor value
       _samples[_curReadIndex] = gY;
  
       // add the reading to the total:
       _sampleTotal = _sampleTotal + _samples[_curReadIndex];
  
       // advance to the next position in the array:
       _curReadIndex = _curReadIndex + 1;

      // if we're at the end of the array...
      if (_curReadIndex >= SMOOTHING_WINDOW_SIZE) {
          // ...wrap around to the beginning:
           _curReadIndex = 0;
      }

       // calculate the average:
      _sampleAvg = _sampleTotal / SMOOTHING_WINDOW_SIZE;
  

            if (xbool == false && _sampleAvg < -170   ) {
              xbool = true;

            } else if (xbool == true && _sampleAvg > -170   ) {
              xbool=false;
              currentMillisSTEPS = millis();
              changeInMilllisSTEPS = currentMillisSTEPS - previousMillisSTEPS;
              updateSteps();
              previousMillisSTEPS = currentMillisSTEPS;
              //Serial.print("A SIGNIFICANT EVENT*******!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
            }


            currentMillisSTEPS = millis();
            changeInMilllisSTEPS = currentMillisSTEPS - previousMillisSTEPS;

  



      if (changeInMilllisSTEPS > 3000) {
        cadence = 0;
        displayData();
        previousMillisSTEPS = currentMillisSTEPS;
      }
  }//end if connected
 

  long currentMillisSLEEP = millis();

  // if 1800000ms (3 minutes) have passed, check the steps level:
  if ((currentMillisSLEEP - previousMillisSLEEP >= 60000) && CONNECTEDtoble==false) {

      goToPowerOff();
  }

  // Only send update once per second
  //delay(10);


}//end loop



void setupHRM(void)
{
  // Configure the Heart Rate Monitor service
  // See: https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.service.heart_rate.xml
  // Supported Characteristics:
  // Name                         UUID    Requirement Properties
  // ---------------------------- ------  ----------- ----------
  // Heart Rate Measurement       0x2A37  Mandatory   Notify
  // Body Sensor Location         0x2A38  Optional    Read
  // Heart Rate Control Point     0x2A39  Conditional Write       <-- Not used here
  hrms.begin();

  // Note: You must call .begin() on the BLEService before calling .begin() on
  // any characteristic(s) within that service definition.. Calling .begin() on
  // a BLECharacteristic will cause it to be added to the last BLEService that
  // was 'begin()'ed!

  // Configure the Heart Rate Measurement characteristic
  // See: https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.heart_rate_measurement.xml
  // Properties = Notify
  // Min Len    = 1
  // Max Len    = 8
  //    B0      = UINT8  - Flag (MANDATORY)
  //      b5:7  = Reserved
  //      b4    = RR-Internal (0 = Not present, 1 = Present)
  //      b3    = Energy expended status (0 = Not present, 1 = Present)
  //      b1:2  = Sensor contact status (0+1 = Not supported, 2 = Supported but contact not detected, 3 = Supported and detected)
  //      b0    = Value format (0 = UINT8, 1 = UINT16)
  //    B1      = UINT8  - 8-bit heart rate measurement value in BPM
  //    B2:3    = UINT16 - 16-bit heart rate measurement value in BPM
  //    B4:5    = UINT16 - Energy expended in joules
  //    B6:7    = UINT16 - RR Internal (1/1024 second resolution)
  hrmc.setProperties(CHR_PROPS_NOTIFY);
  hrmc.setPermission(SECMODE_OPEN, SECMODE_NO_ACCESS);
  hrmc.setFixedLen(2);
  //hrmc.setCccdWriteCallback(cccd_callback);  // Optionally capture CCCD updates
  hrmc.begin();
  uint8_t hrmdata[2] = { 0b00000110, 0x40 }; // Set the characteristic to use 8-bit values, with the sensor connected and detected
  hrmc.write(hrmdata, 2);

  // Configure the Body Sensor Location characteristic
  // See: https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.body_sensor_location.xml
  // Properties = Read
  // Min Len    = 1
  // Max Len    = 1
  //    B0      = UINT8 - Body Sensor Location
  //      0     = Other
  //      1     = Chest
  //      2     = Wrist
  //      3     = Finger
  //      4     = Hand
  //      5     = Ear Lobe
  //      6     = Foot
  //      7:255 = Reserved
  bslc.setProperties(CHR_PROPS_READ);
  bslc.setPermission(SECMODE_OPEN, SECMODE_NO_ACCESS);
  bslc.setFixedLen(1);
  bslc.begin();
  bslc.write8(2);    // Set the characteristic to 'Wrist' (2)
}


void setupRSC(void)
{
  // Configure the Heart Rate Monitor service
  // See: https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.service.heart_rate.xml
  // Supported Characteristics:
  // Name                         UUID    Requirement Properties
  // ---------------------------- ------  ----------- ----------
  // Heart Rate Measurement       0x2A37  Mandatory   Notify
  // Body Sensor Location         0x2A38  Optional    Read
  // Heart Rate Control Point     0x2A39  Conditional Write       <-- Not used here
  RSC.begin();

  // Note: You must call .begin() on the BLEService before calling .begin() on
  // any characteristic(s) within that service definition.. Calling .begin() on
  // a BLECharacteristic will cause it to be added to the last BLEService that
  // was 'begin()'ed!

  // Configure the Heart Rate Measurement characteristic
  // See: https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.heart_rate_measurement.xml
  // Properties = Notify
  // Min Len    = 1
  // Max Len    = 8
  //    B0      = UINT8  - Flag (MANDATORY)
  //      b5:7  = Reserved
  //      b4    = RR-Internal (0 = Not present, 1 = Present)
  //      b3    = Energy expended status (0 = Not present, 1 = Present)
  //      b1:2  = Sensor contact status (0+1 = Not supported, 2 = Supported but contact not detected, 3 = Supported and detected)
  //      b0    = Value format (0 = UINT8, 1 = UINT16)
  //    B1      = UINT8  - 8-bit heart rate measurement value in BPM
  //    B2:3    = UINT16 - 16-bit heart rate measurement value in BPM
  //    B4:5    = UINT16 - Energy expended in joules
  //    B6:7    = UINT16 - RR Internal (1/1024 second resolution)
  RSCcharac.setProperties(CHR_PROPS_NOTIFY);
  RSCcharac.setPermission(SECMODE_OPEN, SECMODE_NO_ACCESS);
  RSCcharac.setFixedLen(8);
  RSCcharac.setCccdWriteCallback(cccd_callback);  // Optionally capture CCCD updates
  RSCcharac.begin();
  // uint8_t hrmdata[2] = { 0b00000110, 0x40 }; // Set the characteristic to use 8-bit values, with the sensor connected and detected
  // RSCcharac.write(hrmdata, 2);

 

}

void connect_callback(uint16_t conn_handle)
{

  myIMU.begin();

  CONNECTEDtoble = true;
  // Get the reference to current connection
  BLEConnection* connection = Bluefruit.Connection(conn_handle);

  char central_name[32] = { 0 };
  connection->getPeerName(central_name, sizeof(central_name));

  //Serial.print("Connected to ");
  //Serial.println(central_name);

  digitalWrite(LED_GREEN, HIGH);
  digitalWrite(LED_RED, HIGH);
}
/**
 * Callback invoked when a connection is dropped
 * @param conn_handle connection where this event happens
 * @param reason is a BLE_HCI_STATUS_CODE which can be found in ble_hci.h
 */
void disconnect_callback(uint16_t conn_handle, uint8_t reason)
{
  myIMU.settings.gyroEnabled = 0;
  myIMU.settings.accelEnabled = 0;

  CONNECTEDtoble = false;
  (void) conn_handle;
  (void) reason;

  //Serial.print("Disconnected, reason = 0x"); Serial.println(reason, HEX);
  //Serial.println("Advertising!");

  //digitalWrite(LED_GREEN, HIGH);
  //digitalWrite(LED_RED, HIGH);
}

void cccd_callback(uint16_t conn_hdl, BLECharacteristic* chr, uint16_t cccd_value)
{
    // Display the raw request packet
    //Serial.print("CCCD Updated: ");
    //Serial.printBuffer(request->data, request->len);
    //Serial.print(cccd_value);
    //Serial.println("");

    // Check the characteristic this CCCD update is associated with in case
    // this handler is used for multiple CCCD records.
    if (chr->uuid == RSCcharac.uuid) {
        if (chr->notifyEnabled(conn_hdl)) {
            //Serial.println("Heart Rate Measurement 'Notify' enabled");
        } else {
            //Serial.println("Heart Rate Measurement 'Notify' disabled");
        }
    }
}

//https://gitlab.utu.fi/tujupan/DTEK8081_source_codes/-/blob/15585c783735d98663ada2352cd9dc0f8c61e880/examples/ble_peripheral/ble_app_rscs/main.c
void updateSteps() {
  //     bool        is_inst_stride_len_present;                                 /**< True if Instantaneous Stride Length is present in the measurement. */
  //     bool        is_total_distance_present;                                  /**< True if Total Distance is present in the measurement. */
  //     bool        is_running;                                                 /**< True if running, False if walking. */
  //     uint16_t    inst_speed;                                                 /**< Instantaneous Speed. */
  //     uint8_t     inst_cadence;                                               /**< Instantaneous Cadence. */
  //     uint16_t    inst_stride_length;                                         /**< Instantaneous Stride Length. */
  //     uint32_t    total_distance;







  if (UPDATED == false) {
    UPDATED = true;
    cadence = 60000 / changeInMilllisSTEPS;

    if(cadence>(previouscadence*2) && previouscadence>10){
      //do nothing
    }else{


              if(stepcountforcadenceaverage >= 3)
              {
                cadence = totalcandenceforaverage/stepcountforcadenceaverage;
                stepcountforcadenceaverage = 0;
                totalcandenceforaverage = 0;
                displayData();

              }
              else
              {
                stepcountforcadenceaverage = stepcountforcadenceaverage+1;
                totalcandenceforaverage = totalcandenceforaverage +cadence;    
              }





        previouscadence=cadence;
        //Serial.print("steps taken: ");
        //Serial.println(stepsTaken);
        //Serial.print("delta time: ");
        //Serial.println(changeInMilllisSTEPS);
    }

  }




  if (UPDATED == true) {
    delay(100);
    UPDATED = false;
  }
}

void displayData() {



  int running;
  if (cadence > 70) {
    running = 3;
  } else if (cadence > 60) {
    running = 2;
  } else if (cadence > 0) {
    running = 1;
  } else {
    running = 2;
  }
  //byte data[4] = {0, 0, 0, 0};
  //byte data[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
  //uint8_t data[8] = { 0b00000110, 0x40 }; // Set the characteristic to use 8-bit values, with the sensor connected and detected
  uint8_t data[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };

  //static uint8_t data[4] = {0, 0, 0, 0};
  data[0] = 3;  //location. of foot. pod
  //data[1] = 0; // lowByte(CurrentSpeed);
  data[2] = running;  //0 nothing 1=walk 2=running
  data[3] = cadence;  //step count
  //data[4] = 0;
  data[5] = 0;  //always 0
  //data[6] = 0;
  data[7] = stepCount / 10;

  //RSCchar.setValue(data, 4);
  //RSCchar->writeValue(data, 8);
  //RSCcharac.writeValue(data, 8);  //convert number to hex);  // and update the stepcount level characteristic
  //RSCchar.readValue(data,8); //convert number to hex);  // and update the stepcount level characteristic
  RSCcharac.notify(data, 8);  //convert number to hex);  // and update the stepcount level characteristic

  // RSCchar.setValue(data, 8);
  //  RSCchar.notify();
  //Serial.print("Cadence: ");
  //Serial.println(cadence);
}



void goToPowerOff() {
  Bluefruit.Advertising.stop();


  digitalWrite(LED_GREEN, HIGH);
  digitalWrite(LED_RED, HIGH);

  // Setup up double tap interrupt to wake back up
  setupWakeUpInterrupt();

  // Execution should not go beyond this
  NRF_POWER->SYSTEMOFF=1;

}


2 Likes