Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8725047
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T07:57:00+00:00 2026-06-13T07:57:00+00:00

As a first project I plan on making a teensyduino ambient light with different

  • 0

As a first project I plan on making a teensyduino ambient light with different light modes, which are checked in a big switch statement – now I want to switch from one mode to another by pressing a button.

googling lead me to using interrupts, but there is one point that is not clear – if I press the button during an expensive function, which takes long time and has many variables in use, what happens if i call the main loop from the interrupt, does the remaining state of remain in the ram and leads to a stackoverflow if I do switch too many times or is it cleared.

Here some code:

const int speed = 30 //milliseconds
const int modes = 11; //maximum number of modes
const int red   = 15;
const int green = 14;
const int blue  = 12;

volatile int mode  = 0;

void setup() {
    pinMode(red   , OUTPUT);
    pinMode(green , OUTPUT);
    pinMode(blue  , OUTPUT);
    randomSeed(analogRead(0));
    Serial.begin(9600);
    attachInterrupt(0,incMode,CHANGE); // 0 -> digital pin 2
}
void loop()  {
    switch(mode){
        case 0:{
            Serial.println("powerdown");
            setAll(0);
            delay(1000);
            break;
        }
        \\...
        case modes:{
            \\ expensive long function
        }
    }
}
void blinkAll(int times){
    for(int i=1;i <= times;i++){
        setAll(255);
        delay(speed*17);
        setAll(0);
        delay(speed*17);
    }
}

void setAll(int bright){
        analogWrite(red   , bright);
        analogWrite(green , bright);
        analogWrite(blue  , bright);
}
void incMode(){
    delay(speed);
    blinkAll(2); //to indicate mode has changed
    mode = (mode+1) % (modes+1); //switch starts with 0 so use "% modes+1"!
    Serial.println("mode increased");
    //--> loop();
    //--> would resume the main loop but lead to a stackoverflow i presume
}

How would I break out of the running function without delay and stack pollution.
I know I could just set the mode and wait until the function has ended, but if I have a mode that takes minutes to end I want to be able to switch from it immediately.

PS.: Though I am using a teensyduino, I will use the arduino tag, and as I don’t know what language the arduinio uses the tags c/c++. Please change this if it is not appropriate.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-13T07:57:01+00:00Added an answer on June 13, 2026 at 7:57 am

    You would eventually overflow the stack if you were to reenter main from the interrupt handler multiple times recursively. Additionally, since you’ll still be in the interrupt handler as far as the hardware is concerned, you’ll have all kinds of weirdness – in particular, interrupts are blocked when you’re already in an interrupt, which means delay() won’t work and millis() won’t count up, and various other things will be broken as well unless you figure out some way to manually re-enable interrupts.

    A better way to solve this would be to make your ‘expensive long function’ instead be a state machine driven by a cheap, short function that is called very frequently. Your interrupt handler can then simply set a flag that is checked on entry into this function, at which point the current mode (ie, current state machine) is changed.

    This approach also makes it easier to define new lighting modes. For example, you could define something like this:

    struct phase {
      unsigned char r, g, b, delay;
    };
    
    unsigned long t_nextPhase;
    volatile struct phase *forceMode = NULL;
    struct phase *mode = blinkAll;
    int nextPhase = 0;
    
    struct phase blinkAll[] = {
      { 255, 255, 255, 17 },
      { 0, 0, 0, 17 },
      { 0, 0, 0, 255 } // loop sentinel
    };
    
    void lighting_kernel() {
        noInterrupts(); // ensure we don't race with interrupts
        if (forceMode) {
            mode = forceMode;
            forceMode = NULL;
            t_nextPhase = millis();
            nextPhase = 0;
        }
        interrupts();
    
        if (t_nextPhase > millis()) {
            return;
        }
    
        struct phase *cur_phase;
        do {
            cur_phase = mode[nextPhase++];
            if (cur_phase->delay == 255) {
                nextPhase = 0;
            }
        } while (cur_phase->delay == 255);
    
        analogWrite(red   , cur_phase->r);
        analogWrite(green , cur_phase->g);
        analogWrite(blue  , cur_phase->b);
    
        t_nextPhase = millis() + cur_phase->delay;    
    }
    

    Now to define a new lighting mode you just need a new array of colors and times, rather than writing new code. Adding things like color ramps and other such effects is left as an exercise to the reader.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm working on my first project in which I'm utilizing PHPUnit for unit testing.
I'm still just getting into MVC, and for my first real project I plan
I'm doing my first project based on ASP.NET Membership and I'm having issues with
I'm doing my first project with EF and I'm planning to go the code-first
class Project has_many :pages end class Page belongs_to :project end @project = Project.first @project.pages.list_out
im using drupal 6.15 and doing my first project in drupal . i got
i'm create a dating website using symfony 1.4 (it's my first project using symfony).
I am just starting to learn Rails and I'm creating my first project. In
I'm learning C++ for one of my CS classes, and for our first project
this is my first python project. I am having issues setting up a project

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.