Swim-It, is a waterproof counter for arm movement

Dependencies:   Hexi_KW40Z Hexi_OLED_SSD1351

Fork of Hexi_BLE_Example by Hexiwear

main.cpp

Committer:
fyaocn
Date:
2016-10-09
Revision:
3:f9d351e32e78
Parent:
1:a0d9eeedb771

File content as of revision 3:f9d351e32e78:

//This file is based on example of Hexi_Accelero_Magnet and Hexi_BLE_Example, logic of swim it is added as core lines for arm stroke counting in 
#include "mbed.h"
#include "Hexi_KW40Z.h"
#include "Hexi_OLED_SSD1351.h"
#include "./FXOS8700/FXOS8700.h"
#include "OLED_types.h"
#include "OpenSans_Font.h"
#include "string.h"

#define LED_ON      0
#define LED_OFF     1

#define MAG_THREHOLD        0.5
#define ACCEL_THREHOLD      0.5
   
Timeout swimit_reset;
static uint16_t swimit_count;
   
void StartHaptic(void);
void StopHaptic(void const *n);
void txTask(void);
void swimit_reseter(void);

DigitalOut redLed(LED1,1);
DigitalOut greenLed(LED2,1);
DigitalOut blueLed(LED3,1);
DigitalOut haptic(PTB9);

// Pin connections & address for Hexiwear
FXOS8700 accel(PTC11, PTC10);
FXOS8700 mag(PTC11, PTC10);

/* Define timer for haptic feedback */
RtosTimer hapticTimer(StopHaptic, osTimerOnce);

/* Instantiate the Hexi KW40Z Driver (UART TX, UART RX) */ 
KW40Z kw40z_device(PTE24, PTE25);

/* Instantiate the SSD1351 OLED Driver */ 
SSD1351 oled(PTB22,PTB21,PTC13,PTB20,PTE6, PTD15); /* (MOSI,SCLK,POWER,CS,RST,DC) */

/*Create a Thread to handle sending BLE Sensor Data */ 
Thread txThread;

 /* Text Buffer */ 
char text[20]; 



/****************************Call Back Functions*******************************/
void ButtonRight(void)
{
    StartHaptic();
    kw40z_device.ToggleAdvertisementMode();
}

void ButtonLeft(void)
{
    StartHaptic();
    kw40z_device.ToggleAdvertisementMode();
}

void PassKey(void)
{
    StartHaptic();
    strcpy((char *) text,"PAIR CODE");
    oled.TextBox((uint8_t *)text,0,25,95,18);
  
    /* Display Bond Pass Key in a 95px by 18px textbox at x=0,y=40 */
    sprintf(text,"%d", kw40z_device.GetPassKey());
    oled.TextBox((uint8_t *)text,0,40,95,18);
}

/***********************End of Call Back Functions*****************************/

/********************************Main******************************************/

int main()
{    
    // Configure Accelerometer FXOS8700, Magnetometer FXOS8700
    accel.accel_config();
    mag.mag_config();


        
    /* Get OLED Class Default Text Properties */
    oled_text_properties_t textProperties = {0};
    oled.GetTextProperties(&textProperties);    

    /* Turn on the backlight of the OLED Display */
    oled.DimScreenON();
    
    /* Fills the screen with solid black */         
    oled.FillScreen(COLOR_BLACK);
        
    /* Register callbacks to application functions */
    kw40z_device.attach_buttonLeft(&ButtonLeft);
    kw40z_device.attach_buttonRight(&ButtonRight);
    kw40z_device.attach_passkey(&PassKey);

    /* Change font color to Blue */ 
    textProperties.fontColor   = COLOR_BLUE;
    oled.SetTextProperties(&textProperties);
    
    /* Display Bluetooth Label at x=17,y=65 */ 
    strcpy((char *) text,"BLUETOOTH");
    oled.Label((uint8_t *)text,17,65);
    
    /* Change font color to white */ 
    textProperties.fontColor   = COLOR_WHITE;
    textProperties.alignParam = OLED_TEXT_ALIGN_CENTER;
    oled.SetTextProperties(&textProperties);
    
    /* Display Label at x=22,y=80 */ 
    strcpy((char *) text,"Tap Below");
    oled.Label((uint8_t *)text,22,80);
         
    uint8_t prevLinkState = 0; 
    uint8_t currLinkState = 0; 
    txThread.start(txTask); /*Start transmitting Sensor Tag Data */
    
    while (true) 
    {
        blueLed = !kw40z_device.GetAdvertisementMode(); /*Indicate BLE Advertisment Mode*/   
        Thread::wait(50);
        
    }
}

/******************************End of Main*************************************/


/* txTask() transmits the sensor data */
void txTask(void){

    float accel_data[3];
    float accel_rms=0.0;
    float mag_data[3];   
    float mag_rms=0.0;   
    uint16_t steps=0;
    float accel_rms_ave=accel_rms;
    
   while (true) 
   {

 
    
        /*acquire accel_data and mag_data, running Sensor Tag mode*/
      accel.acquire_accel_data_g(accel_data);
      accel_rms = sqrt(((accel_data[0]*accel_data[0])+(accel_data[1]*accel_data[1])+(accel_data[2]*accel_data[2]))/3);
      Thread::wait(0.01);
      
      mag.acquire_mag_data_uT(mag_data);
      mag_rms = sqrt(((mag_data[0]*mag_data[0])+(mag_data[1]*mag_data[1])+(mag_data[2]*mag_data[2]))/3);
      Thread::wait(0.01);
    
        //rm Strok counting by change of MAG and ACCEL at the same time, 
      if (accel_rms>ACCEL_THREHOLD ||mag_rms>MAG_THREHOLD)   swimit_count++;
      steps = swimit_count;
      accel_rms_ave=accel_rms;

      
      // Reset the step after 60 second without any movement;
      if (abs(accel_rms_ave-accel_rms)<0.1)    swimit_reset.attach(&swimit_reseter, 60.0);


        /*Notify Hexiwear App that it is running Sensor Tag mode*/
        kw40z_device.SendSetApplicationMode(GUI_CURRENT_APP_SENSOR_TAG);
                

              
        /*The following is sending Mag,Accel,Gyro Data over BLE.*/
    
        kw40z_device.SendAccel(accel_data[0],accel_data[1],accel_data[2]); 
        kw40z_device.SendSteps(steps);  
        Thread::wait(10);                 
    }
}

void StartHaptic(void)  {
    hapticTimer.start(50);
    haptic = 1;
}

void StopHaptic(void const *n) {
    haptic = 0;
    hapticTimer.stop();
}

void swimit_reseter() {
swimit_count=0;
}