whatever

Dependencies:   C027 C027_Support M2XStreamClient PowerControl jsonlite mbed-rtos mbed

Fork of PONY_Ph0-uAXIS by Sean McBeath

main.cpp

Committer:
sgmcb
Date:
2016-01-14
Revision:
50:bba466f093a4
Parent:
49:a8c40c816199
Child:
51:61a1ec3c56fc

File content as of revision 50:bba466f093a4:

#include "mbed.h"

//------------------------------------------------------------------------------------
// C027 Support Libraries
#include "GPS.h"
#include "MDM.h"

// Power control libraries
#include "PowerControl.h"
#include "EthernetPowerControl.h"


// M2X Support Libraries
#include <jsonlite.h>
#include "M2XStreamClient.h"

// PONY-specific config support libraries
#include "LIS331.h"
#include "PONY_Loc.h"       // PONY Location Code
#include "PONY_sense.h"

//----
// DEBUG DEFINITIONS
//#define THROWAWAY
//#define MDMDEBUG
#define LOCDEBUG

//------------------------------------------------------------------------------------
// Cellular modem/SIM parameters
#define SIMPIN      "1111"          //!SIMPIN is 1111 by default for AT&T SIMs.
#define APN         "m2m.com.attz"  // Defined AT&T M2M APN
#define USERNAME    NULL            //! Set the user name for your APN, or NULL if not needed (which, apparently, it isn't)
#define PASSWORD    NULL            //! Set the password for your APN, or NULL if not needed (which, apparently, it isn't)

//------------------------------------------------------------------------------------
// AT&T M2X Kekys


#ifdef THROWAWAY
// Codes for a throwaway M2X device
#define M2XAPIKEY "97f6f92f72b9dd1c66e9b81b982bc3ec"
#define DEVID "743fe2502be9d4d0c550ffa9340998a3"
#endif

#ifndef THROWAWAY
// v1.4 codes
#define M2XAPIKEY "537d09e921aa6589523e10aecde17a44"
#define DEVID "59a85c486aaf8dd427945320f4f779eb"
#endif


//------------------------------------------------------------------------------------
// PIN Config
DigitalOut led1(LED1);
DigitalOut led2(LED2);

AnalogIn   tempPin(P0_23);
//AnalogIn   tempGnd(P0_24);

//I2C axis(P0_0, P0_1);       // SDA, SCL
//LIS331 axle(P0_0, P0_1);        // Library object


//------------------------------------------------------------------------------------
// GLOBAL VARIABLES

Ticker flipper;

// M2X Drivers
Client client;
M2XStreamClient m2xClient(&client, M2XAPIKEY);
int M2X_response;   // For m2x message responses


char statusBuf[145] = "";

// Location reading
unsigned int kLocLoopDelayDef = 30 * 1000;         // The default loop waiting time for location reads
unsigned int kLocLoopDelay = kLocLoopDelayDef;


unsigned int kReadingDelay = 3 * 60 * 1000;         // How many seconds to wait between reads
unsigned int kReadingDelayClimb = 15000;    // How many seconds to add to the wait period when sitting idle
unsigned int kReadingDelayMax = 5 * 60000;  // What's the maximum time between readings?


// System time
time_t kSysSeconds = time(NULL);
time_t thisTime = time(NULL);
bool kSysClockSet = false;
tm kFormatTime;



// Global function definitions

void flip() {
    led1 = !led1;
}


//------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------
int main(void)
{
    
    printf("\r\n\n\n\n-----\r\nI'm alive - vers. uA - device codes PONY_v1.4\r\n\n");
    #ifdef THROWAWAY
    printf("Using THROWAWAY M2X device\r\n");
    #endif
    
    #ifndef THROWAWAY
    printf("Using PONY_v1.4 M2X device\r\n");
    #endif    
    
    // POWER MANAGEMENT
    PHY_PowerDown();    // Turn off the ethernet interface; -175mW
    
    //C027 thisBoard;
    

    MDMSerial mdm;
    MDMParser::DevStatus devStatus = {};
    MDMParser::NetStatus netStatus = {};
    bool mdmOk = mdm.init(SIMPIN, &devStatus);
    
    #ifdef MDMDEBUG
        mdm.setDebug(4);
    #endif
    
    // ----------------
    // LOCATION READING
    
    
    // OPEN MODEM CONNECTION
    if (!mdm.connect(SIMPIN, APN,USERNAME,PASSWORD))
        return -1;
    
    // SET DEEP SCAN MODE
    printf("Configure deep scan mode\r\n");
    int locConf = mdm.cellLocConfigSensor(1);
    
    
    // Cell location data
    MDMSerial::CellLocData thisLoc;
    
    // Location loop driving variables
    int loopIter = 0;
    bool sendStatus = false;
    
    // Loop timing variables
    Timer cellLocDelay;
    
    int cellLocPeriod = 30; // in seconds
    int timeoutMargin = 5;  // in seconds

    
    // Location data filter variables
    int locAccLower = 50;   // Immediately accept locations with uncertainty lower than this
    int locAccUpper = 5000; // Don't accept locations with uncertainty greater than this
    
    // Filter counters
    int fail1count = 0;
    int fail2count = 0;
    int fail3count = 0;


    // Cell location call variables
    const int sensorMask = 2;  // 1 = GNSS, 2 = CellLocate (aka cell grid position info), 3 = Hybrid: GNSS + CellLocate
    int cellLocReqTimeout = cellLocPeriod - timeoutMargin;  // in seconds       
    const int targetAccuracy = 1; // in meters

    
    // -----------------------
    // Location reporting loop
    while(true) {
        
        // Set some important variables
        M2X_response = 0;
        sendStatus = 0;
        loopIter++;
        
        //printf("tick\r\n");
        
        // Request to fill cell-location buffer
        cellLocDelay.start();
        #ifdef LOCDEBUG
            printf("Initiate cellLocRequest call...\r\n");
        #endif
        mdm.cellLocRequest(sensorMask, cellLocReqTimeout, targetAccuracy);

        
        // Hold next functions until we give cellLocRequest time to execute.
        while((cellLocDelay.read() < cellLocReqTimeout)  &&  (!mdm.cellLocGet(&thisLoc)) ) {
            // Nothin much
        };
      
        // Stop and reset cellLocDelay timer
        cellLocDelay.stop();cellLocDelay.reset();
        
        // We've either got SOME location data or we've timed out. There are three filters:
        // 1. Does it exist?
        // 2. Is it new, or extrapolated from old info?
        // 3. Is the uncertainty within our accepted range?
        
        /* N.B.
        Right now I'm conducting these tests serially in the loop in ancitipation of behavior that will modify itself based on whether we're seeing lots of highly uncertain or extrapolated readings;
        not sure what that behavior is yet, but we're not optimizing enough that I care about nesting conditionals yet.
        */
        
        // 1. Does the location data exist?
        if( thisLoc.validData ) {//if( (mdm.cellLocGet(&thisLoc)) ) {
            fail1count = 0;
            #ifdef LOCDEBUG
                printf("LOC uncertainty= %d, sensor= %d\r\n", thisLoc.uncertainty, thisLoc.sensorUsed );
                printf("LOC = latitude: %0.5f, longitude: %0.5f, altitute: %d\r\n", thisLoc.latitude, thisLoc.longitude, thisLoc.altitude);
            #endif
            
            
            (thisLoc.time).tm_year -= 1900;
            kSysSeconds = mktime( &(thisLoc.time) );
            
            // Set the system clock, if it's not already
            if(!kSysClockSet) {
                set_time(kSysSeconds);
                printf("\033[31mSet system clock time.\033[39m\r\n");
                kSysClockSet=true;
            }            
            #ifdef LOCDEBUG
                printf("LOC read at: %s\r", ctime(&kSysSeconds) );
            #endif           
            

            
            // 2. Is this new position data, or extrapolated from an old reading?
            if(thisLoc.sensorUsed == 2) {
                fail2count = 0;
                #ifdef LOCDEBUG
                    printf("LOC has new information (non-extrapolation)\r\n");
                #endif
                
                // 3. Is this data acceptably accurate (e.g. low enough reported uncertainty)?
                if( (thisLoc.uncertainty < locAccUpper) && (thisLoc.uncertainty > 0) ) {
                    fail3count = 0;
                    #ifdef LOCDEBUG
                        printf("LOC has suitable uncertainty (<%i).\r\n", locAccUpper);
                    #endif                    
                    
                    
                    // PASSSES ALL 3 TESTS => REPORT TO M2X
                    
                    // Report position
                    printf("\r\n\033[34mTRANSMIT LOCATION DATA:\033[39m\r\nla=%0.5f, lo=%0.5f, alt=%d\r\n", thisLoc.latitude, thisLoc.longitude, thisLoc.altitude);
                    M2X_response = m2xClient.updateLocation(DEVID, "pony-spot", (double) thisLoc.latitude, (double) thisLoc.longitude, (double) thisLoc.altitude);
                    if(M2X_response == 202)
                        printf("Location POST successful\r\n");
                    
                    // Report uncertainty
                    M2X_response = m2xClient.updateStreamValue(DEVID, "locacc", thisLoc.uncertainty);
                    if(M2X_response == 202)
                        printf("Location Confidence (%d) POST successful\r\n", thisLoc.uncertainty);
                        
                        
                    // Report temperature
                    float thisTemp = getTemp(&tempPin);
                    printf("temp=%.1fC\r\n",thisTemp);

                    M2X_response = m2xClient.updateStreamValue(DEVID, "kegtemp", thisTemp);
                    if(M2X_response == 202)
                        printf("Temperature (%.2f) POST successful\r\n", thisTemp);
                        
                                            
                    // Report system time
                    thisTime = time(NULL);
                    M2X_response = m2xClient.updateStreamValue(DEVID, "systime", ctime(&thisTime) );
                    if(M2X_response == 202)
                        printf("Systime POST successful - %s \r", ctime(&thisTime) );
                        
                            
                }
                // Fails 3:
                else {
                    fail3count++;
                    #ifdef LOCDEBUG
                        printf("LOC has high uncertainty (<%i); will not report.\r\n", thisLoc.uncertainty);
                    #endif        
                }
            }
            // Fails 2:
            else {
                fail2count++;
                #ifdef LOCDEBUG
                    printf("LOC is extrapolated information; disregard.\r\n");
                #endif
                
            }            
        }

        // Fails 1 and timer is up:
        else {
            ++fail1count;
            printf("CellLocRequest timeout; no location data available.\r\n");    
        }
        
        
        

        
        // --------------------
        // DETERMINE LOOP DELAY
        
        
        
        // TODO: Add conditionals to handle successful location and unsuccessful communication with M2X
        
        // ACTIONS BASED ON LOCATION READ SUCCESS/FAILURE
        
        // Successful read
        if( (!fail1count) && (!fail2count) && (!fail3count) ) {
            kLocLoopDelay = 1 * (60 * 1000);    // Set # minute wait before next read
            printf("Successful LOC read; ");
        }
        // Too many invalid location reads
        else if (fail1count > 10) {
            sprintf(statusBuf, "Fail1count exceeds 10.\r\n");
            printf(statusBuf);
            fail1count = 0;
            sendStatus = true;
        }

        else if (fail2count > 10) {
            sprintf(statusBuf, "Fail2count exceeds 10.\r\n");
            printf(statusBuf);
            fail2count = 0;
            sendStatus = true;
        }        
        
        else if (fail3count > 10) {
            sprintf(statusBuf, "Fail3Count exceeds 10.\r\n");
            printf(statusBuf);
            fail3count = 0;
            sendStatus = true;
        }        
        
        else {
            kLocLoopDelay = kLocLoopDelayDef;
            printf("Failed LOC loop; ");
        }
        
        // If we have no status update to send, send one every 10 loops just cause.
        if (!sendStatus && (loopIter % 10 == 0) ) {
            sprintf(statusBuf, "Periodic status update check-in.\r\n");
            printf(statusBuf);            
            sendStatus = true;
        }
        
        // Transmit a status response?
        if(sendStatus) {
            M2X_response = m2xClient.updateStreamValue(DEVID, "status", statusBuf);
            if(M2X_response == 202)
                printf("Status POST successful\r\n"); 
        }
        
        // Set loop delay (i.e. period)
        printf("loop waiting for %i seconds...\r\n---\n\r\n", (kLocLoopDelay / 1000) );
        
        flipper.attach(&flip, 0.5); // LED toggle! // the address of the function to be attached (flip) and the interval (2 seconds)
        
        // Put this shiz to sleep
        
        
        
        delay(kLocLoopDelay); 
        led1 = 0;   // Turn that LED off!
        
    }


    //mdm.disconnect();
    //mdm.powerOff();
    
}