salesforce HeartRate monitor sample application. This application sends periodic heart rate values into salesforce.com via the mbed SalesforceInterface API.
Dependencies: BufferedSerial C12832 EthernetInterface GroveEarbudSensor Logger SalesforceInterface mbed-rtos mbed
Fork of df-2014-salesforce-hrm-k64f by
main.cpp
- Committer:
- ansond
- Date:
- 2014-09-24
- Revision:
- 1:a71236906eed
- Parent:
- 0:a298d18da239
- Child:
- 3:3a5fdfdabca3
File content as of revision 1:a71236906eed:
/* Copyright C2014 ARM, MIT License * * Author: Doug Anson (doug.anson@arm.com) * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software * and associated documentation files the "Software", to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, publish, distribute, * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or * substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "Definitions.h" // definitions including platform specifics... #include "ErrorHandler.h" // HRM sensor defines #define HRM_OFF 0 // earbud sensor is offline #define HRM_MIN 10 // min HRM #define HRM_MAX 250 // max HRM // include salesforce.com credentials #include "sf_creds.h" // our Serial port #include "BufferedSerial.h" BufferedSerial pc(USBTX, USBRX); #define LOG_CONSOLE(...) { pc.printf(__VA_ARGS__); } // mbed AppBoard Shield LCD C12832 lcd(D11, D13, D12, D7, D10); // Earbud InterruptIn earbud(D0); Timer t; // Ethernet #include "EthernetInterface.h" EthernetInterface ethernet; // HTTP #include "HTTPClient.h" HTTPClient http; // Salesforce.com Interface #include "SalesforceInterface.h" // Sensor Lat/Long #define SENSOR_LATITUDE "37.404120" #define SENSOR_LONGITUDE "-121.973195" // Salesforce.com Configuration/Tunables char *hrm_object_name = "HeartRate__c"; // custom object char *hrm_bpm_field_name = "bpm__c"; // heartrate field char *hrm_user_field_name = "Name"; // heartrate user char *hrm_counter_field_name = "count__c"; // heartrate counter char *hrm_latitude = "latitude__c"; // sensor latitude char *hrm_longitude = "longitude__c"; // sensor longitude char *hrm_user = "Doug Anson"; // whos heartrate is this? // main loop toggle bool do_loop = true; // # retries before we give up and exit int num_retries = MAX_TRIES; // heartrate values and iteration counter volatile int iteration_counter = 0; volatile int oldhrmCounter = HRM_MAX+1; volatile int hrmCounter = HRM_OFF; // Earbud sensor tunables #define NUM_SLOTS 11 // larger numbers give more fidelity but slow down the acquisition response rate volatile unsigned char counter = 0; volatile unsigned long temp[NUM_SLOTS]; volatile unsigned long sub = 0; volatile bool data_effect = true; const int max_heartpluse_duty = 2000; // Change to follow your system's request. System returns error if the duty overtrips by 2 seconds. (in MS) // Salesforce.com record ID DEFINE_SML_BUFFER(bpm_record_id); // initialize the array void arrayInit() { for(int i=0;i<(NUM_SLOTS-1);++i) temp[i]=0; temp[NUM_SLOTS-1] = t.read_ms(); } // summation function void sum() { if(data_effect) { int tmp = 60 * (NUM_SLOTS-1) * 1000; hrmCounter = tmp/(temp[NUM_SLOTS-1]-temp[0]); LOG_CONSOLE("Heart_rate_is: %d bpm\r\n",hrmCounter); } data_effect=1; //sign bit } // interrupt() function for earbud void interrupt() { temp[counter] = t.read_ms(); switch(counter) { case 0: sub=temp[counter]-temp[NUM_SLOTS-1]; break; default: sub=temp[counter]-temp[counter-1]; break; } if(sub > max_heartpluse_duty) { //set 2 seconds as max heart pluse duty data_effect=0;//sign bit counter=0; LOG_CONSOLE("Heart rate measure error. Restarting...\r\n"); arrayInit(); t.stop(); t.start(); } if (counter == (NUM_SLOTS-1) && data_effect) { counter=0; sum(); } else if(counter != (NUM_SLOTS-1) && data_effect) { counter++; } else { counter=0; data_effect=1; } } // Get the heartrate from the sensor int get_heartrate() { ++iteration_counter; return hrmCounter; } // Create the heart rate record in Salesforce.com void create_heartrate_record(ErrorHandler *logger,SalesforceInterface *sf) { // create a new record MbedJSONValue bpm_record; bpm_record[hrm_bpm_field_name] = (int)get_heartrate(); bpm_record[hrm_user_field_name] = hrm_user; bpm_record[hrm_counter_field_name] = (int)iteration_counter; bpm_record[hrm_latitude] = SENSOR_LATITUDE; bpm_record[hrm_longitude] = SENSOR_LONGITUDE; logger->log("ARM Salesforce HRM v%s\r\nCreate: new bpm record(%d): %d\r\nSending...",APP_VERSION,iteration_counter,hrmCounter); logger->logConsole("Initializing BPM record: %s",bpm_record.serialize().c_str()); // create the BPM record in salesforce.com MbedJSONValue response = sf->createRecord(hrm_object_name,bpm_record); // display the result char *result = (char *)response.serialize().c_str(); if (result != NULL && strlen(result) > 0 && strcmp(result,"null") != 0) { // save off the token if we succeeded logger->log("ARM Salesforce HRM v%s\r\nCreate: new bpm record(%d): %d\r\nSending...SUCCESS",APP_VERSION,iteration_counter,hrmCounter); logger->logConsole("Create: result: %s http_code = %d",result,sf->httpResponseCode()); RESET_SML_BUFFER(bpm_record_id); strcpy(bpm_record_id,(char *)response["id"].get<std::string>().c_str()); logger->turnLEDGreen(); } else { // failure logger->log("ARM Salesforce HRM v%s\r\nCreate: new bpm record(%d): %d\r\nSending...FAILED",APP_VERSION,iteration_counter,hrmCounter); logger->logConsole("Create: FAILED http_code=%d",sf->httpResponseCode()); logger->turnLEDRed(); do_loop = false; } } // Update the heart rate record in Salesforce.com void update_heartrate_record(ErrorHandler *logger,SalesforceInterface *sf) { logger->turnLEDOrange(); // update am existing record - assume "name" is the proper key for the record you wish to update... MbedJSONValue bpm_record; int bpm = get_heartrate(); bpm_record[hrm_bpm_field_name] = bpm; bpm_record[hrm_user_field_name] = hrm_user; bpm_record[hrm_counter_field_name] = (int)iteration_counter; bpm_record[hrm_latitude] = SENSOR_LATITUDE; bpm_record[hrm_longitude] = SENSOR_LONGITUDE; // DEBUG logger->log("ARM Salesforce HRM v%s\r\nUpdate HR(%d): %d bpm\r\nSending...",APP_VERSION,iteration_counter,bpm); logger->logConsole("Update: updated record: %s",bpm_record.serialize().c_str()); // update the BPM record in salesforce.com bool updated = sf->updateRecord(hrm_object_name,bpm_record_id,bpm_record); // display the result if (updated) { // SUCCESS logger->log("ARM Salesforce HRM v%s\r\nUpdate HR(%d): %d bpm\r\nSending...SUCCESS",APP_VERSION,iteration_counter,bpm); logger->logConsole("Update: successful! http_code=%d",sf->httpResponseCode()); logger->turnLEDGreen(); } else { if (num_retries > 0) { // retry state logger->turnLEDPurple(); // OAUTH token may have expired - reset and retry if (num_retries == MAX_TRIES) --iteration_counter; // one time only in retries... --num_retries; sf->resetSalesforceToken(); update_heartrate_record(logger,sf); } else { // failure logger->log("ARM Salesforce HRM v%s\r\nUpdate HR(%d): %d bpm\r\nSending...FAILED",APP_VERSION,iteration_counter,bpm); logger->logConsole("Update: FAILED http_code=%d",sf->httpResponseCode()); do_loop = false; // give-up state logger->turnLEDRed(); } } } // Report heart rate to Salesforce.com void report_heartrate(ErrorHandler *logger,SalesforceInterface *sf) { if (iteration_counter == 0) create_heartrate_record(logger,sf); else update_heartrate_record(logger,sf); } // Main Task... void mainTask(void const *v) { // create our object instances ErrorHandler logger(&pc,&lcd); SalesforceInterface *sf = NULL; // announce logger.log("\r\n\r\nARM Salesforce HRM v%s",APP_VERSION); logger.turnLEDBlue(); wait(1); // initialize Ethernet logger.log("Initializing Ethernet..."); ethernet.init(); // get a DHCP address and bring the network interface up logger.log("Getting IP Address..."); logger.turnLEDYellow(); if (ethernet.connect() == 0) { // log our IP address (DHCP) logger.log("IP Address: %s",ethernet.getIPAddress()); // allocate the Salesforce.com interface logger.logConsole("Allocating the Saleforce.com interface..."); sf = new SalesforceInterface(&logger,&http); // set our Salesforce.com credentials logger.logConsole("Setting credentials in the Salesforce.com interface..."); sf->setCredentials(username,password,client_id,client_secret); // initialize the earbud LOG_CONSOLE("Initializing Earbud...\r\n"); t.start(); arrayInit(); earbud.rise(&interrupt); hrmCounter = HRM_OFF; // enter main loop logger.logConsole("Beginning main event loop..."); while(do_loop) { report_heartrate(&logger,sf); Thread::wait(WAIT_TIME_MS); } // if we fell out of the loop exit... logger.log("Application Exiting..."); logger.turnLEDRed(); exit(1); } else { logger.log("No Network... Exiting..."); logger.turnLEDRed(); exit(1); } } // main entry int main() { Thread workerTask(mainTask, NULL, osPriorityNormal, STACK_SIZE); while (true) { Thread::wait(10*WAIT_TIME_MS); } }