Timer stop causing program to restart

I have a simple program which utilizes a software timer. I don’t understand why the device restarts every time the timer expires. Thoughts?

Here’s the code:

//Strobe Light Control
//C Thomas Morrison
//20190829
//

//Let's use an external antenna if it one is connected
STARTUP(WiFi.selectAntenna(ANT_AUTO));

#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)

retained int onSeconds = 900; //number of seconds to run strobe light
retained int onMilliseconds = onSeconds * 1000; //number of milliseconds to run strobe light

int strobe = D5; //output used for strobe light

char gDeviceInfo [200];

//Required for the timer function
void callstopOutput () {
  stopOutput("fred");
}

Timer t(onMilliseconds,callstopOutput); //one shot timer used to stop strobe light

void setup() {
  //Serial.println("we're trying to sync the device's time");
  while(Time.year() <= 1970) Particle.process();
  //Publishes info about the device
  snprintf(gDeviceInfo, sizeof(gDeviceInfo)
          ,"Application: %s, Date: %s, Time: %s, System firmware: %s, SSID: %s"
          ,__FILENAME__
          ,__DATE__
          ,__TIME__
          ,(const char*)System.version()  // cast required for String
          ,(const char*)WiFi.SSID()       // cast not required but always safe when in doubt if String or char*
          //,WiFi.RSSI()
          );
  Particle.variable("deviceInfo",gDeviceInfo);
  Particle.variable("onSeconds",onSeconds);
  Particle.function("pReset",pReset);
  Particle.function("startStrobe",startOutput);
  Particle.function("stopStrobe",stopOutput);
  Particle.function("setOnPeriod",setOnPeriod);
  Particle.function("getStrobeState",getStrobeState);
  pinMode(strobe, OUTPUT);
}

void loop() {
  //nothing needed in here
}


int startOutput (String command) {
    t.reset(); //reset and start the timer to automatically shut off the filler
    digitalWrite(strobe,1);
    Particle.publish("Started strobe",NULL,60,PRIVATE);
    return 1;
}

int stopOutput (String command) {
    digitalWrite(strobe,0);
    t.stop();
    Particle.publish("Stopped strobe",NULL,60,PRIVATE);
    return 1;
}

int pReset(String command) {
  //function to call to remotely reset Photon
  Particle.publish("strobe control reset",NULL,60,PRIVATE);
  System.reset();
  return 1;
}

int getStrobeState(String command) {
  int _state = digitalRead(strobe);
  if (_state==0){
    Particle.publish("Strobe is off",NULL,60,PRIVATE);
  }
  else {
    Particle.publish("Strobe is on",NULL,60,PRIVATE);
  }
  return _state;
}

int setOnPeriod(String command) {
  //change the Grovestreams update period
  Serial.println("Setting strobe run period");
  int _command;
  _command = command.toInt();
  if (_command>=60 && _command<=3600) {//in minutes - between 1 and 3 minutes)
    onSeconds = _command;
    onMilliseconds = onSeconds * 1000;
    t.changePeriod(onMilliseconds);
    return 1;
  }
  else {
    return -1;
  }
}

Darn…calling Particle.publish() is a NO NO in a timer callback!

I would instead set a flag in your callback, and then call stopOutput() from loop() when that flag is set.

1 Like