Stack overflow with simple (?) code, IFTTT, and Twitter

photon
Tags: #<Tag:0x00007fe2245bc5d0>

#1

I’m just getting back into using a Photon after being away for a couple of years. I seem to be getting 13 red blinks, and I can’t see why, or even a pattern as to when.

The basic idea is that an IFTTT applet publishes an event if a certain Twitter user tweets, and second IFTTT applet publishes an event if a certain hashtag is used. The Photon should light one LED for every hashtag mention and a different LED for each tweet from the user.

Each LED goes to the corresponding pin, and their grounds share a 220 ohm resistor to ground.

Troubleshooting I’ve done:

-I had a hard time flashing code, but finally figured out to install the CLI, Homebrew, and the DFU installer thing, and managed to get the firmware updated. Now I can flash the code from from web IDE, and it seems to work…until I get the SOS and 13 blinks and everything resets.

-I’ve tried different power sources for the USB cable (which is the one that came with the Photon and seems to still be good and undamaged).

-I don’t know what stack overflow means, really. I am not sending any data from the IFTTT event, and the code (which I basically copied from somebody else’s project) seems simple and small.

int hashtagLED = D2; 
int tweetLED = D5;      

int tweetLEDduration = 2; // in minutes
int hashtagLEDduration = 10; // in seconds

void setup(){

    pinMode(tweetLED, OUTPUT);
    pinMode(hashtagLED, OUTPUT);

    Particle.subscribe("tweetEvent", tweetHandler, MY_DEVICES);
    Particle.subscribe("hashtagEvent", hashtagHandler, MY_DEVICES);
}

void loop() {
}

void tweetHandler(const char *event, const char *data){

    // If the user tweets, turn LED on
    digitalWrite(tweetLED, HIGH);
    
    // Leave it on for the length in minutes (set above) times 60000 milliseconds.
    delay(tweetLEDduration * 60000);
    
    // Turn the LED back off.
    digitalWrite(tweetLED, LOW);
}

void hashtagHandler(const char *event, const char *data){

    // If the hashtag is used, turn LED on.
    digitalWrite(hashtagLED, HIGH);
    
    // Leave it on for the length in seconds (set above) times 1000 milliseconds.
    delay(hashtagLEDduration * 1000);
    
    //Then we'll turn it off...
    digitalWrite(hashtagLEDduration, LOW);
}

I’ve tried to search the forums and have tried a few different solutions, but not sure what to do next.

-Can the Photon not subscribe to two different events?
-Is there a problem with power consumption of the LEDs over a long (?) period of time?
-Am I missing something completely different?


#2

I’d advise against using long delays in a subscription handler.
When you have multiple events during that waiting time each new hander call will allocate its own set of data on the stack. Doing that too often may exhaust the stack space - that is what stack overflow is.

The better way is to set a global flag inside your handler and treat that flag in loop().
Alternatively you can switch on your LED in the handler and start a one-shot timer to switch it back off after the desired time.


#3

Thank you for the prompt response. I think I understand the problem. Not sure how to implement your solutions, since I don’t have a great grasp of …function calls (?) outside of the main loop, but I think it’s something I can figure out now that I know what to look at. Thanks!


#4

Here is a prototype that will avoid longggggg delays in the handler and the loop

Add global variables

volatile bool isTweet;
volatile bool isHashTag;
unsigned long hashtagtimer;
unsigned long tweettimer;

in setup() add to the end

isTweet = false;
isHashTag = false;
tweettimer = 0;
hashtagtimer = 0;
digitalWrite(tweetLED, LOW);

in loop()

if (isTweet)
{
     isTweet = false;  //reset flag
     digitalWrite(tweetLED, HIGH);   //LED on
     tweettimer = millis();  //start time on
}
if (tweettimer > 0 && (millis() - tweettimer >= (unsigned long) tweetLEDduration * 60000))
{
     digitalWrite(tweetLED, LOW);
tweettimer = 0;   //stop the timer
}

then repeat the same for the hashtag

Handlers then become super short and simple

void tweetHandler(const char *event, const char *data){
isTweet = true;   //set flag
}

void hashtagHandler(const char *event, const char *data){
isHashTag = true;
}

#5

You either don’t need tweettimer > 0 or you should add tweettimer = 0 inside the conditional block.
As is the extra condition only prevents entering the block on the very first run but after one trigger it will keep doning it repeatedly after all.
So either we can put up with the initial triggers (drop the extra check) or we keep preventing repeated triggers on all future instances too (reset the timer to zero).


#6

Have edited the code - thanks for the spot! Forgot to add clearing the value of the timer to signify not active.


#7

Thank you both so much, I really appreciate the time you’ve taken to help me out.

So am I right in thinking that IFTTT isn’t necessarily super reliable? I watch Twitter for posts using target hashtags, and sometimes my routine is triggered, sometimes it isn’t.

Also, and worse, when it is called, the handler is called many times per event. I don’t know if this is IFTTT or Particle’s subscribe functionality, but I put a counter in there - increase the variable by one each time it runs - and when I do get just one event the counter quickly jumps to 20+.

My project is an art project, and so fortunately accuracy isn’t life or death, but the first problem is frustrating, and the second one kinda makes the whole project arbitrary.

I feel like I must be missing something? I would like for my “art project” to at least have some semblance of accuracy.


#8

It’s not uncommon to see multiple IFTTT triggers. On the other hand I hardly ever saw a Particle.subscribe() handler to fire without an actual/explicit event.

But you should be able to check the incoming events via console.particle.io/events