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)
}