The Hiking Pal tracking device firmware. See full description on the detail page: https://www.hackster.io/bowenfeng/hiking-pal-v1-07c02d

Dependencies:   FXOS8700CQ MODSERIAL mbed

Fork of Avnet_ATT_Cellular_IOT by Avnet

main.cpp

Committer:
bowenfeng
Date:
2016-12-22
Revision:
87:ca75c5e785a7
Parent:
86:5ff234988f53

File content as of revision 87:ca75c5e785a7:

/* ===================================================================
Copyright © 2016, AVNET Inc.  

Licensed under the Apache License, Version 2.0 (the "License"); 
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, 
software distributed under the License is distributed on an 
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
either express or implied. See the License for the specific 
language governing permissions and limitations under the License.

======================================================================== */

#include "mbed.h" 
#include <cctype>
#include <string>
#include "config_me.h"
#include "sensors.h"
#include "cell_modem.h"
#include "hardware.h"

I2C i2c(PTC11, PTC10);    //SDA, SCL -- define the I2C pins being used
MODSERIAL pc(USBTX, USBRX, 256, 256); // tx, rx with default tx, rx buffer sizes
MODSERIAL mdm(PTD3, PTD2, 4096, 4096);
DigitalOut led_green(LED_GREEN);
DigitalOut led_red(LED_RED);
DigitalOut led_blue(LED_BLUE);

#define OK_COLOR 0x2
#define ERROR_COLOR 0x1


//********************************************************************************************************************************************
//* Create string with sensor readings that can be sent to flow as an HTTP get
//********************************************************************************************************************************************
K64F_Sensors_t  SENSOR_DATA = {
    .Temperature        = "0",
    .Humidity           = "0",
    .AccelX             = "0",
    .AccelY             = "0",
    .AccelZ             = "0",
    .MagnetometerX      = "0",
    .MagnetometerY      = "0",
    .MagnetometerZ      = "0",
    .AmbientLightVis    = "0",
    .AmbientLightIr     = "0",
    .UVindex            = "0",
    .Proximity          = "0",
    .Temperature_Si7020 = "0",
    .Humidity_Si7020    = "0",
    .Virtual_Sensor1    = "0",
    .Virtual_Sensor2    = "0",
    .Virtual_Sensor3    = "0",
    .Virtual_Sensor4    = "0",
    .Virtual_Sensor5    = "0",
    .Virtual_Sensor6    = "0",
    .Virtual_Sensor7    = "0",
    .Virtual_Sensor8    = "0",
    .GPS_Satellites     = "0",
    .GPS_Latitude       = "0",
    .GPS_Longitude      = "0",
    .GPS_Altitude       = "0",
    .GPS_Speed          = "0",
    .GPS_Course         = "0"
};

char hid[20] = {0};
char sid[20] = {0};
char sessionName[20] = {0};

void display_app_firmware_version(void) {
    PUTS("\r\n\r\nHiking Pal Firmware: Release 1.0 - built: "__DATE__" "__TIME__"\r\n\r\n");
}

//Periodic timer
Ticker OneMsTicker;
volatile bool bTimerExpiredFlag = false;
int OneMsTicks = 0;
int iTimer1Interval_ms = 1000;
//********************************************************************************************************************************************
//* Periodic 1ms timer tick
//********************************************************************************************************************************************
void OneMsFunction() {
    OneMsTicks++;
    if ((OneMsTicks % iTimer1Interval_ms) == 0) {
        bTimerExpiredFlag = true;
    }            
} //OneMsFunction()

//********************************************************************************************************************************************
//* Set the RGB LED's Color
//* LED Color 0=Off to 7=White.  3 bits represent BGR (bit0=Red, bit1=Green, bit2=Blue) 
//********************************************************************************************************************************************
void SetLedColor(unsigned char ucColor) {
    //Note that when an LED is on, you write a 0 to it:
    led_red = !(ucColor & 0x1); //bit 0
    led_green = !(ucColor & 0x2); //bit 1
    led_blue = !(ucColor & 0x4); //bit 2
} //SetLedColor()

void extract_longlong(const char* s, char v[]) {
    long long value = strtoll(s, NULL, 0);
    sprintf(v, "%lld", value);
}

long long find_longlong(const char* s, const char* token, const char** end) {
    const char* tokenBegin = strstr(s, token);
    if (tokenBegin != 0) {
        *end = tokenBegin + strlen(token);
        return strtoll(tokenBegin + strlen(token), NULL, 0);
    }
    return 0;
}

void find_longlong(const char* s, const char* token, char v[]) {
    const char* tokenBegin = strstr(s, token);
    if (tokenBegin != 0) {
        extract_longlong(tokenBegin + strlen(token), v);
    }
}


int send_receive(char* request, char* response) {
    int result = cell_modem_Sendreceive(request, response);
    SetLedColor(result ? OK_COLOR : ERROR_COLOR);
    return result;
}

int send_only(char* request) {
    char response[512];
    return send_receive(request, response);
}

void find_latest_hiking(char hikingId[]) {
    char request[512];
    char response[512];
    sprintf(request, "GET %s/hikings HTTP/1.1\r\nHost: %s\r\n\r\n", FLOW_BASE_URL, MY_SERVER_URL);
    if (send_receive(&request[0], &response[0])) {
        long long llv;
        long long latestId = 0;
        const char* begin = response;
        PRINTF("%s\n\n", begin);
        
        char token[] = "\"id\":";
        for (;;) {
            llv = find_longlong(begin, token, &begin);
            
            PRINTF("---> %lld\n", llv);
            PRINTF("%s\n", begin);
            
            if (llv == 0) {
                break;
            }
            if (llv > latestId) {
                latestId = llv;
            }
        }
        sprintf(hikingId, "%lld", latestId);
        PRINTF("LATEST HIKING ID: %lld", latestId);
    }
}

void join_hiking(const char* hikingId, const char* name, char sessionId[]) {
    char request[512];
    char response[512];
    sprintf(request, "GET %s/hikings/%s/sessions?name=%s HTTP/1.1\r\nHost: %s\r\n\r\n", FLOW_BASE_URL, hikingId, name, MY_SERVER_URL);
    if (send_receive(&request[0], &response[0])) {
        find_longlong(response, "\"id\":", sessionId);
    }
}

void generate_move_request(char request[], const char* hid, const char* sid) {
    sprintf(
        request,
        "GET %s/hikings/%s/sessions/%s/moves?lat=%s&lng=%s HTTP/1.1\r\nHost: %s\r\n\r\n",
        FLOW_BASE_URL,
        hid,
        sid,
        SENSOR_DATA.GPS_Latitude,
        SENSOR_DATA.GPS_Longitude,
        MY_SERVER_URL);
}
void report_move(const char* hid, const char* sid) {
    char request[512];
    generate_move_request(request, hid, sid);
    send_only(&request[0]);
}

int main() {
    //delay so that the debug terminal can open after power-on reset:
    wait (5.0);
    pc.baud(115200);
    
    display_app_firmware_version();
    
    PRINTF(GRN "Hiking Pal tracking device started!\r\n\r\n");

    //Initialize the I2C sensors that are present
    sensors_init();
    read_sensors();

    // Set LED to RED until init finishes
    SetLedColor(0x1); //Red
    // Initialize the modem
    PRINTF("\r\n");
    cell_modem_init();
    display_wnc_firmware_rev();

    // Set LED BLUE for partial init
    SetLedColor(0x4); //Blue

    //Create a 1ms timer tick function:
    iTimer1Interval_ms = SENSOR_UPDATE_INTERVAL_MS;
    OneMsTicker.attach(OneMsFunction, 0.001f) ;
    
    sprintf(sessionName, "IoT-kit-%d", rand() % 1000);
    
    find_latest_hiking(hid);
    PRINTF("Found Hiking ID: ");
    PRINTF(hid);
    PRINTF("\r\n");
    
    join_hiking(hid, sessionName, sid);
    PRINTF("Allocated Session ID: ");
    PRINTF(sid);
    PRINTF("\r\n");

    // Send and receive data perpetually
    while(1) {
        if (bTimerExpiredFlag) {
            bTimerExpiredFlag = false;
            read_sensors(); //read available external sensors from a PMOD and the on-board motion sensor
            report_move(hid, sid);
        }
    } //forever loop
}