Button press to freeze program

Hi again, as I would like to ask how to freeze a program once a button is pressed

To save you time I've included only a part of my scetch.

ButtonValue = digitalRead(Button);

  if(ButtonValue != 0){
   //the line of coding to freeze it
  }
   else{
   //let it keep running, so nothing here
   }

To freeze your sketch: while(true);

:slight_smile: thank you, it worked!!!
But how I mean, while (true) what's next, here's my program

ButtonValue3 = digitalRead(Button3);
  if(ButtonValue3 != 0){
    digitalWrite ( 2, LOW);
    while(true);
  }

I know it works now, but I'm wondering how?
Anyways I was wondering because it did stop the program, but the lights were still on, is there a way to get the nano's pow light off?

is there a way to get the nano's pow light off?

Yes. Disconnect the power.

Squidsirymchenry:
I know it works now, but I'm wondering how?

It's called an "Infinite Loop". It repeatedly executes the "Null Statement" (';') as long as the value 'true' is true.

Squidsirymchenry:
Anyways I was wondering because it did stop the program, but the lights were still on, is there a way to get the nano's pow light off?

The only way to turn off the power light is to turn off the power.

Or remove the light. That saves power too.

Well, @morganS, I mean if you disassemble the nano....
Is it possible to press the button, freeze the code, and then when it's pressed, return to normal.What I'm trying to do is that with a button the code stops and once pressed again make it start again. NOT THE RESET, that has to be in the case, my stuff has to be outside. It takes a while for the aurdino to load, so I would like to cut it. Or would I have to use hardware?

Thanks,
squidsirymchenry

Hi,
Look up

https://www.arduino.cc/en/Reference/While

Tom... :slight_smile:

Could use sleep mode with an interrupt on say INT0. Flip a global Boolean to keep a track on what status the device should be in.

Have a feeling they are asking about the led simply to save power...

Also...is this say "stop the code during a sequence of events" and resume at the end point when pressed?
Maybe using a byte to store the "current position" in the code which is saved on sleeping...the code could resume from that point...maybe a better way though?

Squidsirymchenry:
Is it possible to press the button, freeze the code, and then when it's pressed, return to normal.

In simple terms that is not possible. Think about it. if the program is frozen how could it detect your second button press to start it working again.

What you can do is break up the program into functions and call a function (or not) depending on the state of a variable. So your code in loop() could be something like this

void loop() {
   checkPauseButton();
   if (pauseSelected == false) {
      doTheStuff();
   }
}

The code in your checkPauseButton() function will toggle the variable pauseSelected when you press the button.

The code in your function doTheStuff() [I know it's a horrid name] is the code that you want to run, or pause.

Note that the code in doYourStuff() must be written so that it allows loop() to repeat very frequently - ideally hundreds of times per second.

Have a look at the code in the demo Several Things at a Time

...R

@Johnny, can you please provide an example, as I said, I am a rookie at this.
@Robin2, you got my point, but um you still haven't explained how to pause it...
So I was thinking that I could use a delay function and cancel it?
I have this new idea below, but it's acting funny, it kinda works,
Please help!!
squidsirymchenry

void sleep(void) {
 int newbutton = digitalRead(button);
  if (newbutton != 0)
  {
    attachInterrupt(8, pinInterrupt, LOW);
    set_sleep_mode(SLEEP_MODE_STANDBY);
    sleep_enable();
    Serial.println("Status : sleeping");
    sleep_mode();
  }
}
void pinInterrupt(void)
{
  int newbutton2 = digitalRead(button2);
  if (newbutton2 != 0)
  {
  sleep_disable();
  Serial.println("Status : Awake");
  detachInterrupt(8);
}
}

Squidsirymchenry:
@Robin2, you got my point, but um you still haven't explained how to pause it...
So I was thinking that I could use a delay function and cancel it?

I think I did explain it and I gave you a program outline to do it.

I also told you that you need to keep the program running so it can detect the next button press and that means that you CANNOT use delay().

...R

You see this is the difference between a 5-star pro(robin2) and a no star newbie. But as I said, the program outline doesn't ring a bell. I know the outline, but what is the code to make it sleep? You said in your code to dotheStuff, well I don't know what to put there. Here we go, here's my full code.

#include <avr/interrupt.h>
#include <avr/power.h>
#include <avr/sleep.h>
#include <avr/io.h>
int total;
int readings;
int irnow;
int average;
int newaverage;
int potValue;
const byte pot = A3;
const byte button = 8;
const byte button2 = 10;
void setup() {
  Serial.begin(9600);
  pinMode(2, OUTPUT);
  pinMode(pot, INPUT);
  pinMode(button, INPUT);
  pinMode(button2, INPUT);
}
void loop() {
  irnow = 0;
  while ( irnow < 9)
  {
    readings = analogRead(A1);
    total = total + readings;
    irnow = irnow + 1;
  }
  average = total / 9;
  newaverage = map(average, 0, 1023, 500, 200);
  Serial.println(newaverage);
  potValue = analogRead(pot);
  int mappedpot = map(potValue, 0, 1023, 0, 90);


  if (newaverage < 390 - mappedpot)
  {
    if (newaverage > 385 - mappedpot)
    {
      digitalWrite(2, HIGH);
      delay(1000);
    }

    if (newaverage <= 370 - mappedpot)
    {
      digitalWrite(2, HIGH);
      delay(100);
    }
  }
  else  {
    digitalWrite(2, LOW);
    delay(100);
  }

  average = 0;
  total = 0;
  newaverage = 0;
}

void sleep(void) {
 int newbutton = digitalRead(button);//I don't know what to put in from here to the end, don't judge
  if (newbutton != 0)
  {
    attachInterrupt(8, pinInterrupt, LOW);
    set_sleep_mode(SLEEP_MODE_STANDBY);
    sleep_enable();
    Serial.println("Status : sleeping");
    sleep_mode();
  }
}
void pinInterrupt(void)
{
  int newbutton2 = digitalRead(button2);
  if (newbutton2 != 0)
  {
  sleep_disable();
  Serial.println("Status : Awake");
  detachInterrupt(8);
}
}

So, I copied all your code and changed the name of loop() to doTheStuff(). Then I pasted Robin's loop() function in.

That function requires a global variable called pauseSelected and it calls checkPauseButton(), which is a function we need to write.

Looking at your attempt to use the sleep library, I worked out which pin is the pause button and removed those, replacing with checkPauseButton(). This is a little complex because it needs to 'debounce' the button. That is, it ignores any changes to the button state which occur less than 10ms after the first change is detected.

Along the way, I also created a named constant for 9, since that was used in 2 places in the program and those two places must always have the same value. I also moved the zeroing of total back to the point immediately before you start adding things to it.

The doTheStuff() can't spend a lot of time in delays, so I removed all delays. It's going to end up printing a lot of crap to the Serial Monitor. Once you've verified for yourself that it's working OK, remove all those prints.

int total;
int readings;
int irnow;
int average;
int newaverage;
int potValue;
bool pauseSelected = false;
const byte pot = A3;
const byte button = 8; //the pause button - should be connected between this pin and ground so it reads LOW when pressed
const byte button2 = 10;
const int NumberOfIRReadingsToAverage = 9;

void setup() {
  Serial.begin(9600);
  pinMode(2, OUTPUT);
  pinMode(pot, INPUT);
  pinMode(button, INPUT);
  pinMode(button2, INPUT);
}

void loop() {
  checkPauseButton();
  if (pauseSelected == false) {
    doTheStuff();
  }
}

void doTheStuff() {
  irnow = 0;
  total = 0;
  while ( irnow < NumberOfIRReadingsToAverage)
  {
    readings = analogRead(A1);
    total = total + readings;
    irnow = irnow + 1;
  }
  average = total / NumberOfIRReadingsToAverage;
  newaverage = map(average, 0, 1023, 500, 200);
  Serial.println(newaverage);
  potValue = analogRead(pot);
  int mappedpot = map(potValue, 0, 1023, 0, 90);


  if (newaverage < 390 - mappedpot)
  {
    if (newaverage > 385 - mappedpot)
    {
      digitalWrite(2, HIGH);
    }

    if (newaverage <= 370 - mappedpot)
    {
      digitalWrite(2, HIGH);
    }
  }
  else  {
    digitalWrite(2, LOW);
  }
}

void checkPauseButton() {
  const unsigned long DebounceInterval = 10; //milliseconds - ignore button state flips faster than this
  static unsigned long lastButtonPress;
  static int lastButtonState = HIGH;
  int buttonState = digitalRead(button);
  if (lastButtonState != buttonState)
  {
    //the button has changed since we last looked at it
    lastButtonState = buttonState;
    if (millis() - lastButtonPress > DebounceInterval)
    {
      //it last changed a long time ago, so this is a new event
      lastButtonPress = millis(); //record the time that it changed
      if (buttonState == LOW)
      {
        pauseSelected = !pauseSelected; //flip the pause state
      }
    }
  }
}

WOW! Thank you, I will test it during this week and will get back to you if I have problems, karma added! Even if it doesn't work

keep in touch,
squidsirymchenry

Ok, it stopped but there were 2 problems.

  1. it took quite a while to stop, no like under 1 second
    and 2. I couldn't get it back on

thanks,
squidsirymchenry

Sorry, that should have been...

  pinMode(button, INPUT_PULLUP);

It should be much more responsive if you change that.

MorganS:
So, I copied all your code and changed the name of loop() to doTheStuff(). Then I pasted Robin's loop() function in.

Thanks - nice tutorial.

...R

It worked perfectly, thank you, but where do I put digitalWrite LOW in there. If I was in the inferred's way when I pressed the button, the motor keeps running. If I stay clear then press the button, it stays clear. Please tell me how to do this!!Thank you!!!
BR,
squidsirymchenry