Calling a function from the iPhone App => awesome || Running it from IFTTT or called from within the app => RED LIGHT OF DEATH

I am using my particle to read an XML file (using myHandler()), parse it (using splitNumbersOut() and tryExtractString()), and then use those values to move servos (using runThemAll()). If I call runThemAll() from my iphone particle app using runthemaller(), it works great. However, if I call runThemAll() from the Loop() or though IFTTT, I get the red light, the particle goes offline, and then restarts. Thanks in advance for any help!!! :smile:

Full Code:

    int Servo_Location[] = {5,5,5,5,5};

Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;

Servo Scycler[5]= {servo1, servo2, servo3, servo4, servo5};

String weight_string, weather_string, lion_string, choice_string, dow_string, weatherTom_string;

int servoPos = 120;

String xml_result;
String lastrun = "not yet";

boolean restarted = true;
 
//THE SET UP
//****************************************************************************************************
//****************************************************************************************************


void setup()
{

    // Set time zone to Eastern USA daylight saving time
    Time.zone(-4);

	//ATTACH THE SERVOS TO THE DIFFERENT PINS OF THE PHOTON	

	//
	//Attach Servo’s
	//
	servo1.attach(D0);
	servo2.attach(D1);
	servo3.attach(D2);
	servo4.attach(D3);
	servo5.attach(WKP);

	//
	//Particle Functions
	//
	Particle.subscribe("hook-response/Bar_Info", myHandler, MY_DEVICES);
	Particle.function("servo", servoControl);
	Particle.function("setter", setterControl);
	Particle.function("runthemaller", runthemaller);
	Particle.function("Timedrun", Timedrun);


	//
	//Particle Variables
	//
	Particle.variable("SERVO1", Servo_Location[0]);
	Particle.variable("SERVO2", Servo_Location[1]);
	Particle.variable("SERVO3", Servo_Location[2]);
	Particle.variable("SERVO4", Servo_Location[3]);
	Particle.variable("SERVO5", Servo_Location[4]);
	Particle.variable("timer", lastrun);
	
}


//WEB FUNCTIONS
//****************************************************************************************************
//****************************************************************************************************


void myHandler(const char *event, const char *data)
{
  // Handle the integration response
    xml_result = String(data);
    Particle.publish("XML Result", xml_result, PUBLIC);
    StringReset();
    splitNumbersOut(0,weather_string, ",");
}




int setterControl(String command)
{
    Particle.publish("Setter_String", command, PUBLIC);
    int i = command.toInt();
    int z = constrain(i, 0, 100);
    servoRunner(z,z,z,z,z);
    return 1;
}



int servoControl(String command)
{
   int newPos = command.toInt();
   servoPos = constrain( newPos, 0 , 180);
   servo1.write(servoPos);

   	//β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
   	//Test that the string is split correctly
  	//β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
  	 Particle.publish("position", command, PUBLIC);


   delay(2000);
   showWeight();
   delay(2000);
   return 1;

}

int runthemaller(String command)
{
   runThemAll();
   Particle.publish("runthemaller", "rta_over", PUBLIC);
   return 1;
  
}


int Timedrun(String command)
{
   Particle.publish("runthemaller", command, PUBLIC);
  int ttime = Time.hour();
    if ((ttime > 8) && (ttime < 20))
    {
    Particle.publish("in_Loop", "runningthemall", PUBLIC);
    runThemAll();
    }
    else
    {
    Particle.publish("in_Loop", "wrong time", PUBLIC);
    }
    Particle.publish("in_Loop", "Timed_over", PUBLIC);

   return 1;
  
}


//DATA PARSING FUNCTIONS
//****************************************************************************************************
//****************************************************************************************************



void StringReset() 
{
    weight_string = tryExtractString(0, xml_result, "weight=\"", "\"");
    weather_string = tryExtractString(0, xml_result, "weather=\"", "\"");
    weatherTom_string = tryExtractString(0, xml_result, "weather_tom=\"", "\"");
    lion_string = tryExtractString(0, xml_result, "lion=\"", "\"");
    choice_string = tryExtractString(0, xml_result, "choice=\"", "\"");
    dow_string = tryExtractString(0, xml_result, "choice=\"", "\"");
    
	//β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
   	//Test that the weather and weight are set
   	//β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
    // 	Particle.publish("temp_in_reset", weather_string, PUBLIC);
    //	Particle.publish("weight_in_reset", weight_string, PUBLIC);

}



String splitNumbersOut (int matchNum, String str, const char* end) {
   if (str == NULL) {
    return NULL;
    }
    int count =0;
    while (count<5)
    {
    int lastIdx =0;
    int idx = str.indexOf(end);
    Servo_Location[count] = str.substring(lastIdx, idx).toInt();
    str=str.substring(idx+1);
    count++;

    }
    StringReset();
}


String tryExtractString(int matchNum, String str, const char* start, const char* end) {
    if (str == NULL) {
        return NULL;
    }

    int count = 0;
    int lastIdx = 0;

    while (count <= matchNum) {
        int idx = str.indexOf(start, lastIdx);

        int endIdx = str.indexOf(end, lastIdx + idx + strlen(start));

        lastIdx = endIdx;

        if (count == matchNum) {
            return str.substring(idx + strlen(start), endIdx);
        }
        count++;
    }
}



//SERVO CONTROLS
//****************************************************************************************************
//****************************************************************************************************

void servoRunner(int a, int b, int c, int d, int e)
{
    
 //m is the integer to mutliply the input.
 int m = 1.7;
 //f is the amount that needs to be adjusted to keep it in the servo range
 int f = 10;
   servo1.write(a*m + f);
   delay(500);
   servo2.write(180 - b*m - f);
   delay(500);
   servo3.write(c*m + f);
   delay(500);
   servo4.write(180 - d*m - f);
   delay(500);
   servo5.write(e*m + f);
   delay(500);
}


//LETS PUT ALL THE DATA RUNNERS HERE
//****************************************************************************************************
//****************************************************************************************************


void runThemAll()
{ 
    theDance();
    Particle.publish("this", weather_string, PUBLIC);
    showWeight();
    delay(3000);
    servoRunner(50,50,50,50,50);
    delay(500);
    showLions();
    delay(3000);
    servoRunner(50,50,50,50,50);
    delay(500);
    int slimer = Time.hour();
    lastrun = String(slimer);
    Particle.publish("time", lastrun, PUBLIC);
    if (slimer < 18)
	{
	showWeather();
	}
    else
	{
	showWeatherTom();
	}
	Particle.publish("this", "Run_Over", PUBLIC);

}

void theDance()
    {
    servoRunner(100,75,50,25,0); 
    delay(1500);
    servoRunner(0,25,50,75,100);
    delay(1500);
    servoRunner(50,50,50,50,50);
    }


void showWeather()
{
    splitNumbersOut(0,weather_string, ",");
 	  Particle.publish("_in_showWeather", weather_string, PUBLIC);

    servoRunner(Servo_Location[0], Servo_Location[1],Servo_Location[2], Servo_Location[3],Servo_Location[4]);
}

void showWeight()
{
    splitNumbersOut(0,weight_string, ",");
   
	  //β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
 	  //Test that the string is split correctly
 	  //β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
  	  Particle.publish("_in_showWeight", weight_string, PUBLIC);
   
   servoRunner(Servo_Location[0], Servo_Location[1],Servo_Location[2], Servo_Location[3],Servo_Location[4]);
}

void showWeatherTom()
{
    splitNumbersOut(0, weatherTom_string, ",");
    servoRunner(Servo_Location[0], Servo_Location[1],Servo_Location[2], Servo_Location[3],Servo_Location[4]);
    Particle.publish("_in_showWeatherTom", weatherTom_string, PUBLIC);
}

void showChoice()
{
    splitNumbersOut(0,choice_string, ",");
    servoRunner(Servo_Location[0], Servo_Location[1],Servo_Location[2], Servo_Location[3],Servo_Location[4]);
    Particle.publish("_in_showChoice", choice_string, PUBLIC);
}


void showLions()
{
    splitNumbersOut(0,lion_string, ",");
    servoRunner(Servo_Location[0], Servo_Location[1],Servo_Location[2], Servo_Location[3],Servo_Location[4]);
    Particle.publish("_in_showLions", lion_string, PUBLIC);
}


//THE LOOP
/****************************************************************************************************/
/****************************************************************************************************/


void loop() 
{
  // Get some data
  String data = String(10);
  // Trigger the integration
  Particle.publish("Bar_Info", data, PRIVATE);
  
  // Wait 60 seconds
  delay(60000);
  if (restarted)
    {
    runThemAll();
    delay (50000);
    restarted = false;
    }

   delay(120000);

  
  int ttime = Time.hour();
  int mtime =Time.minute();
    if ((ttime > 7) && (ttime < 20) && (mtime==0))
    {
    Particle.publish("in_Loop", "runningthemall", PUBLIC);
    runThemAll();
    }
}

The β€œred light” does provide some info about the reason.
I guess you see an SOS signal followed by a number of slower blinks followed by another SOS. That number of slow blinks might give a clue.

But some general hints.

  • Don’t delay Particle.function() callbacks too long (best not at all). Keep them short and fast
  • Reduce the use of String objects and better go for pure C strings.
  • You’ve got a lot of publishes, make sure to heed the rate limit

Hi ScruffR, can you elaborate a bit on that, please? I’m not familiar with pure C strings.
thanks!
Gustavo.

What I call β€œpure C strings” is nothing other than a char array which holds the string plus a \0 zero-terminator byte.
With these (zero-terminated) strings you can use all the standard C string functions like sprintf(), strcat(), strcmp(), …
But since they are merely β€œdumb” arrays (rather than objects that might do things behind the scene) you won’t get unexpected results like relocation and heap fragmentation.
On the other hand you need to think ahead a bit more, e.g. how big the array has to be to hold your longest string.

1 Like

Thanks so much for the help - no red light but the functions are coming back with errors. I think they are just taking too long. When I tried to shorten them, and had them just change a variable, that triggered the servos in the loop() function, the red light came back. So, it works, for now but will keep trying. Thanks again!

Yup, hence