0

I have this code

#include <Ticker.h>  //Ticker Library
Ticker blinker;
/* ... */

//blinker.attach(1, []() { digitalWrite(LED,!digitalRead(LED)); }
while(!client.connect(laptop,port)) {
   Serial.println("Connecting...");
   delay(1000);
}

Which works fine, tries connecting, then eventually connects.

If I uncomment the line attaching to this 'blinker' Ticker, then I get a crash right after the first 'Connecting...' print. When I look at the stack trace, it mentions that the crash happens during the delay(1000) in my while loop (which is presumably the moment when the program yields and the blinker can do some work)

Is there anything I can do to make this timer work better?

  • What library is the blinker object from? Where does the Timer.h, from the title` come into play? – Gerben Mar 26 at 15:07
  • I was confused - I meant Ticker.h - I updated the code to make it more apparent - apologies for that – joelhoro Mar 26 at 15:31
  • What's the boot message after the crash? You'll have to set the terminal speed to 74400 to see it. It'll look something like ets Jan 8 2013,rst cause:2, boot mode:(3,6) - the rst cause: number is the most important thing. – John Romkey Mar 27 at 4:35
  • Couldn't get the rst cause thing for some reason... – joelhoro Mar 28 at 1:31
4

Update: the original question mentioned timers, so this answer is for a hardware timer interrupt handler. It doesn't apply to Ticker, which is what the question is now about.

The callback that you attach to blinker will be called as an interrupt handler, so it's important to make sure it's already loaded into executable instruction memory (iRAM) on the ESP8266. When you pass anonymous function inline to blinker.attach() it won't tagged to be stored in iRAM.

Try this instead:

void ICACHE_RAM_ATTR blinker_handler(){
    digitalWrite(LED,!(digitalRead(LED)));  //Toggle LED Pin
}

...

blinker.attach(1, blinker_handler);

ICACHE_RAM_ATTR tells the system to keep the code in the instruction RAM. There's not a lot of iRAM (32Kbytes) so you don't want to do this too often, but it's important for interrupt handlers (another reason to keep them short and sweet).

  • oh that's very useful, thanks. I've used Tickers in other cases, and it seemed to work fine even though I was attaching callbacks to them instead of IRAM (which I had no idea about). I will try your suggestion. – joelhoro Mar 26 at 15:34
  • What's the purpose of timer1_write(600000); please? – Mark Smith Mar 26 at 16:57
  • @MarkSmith I believe that was in the original example before it was updated. – John Romkey Mar 27 at 4:19
  • 1
    @joelhoro with the update - now that we're talking about Ticker, not a timer - I don't think this is the right answer. I thought you were talking about a hardware timer's interrupt handler - this would be correct for that. But I'm sure Ticker's callback doesn't run as an interrupt handler. I'll edit the answer to point that out but I think there's going to be a different solution. – John Romkey Mar 27 at 4:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.