Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: C027 C027_Support M2XStreamClient PowerControl jsonlite mbed-rtos mbed
Fork of PONY_Ph0-uAXIS by
main.cpp
- Committer:
- sgmcb
- Date:
- 2015-12-29
- Revision:
- 46:ab4cccab10c9
- Parent:
- 45:0d8cb417a9e2
- Child:
- 47:d9180474fa1e
File content as of revision 46:ab4cccab10c9:
#include "mbed.h"
//------------------------------------------------------------------------------------
// C027 Support Libraries
#include "GPS.h"
#include "MDM.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 "54c6bbf11012f34830bd23cc091ca250"
#define DEVID "b9c57667ee0495dc0b3cddd890f8d2df"
#endif
#ifndef THROWAWAY
// v1.2 codes
#define M2XAPIKEY "bbc483492238dc76f7d12f0cd6e13a4b"
#define DEVID "3764db38b6c9ec4045a38e0125b14b4c"
#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 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);
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\r\n\n");
#ifdef THROWAWAY
printf("Using THROWAWAY M2X device\r\n");
#endif
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 ponyLoc, thisLoc;
// Loop driving variables
int loopIter = 0;
bool locLock;
// Loop timing variables
Timer cellLocDelay;
int submitPeriod = 30; // AXE THIS
int cellLocPeriod = 30; // in seconds
int timeoutMargin = 5; // in seconds
// Loop limit variables
int readLoopMax = 100;
// 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 = -1;
int fail2count = -1;
int fail3count = -1;
// 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;
locLock = false;
loopIter++;
//printf("tick\r\n");
// Request to fill cell-location buffer
cellLocDelay.start();
mdm.cellLocRequest(sensorMask, cellLocReqTimeout, targetAccuracy);
// Hold next functions until we give cellLocRequest time to execute.
while((cellLocDelay.read() < cellLocReqTimeout) && (!mdm.cellLocGet(&thisLoc)) ) {
// Nothin much
};
// wait 5 to make sure that our URCs are ready?
delay(5000);
//printf("cellLocDelay=%f\r\n",cellLocDelay.read());
// Stop and reset cellLocDelay timer
cellLocDelay.start();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( (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
// 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
// REPORT TO M2X
// Report position
printf("\r\nTRANSMIT LOCATION DATA:\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);
}
// 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 has is extrapolated information; disregard.\r\n");
#endif
}
}
// Fails 1 but inside cellLocReq timeout length; repeat without delay:
else if ( cellLocDelay < cellLocReqTimeout ){
printf("Waiting on cellLoc timeout...\r\n");
}
// Fails 1 and timer is up:
else {
++fail1count;
printf("CellLocRequest timeout; no location data available.\r\n");
delay(30*1000);
}
continue;
// Skip this old crap
// OLD AF
// Have location data
if ( mdm.cellLocGet(&thisLoc) ){
printf("cellLocDelay=%f\r\n",cellLocDelay.read());
if(thisLoc.sensorUsed == 2) { // thisLoc.uncertainty < ponyLoc.uncertainty) { //Basing test for validity on uncertainty and having a new position lock
printf(" NEW-latitude: %0.5f, longitude: %0.5f, altitute: %d, uncertainty: %d, sensor: %d\r\n", thisLoc.latitude, thisLoc.longitude, thisLoc.altitude, thisLoc.uncertainty, thisLoc.sensorUsed);
ponyLoc.latitude = thisLoc.latitude;
ponyLoc.longitude = thisLoc.longitude;
ponyLoc.altitude = thisLoc.altitude;
ponyLoc.uncertainty = thisLoc.uncertainty;
if(!kSysClockSet) {
printf("\033[31mSet system clock time.\033[39m\r\n");
// TODO: Get the local time zone
//mdm.setDebug(4);
//mdm.sendFormated("AT+CTZR=1");
// Adjust year because it's reporting the absolute year
// mbed expects the year to be "since 1900" (https://developer.mbed.org/handbook/Time?action=view&revision=11592)
(thisLoc.time).tm_year -= 1900;
kSysSeconds = mktime( &(thisLoc.time) );
set_time(kSysSeconds);
printf("System time set to: %s\r\n", ctime(&kSysSeconds) );
kSysClockSet=true;
}
// Print the timestamp
time_t newTime = time(NULL);
printf("System time at: %s\r\n", ctime(&newTime) );
}
// Check location data
if( ( 0 < ponyLoc.uncertainty && ponyLoc.uncertainty < locAccLower ) || ( 0 < ponyLoc.uncertainty && ponyLoc.uncertainty < locAccUpper && loopIter > readLoopMax ) ) {
printf("\r\nTRANSMIT LOCATION DATA:\r\nla=%0.5f, lo=%0.5f, alt=%d\r\n", ponyLoc.latitude, ponyLoc.longitude, ponyLoc.altitude);
M2X_response = m2xClient.updateLocation(DEVID, "pony-spot", (double) ponyLoc.latitude, (double) ponyLoc.longitude, (double) ponyLoc.altitude);
if(M2X_response == 202)
printf("Location POST successful\r\n");
// Report uncertainty
M2X_response = m2xClient.updateStreamValue(DEVID, "locacc", ponyLoc.uncertainty);
if(M2X_response == 202)
printf("Location Confidence (%d) POST successful\r\n", ponyLoc.uncertainty);
locLock = true;
}
}
// No location data
else {
printf("cellLocGet failed.\r\n");
//
}
// Wait only if we've received a good location reading
if(locLock) {
printf("Begin %i second delay\r\n",kReadingDelay/1000); loopIter = 0; delay(kReadingDelay);
ponyLoc.uncertainty = locAccUpper + 1;
continue;
}
else if (loopIter > readLoopMax) {
sprintf(statusBuf, "CellLoc location not found after %i loops.\r\n", loopIter);
printf(statusBuf);
M2X_response = m2xClient.updateStreamValue(DEVID, "status", statusBuf);
if(M2X_response == 202)
printf("Status POST successful\r\n");
ponyLoc.uncertainty = locAccUpper + 1;
printf("Begin %i second delay\r\n",kReadingDelay/1000); loopIter = 0; delay(kReadingDelay);
continue;
}
else {
printf("Bad data delay = submitPeriod...\r\n");
delay(submitPeriod * 1000); // Delay between CellLoc requests when not getting good data
flipper.attach(&flip, 0.5); // the address of the function to be attached (flip) and the interval (2 seconds)
}
led1 = 0;
}
//mdm.disconnect();
//mdm.powerOff();
}
