Reset Arduino on button press - ALT's to stopping a Loop!

So, I've been working on this project for a few days now. I've bought a NeoPixel ring, hooked an IR reciever and IR controller to function as controller for the ring. If I press the button UP for example, the NeoPixel Ring displays a rainbow function for a set amount of times. I've gotten so far as to program in a few different functions for the NeoPR to display on the press of different buttons. HOWEVER, these functions go on for a minute or more and I need a way to force quit them. A power down button. I've tried several ways to program in a quit button but to no avail. Nothing budges the Loop that the functions are in. So my question is 1. How do I write a function that stops my Loop completely, turning the NeoPixel off at least. 2. Can I write my functions outside a Loop, what other ways do I have?

My knowledge of programming is slim, not hopeless but slim.

I might have phrased this wrong, perhaps. If so, please ask me more questions specifically that I can answer to provide some light in the matter.

Sounds like you might need an ISR (Interrupt Service Routine).
https://www.arduino.cc/en/Reference/AttachInterrupt

Without seeing your code it is hard to tell the best way to help.

You have not posted any code but I assume that you are using delay() in a for loop, perhaps nested for loops. If you were to abandon the use of delay() and use millis() for timing then you could read a switch much more often (each time through loop()) which will make the system more responsive.

Look at Several things at the same time for inspiration.

Okay, first of all thank you for the quick reply, much appreciated! :smiley:

Code is as such, however I've removed some repetition for simplicity.


#include <Adafruit_NeoPixel.h>
#ifdef AVR
#include <avr/power.h>
#endif
#define NUMPIXELS 16
#define PIN 9
#include <IRremote.h>

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

int RECV_PIN = 11;

#define code1 43095

IRrecv irrecv(RECV_PIN);

decode_results results;

int delayval = 50;

void setup(){
Serial.begin(9600);
irrecv.enableIRIn();
pixels.begin();

}

void loop() {
if (irrecv.decode(&results)) {
unsigned int value = results.value;
switch(value) {
case code1:

for(int i=0;i<NUMPIXELS;i++){

pixels.setPixelColor(i, pixels.Color(0,150,0));

pixels.show();

delay(delayval);
}

break;

}

Serial.println(value);
irrecv.resume();
}
}


So I need a way to make the function in case code1 stop if i press a button, prefferably.

So, UKHeliBob what you're suggesting is that I limit my Ring function to be a short loop, so the stop will be more responsive. So if my loop takes 10 seconds, if I then press my "stop" button after 5 seconds it will make the loop stop 5 seconds later? When the loop makes a loop (ha)?

unsigned int value = results.value;

The value member of the results struct is NOT an unsigned int.

You need to separate the reading of the IR device from acting on the value last read.

You need to completely rewrite what happens in the code1 case. On every pass through loop(), not in a for loop, it may, or may not, be time to change state. If it is, you need to record when that happens, and make the appropriate changes.

Robin2 has some good examples of doing more than one thing at a time. The blink without delay example does, too. Read, understand, and embrace the blink without delay philosophy, and you'll never use delay() again (or a for loop that way, either).