whatever
Dependencies: C027 C027_Support M2XStreamClient PowerControl jsonlite mbed-rtos mbed
Fork of PONY_Ph0-uAXIS by
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(); }