Photon rebooting

For some reason, at the same point in my code every time, my photon reboots.

Right after the line Particle.publish("receivedData", deviceId); is called (I see the event in the event console), I see the following event:

The receivedData event works fine, but right after that the device resets.

The code is here:

// This #include statement was automatically added by the Particle IDE.
#include <google-maps-device-locator.h>

// This #include statement was automatically added by the Particle IDE.
#include "lib1.h"

// This #include statement was automatically added by the Particle IDE.
#include <M2XStreamClient.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

String deviceId = "NULL";
char stream1Name[] = "LPO_P1"; 
char stream2Name[] = "LPO_P2";// Stream you want to post to
char m2xKey[] = "xxxxxxxxxxxxxxxxxx";   // Your M2X access key

TCPClient client;
M2XStreamClient m2xClient(&client, m2xKey);

#define RXPIN2 2 // INTERRUPT 0 = DIGITAL PIN 2 - use the interrupt number in attachInterrupt
#define RXPIN3 3 // INTERRUPT 0 = DIGITAL PIN 3 - use the interrupt number in attachInterrupt
#define MAX_MICROS 35791394

volatile unsigned long duration0; // volatile, we set this in the Interrupt and read it in loop so it must be declared volatile
volatile unsigned long duration1;
volatile unsigned long StartPeriod0 = 0; // set in the interrupt
volatile unsigned long EndPeriod0 = 0; // set in the interrupt
volatile unsigned long StartPeriod1 = 0; // set in the interrupt
volatile unsigned long EndPeriod1 = 0; // set in the interrupt
volatile unsigned long Countint = 0; // set in the interrupt
volatile boolean pulse0 = false; // set in the interrupt and read in the loop
volatile boolean pulse1 = false;
unsigned long starttime;
unsigned long currtime;
unsigned long sampletime_ms = 30000;
unsigned long lowpulseoccupancy0 = 0;
unsigned long lowpulseoccupancy1 = 0;
unsigned long analogcount;
unsigned long analogvalue = 0;
double analogtotal;
double LPO_P1 = 0.0;
double LPO_P2 = 0.0;
GoogleMapsDeviceLocator locator;
String deviceType = "Unidentified";
String locationInfo;


void setup() {
  // ApplicationWatchdog wd(60000, System.reset);
  Particle.variable("LPO_P1", LPO_P1);
  Particle.variable("LPO_P2", LPO_P2);
  pinMode(D2, INPUT);
  pinMode(D3, INPUT);
  attachInterrupt(D2, isrduration0,CHANGE);
  attachInterrupt(D3, isrduration1,CHANGE);
  Serial.begin(115200); 
  locator.withSubscribe(locationCallback).withLocatePeriodic(30);
  String myID = System.deviceID();
  Particle.subscribe(myID, myHandler);
  #if PLATFORM_ID == 0 // Core
  deviceType = "Core";
#elif PLATFORM_ID == 6 // Photon
  deviceType = "Photon";
#elif PLATFORM_ID == 8 // P1
  deviceType = "P1";
#elif PLATFORM_ID == 10 // Electron
  deviceType = "Electron";
#else
  #error "*** PLATFORM_ID not supported by this firmware. PLATFORM should be Core, Photon, P1 or Electron ***"
#endif
  Particle.variable("deviceType", deviceType);
//   bool success = Particle.function("funcKey", funcName);

// Cloud functions must return int and take one String

  //Only for Leonardo
  //while(!Serial) {
  //  ;
  //}

}
void myHandler(const char *event, const char *data)
{
    //  String myID = System.deviceID();
    // ids = str_split(data, ':');
    // Particle.publish("myID", myID);
    // Particle.publish("eventName", String(event));
    // Particle.publish("comparison", strcmp(String(event), myID));
//   if (strcmp(String(event), myID) == 0){
    
    setId(&deviceId, String(data));
    Particle.publish("receivedData", deviceId);
    // deviceId = String(data);
//   }
}
void setId(String *deviceId, String newID){
    *deviceId = newID;
    
}
void loop() {
    locator.loop();

/*    
if(!Particle.connected())
  {
    Serial.println("Particle Disconnected");
    Particle.connect();
  }
*/
  analogvalue = analogvalue + analogRead(0);
  analogcount++;
if(pulse0)
 {
   lowpulseoccupancy0 = lowpulseoccupancy0+duration0;
   //Serial.print("Int0 ");  
   //Serial.print(Countint);  
   //Serial.print(",");
   //Serial.print(EndPeriod0);
   //Serial.print(",");
   //Serial.println(duration0);
   pulse0 = false;
 }
if(pulse1)
 {
   lowpulseoccupancy1 = lowpulseoccupancy1+duration1;
   //Serial.print("Int1 ");  
   //Serial.print(EndPeriod1);
   //Serial.print(",");
   //Serial.println(duration1);
   pulse1 = false;
 }
 currtime = millis();
  if ((currtime-starttime) > sampletime_ms)
  {
    analogvalue = analogvalue/analogcount;
    analogtotal = (analogvalue*3.3)/4095;
    LPO_P1 = lowpulseoccupancy1/10.0/sampletime_ms;
    LPO_P2 = lowpulseoccupancy0/10.0/sampletime_ms;
    // Serial.println(WiFi.localIP()); // Only for Photon, not for Electron
    Serial.print(lowpulseoccupancy0);
    Serial.print(",");
    Serial.print(lowpulseoccupancy1);
    Serial.print(",");
    Serial.println(analogtotal);
    
    Particle.publish("deviceId", deviceId);
    if(strcmp(deviceId, "NULL") != 0){
        int response1 = m2xClient.updateStreamValue(deviceId, stream1Name, LPO_P1);
        // Particle.publish("response1", response1);
        Serial.print("M2x client response code: ");
        Serial.println(response1);
    }
    
    Particle.publish("LPO_P1", String(LPO_P1));
    
    // if (response1 == -1) while(1) ;
    
    if(strcmp(deviceId, "NULL") != 0){
        int response2 = m2xClient.updateStreamValue(deviceId, stream2Name, LPO_P2);
        // Particle.publish("response2", response2);
        Serial.print("M2x client response code: ");
        Serial.println(response2);
    }
    Particle.publish("LPO_P2", String(LPO_P2));

    // if (response2 == -1) while(1) ;
    
  
    lowpulseoccupancy0 = 0;
    lowpulseoccupancy1 = 0;
    analogvalue = 0;
    analogcount = 0;
    starttime = millis();
  }
 
}

void isrduration0()
{
  // if the pin is low, its the start of an interrupt
  Countint++;
  if(digitalRead(D2) == LOW)
  { 
    StartPeriod0 = micros();
  }
  else
  {
    // if the pin is high, its the rising edge of the pulse so now we can calculate the pulse duration by subtracting the 
    // start time  from the current time returned by micros()
    if(StartPeriod0 && (pulse0 == false))
    {
      EndPeriod0 = micros();
      if(StartPeriod0 < EndPeriod0)
        duration0 = EndPeriod0 - StartPeriod0;
      else
        duration0 = MAX_MICROS - StartPeriod0 + EndPeriod0;
      StartPeriod0 = 0;
      pulse0 = true;
    }
  }
}

void isrduration1()
{
  // if the pin is low, its the start of an interrupt
  if(digitalRead(D3) == LOW)
  { 
    StartPeriod1 = micros();
  }
  else
  {
    // if the pin is high, its the rising edge of the pulse so now we can calculate the pulse duration by subtracting the 
    // start time  from the current time returned by micros()
    if(StartPeriod1 && (pulse1 == false))
    {
      EndPeriod1 = micros();
      if(StartPeriod1 < EndPeriod1)
        duration1 = EndPeriod1 - StartPeriod1;
      else
        duration1 = MAX_MICROS - StartPeriod1 + EndPeriod1;
      StartPeriod1 = 0;
      pulse1 = true;
    }
  }
}

// char** str_split(const char* a_str, const char a_delim)
// {
//     char** result    = 0;
//     size_t count     = 0;
//     const char* tmp        = a_str;
//     char* last_comma = 0;
//     char delim[2];
//     delim[0] = a_delim;
//     delim[1] = 0;

//     /* Count how many elements will be extracted. */
//     while (*tmp)
//     {
//         if (a_delim == *tmp)
//         {
//             count++;
//             const char* last_comma = tmp;
//         }
//         tmp++;
//     }

//     /* Add space for trailing token. */
//     count += last_comma < (a_str + strlen(a_str) - 1);

//     /* Add space for terminating null string so caller
//       knows where the list of returned strings ends. */
//     count++;

//     result = (char**)malloc(sizeof(char*) * count);

//     if (result)
//     {
//         size_t idx  = 0;
//         char* token = strtok((char*)a_str, delim);

//         while (token)
//         {
//             assert(idx < count);
//             *(result + idx++) = strdup(token);
//             token = strtok(0, delim);
//         }
//         assert(idx == count - 1);
//         *(result + idx) = 0;
//     }

//     return result;
// }
void locationCallback(float lat, float lon, float accuracy) {
    
    locationInfo = String(lat)+","+String(lon)+","+String(accuracy);
  Particle.variable("locationInfo", locationInfo);
    
  // Handle the returned location data for the device. This method is passed three arguments:
  // - Latitude
  // - Longitude
  // - Accuracy of estimated location (in meters)
}