Reset loop during loop (with or without interrupts)

Hello,

I’m trying to get a subroutine to interrupt the loop and restart from the beginning. I’ve tried various ways to use Interrupts to do this, and after reading the forums have decided there probably isn’t a way to do it like that (my first attempts would just stop but not restart it).

My main loop is about 10 seconds long, but I want to be able to stop and restart it whenever a reset button is pressed.

Here is my code (abridged):

#include <Arduino.h>
#include "ST7036.h"
#include "LCD_C0220BiZ.h"
#include <Wire.h>

//LCD_C0220BIZ lcd = LCD_C0220BIZ ( );
ST7036 lcd = ST7036 ( 2, 20, 0x78 );

const int lcd_resetPin = 8;
const int resetPin = 2;

void setup ()
{
  pinMode(lcd_resetPin, OUTPUT);
  pinMode(resetPin, INPUT_PULLUP);
  digitalWrite(lcd_resetPin, LOW);
  digitalWrite(lcd_resetPin, HIGH);
  Serial.begin ( 57600 );
  lcd.init ();
  lcd.setContrast(10);
}

void reset()
{
    lcd.clear();
    lcd.setCursor (0,0);
    lcd.print("Sing Sing Sing!");
    delay (1000);
}

void alphabet()
{
//prints the alphabet
}

void loop()
{
  //something to reset in the middle of the alphabet
  alphabet();
}

This is just a test code to figure out what I’m doing, the actual application will be to reset a counter on a motor controller, but I also wanted to have it print “RESET COUNT”, which is where I ran into trouble.

Any ideas would be appreciated.

Thanks.

A simple "return" will get you back to the top of loop() within a couple of microseconds

If you want a responsive program you cannot use delay(). The delay() function stops everything. The beginners guide to millis() and the blink without delay example will show how to write code that does not "block".

A bit tricky to advise on a program that does not exhibit the behaviour.

Total code:

#include <Arduino.h>
#include "ST7036.h"
#include "LCD_C0220BiZ.h"
#include <Wire.h>

//LCD_C0220BIZ lcd = LCD_C0220BIZ ( );
ST7036 lcd = ST7036 ( 2, 20, 0x78 );

const int lcd_resetPin = 8;
const int resetPin = 2;

void setup ()
{
  pinMode(lcd_resetPin, OUTPUT);
  pinMode(resetPin, INPUT_PULLUP);
  digitalWrite(lcd_resetPin, LOW);
  digitalWrite(lcd_resetPin, HIGH);
  Serial.begin ( 57600 );
  lcd.init ();
  lcd.setContrast(10);
}

void reset()
{
return;
}

void alphabet()
{
  lcd.clear ();
  lcd.print("ALPHABET!");
  delay(1000);
  lcd.clear();
  lcd.setCursor ( 0, 0 );
  lcd.print ("a");
  delay (200);
  lcd.print ("b");
  delay (200);
  lcd.print ("c");
  delay (200);
  lcd.print ("d");
  delay (200);
  lcd.print ("e");
  delay (200);
  lcd.print ("f");
  delay (200);
  lcd.print ("g");
  delay (500);
  lcd.print ("h");
  delay (200);
  lcd.print("i");
  delay(200);
  lcd.print("j");
  delay(200);
  lcd.print("k");
  delay(200);
  lcd.print("l");
  delay(100);
  lcd.print("m");
  delay(100);
  lcd.print("n");
  delay(100);
  lcd.print("o");
  delay(100);
  lcd.print("p");
  delay(500);
  lcd.setCursor ( 1, 0 );
  lcd.print("q");
  delay(200);
  lcd.print("r");
  delay(200);
  lcd.print("s");
  delay(500);
  lcd.print("t");
  delay(200);
  lcd.print("u");
  delay(200);
  lcd.print("v");
  delay(500);
  lcd.print("w");
  delay(500);
  lcd.print("x");
  delay(500);
  lcd.print("y");
  delay(200);
  lcd.print("&");
  delay(200);
  lcd.print("z");
  delay(1000);
}

void loop()
{
  attachInterrupt(resetPin, reset, FALLING);
  alphabet();
}

but I still couldn’t print anything from the ISR.

but I still couldn't print anything from the ISR.

I don't see where you are trying to print from the ISR (reset()).

You don't have to attach the interrupt every time through loop(). Just do it once in setup(). Look at the syntax for attachInterrupt. The interrupt number is not the pin number.

If you do try to print in an ISR, Serial.print depends on interrupts. Interrupts are disabled during an ISR.

So I could do

#include <Arduino.h>
#include "ST7036.h"
#include "LCD_C0220BiZ.h"
#include <Wire.h>

//LCD_C0220BIZ lcd = LCD_C0220BIZ ( );
ST7036 lcd = ST7036 ( 2, 20, 0x78 );

const int lcd_resetPin = 8;
const int resetPin = 2;

void setup ()
{
  pinMode(lcd_resetPin, OUTPUT);
  pinMode(resetPin, INPUT_PULLUP);
  digitalWrite(lcd_resetPin, LOW);
  digitalWrite(lcd_resetPin, HIGH);
  Serial.begin ( 57600 );
  lcd.init ();
  lcd.setContrast(10);
  attachInterrupt(digitalPinToInterrupt(resetPin), reset, FALLING);
}

void reset()
{
lcd.clear();
lcd.setCursor(0,0);
//lcd.print("SING, SING, SING!");
//lcd.setCursor(0,0);
return;

}

void alphabet()
{
//prints alphabet - see above
}

void loop()
{
  alphabet();
}

and I guess just print the other stuff at the beginning of the loop.

My arduino is having problems uploading, so I can’t test the code :frowning:

Got it to upload, that last attempt didn’t work either - the reset button just stops the routine and doesn’t restart it at all.

Here’s what I have now:

#include <Arduino.h>
#include "ST7036.h"
#include "LCD_C0220BiZ.h"
#include <Wire.h>

//LCD_C0220BIZ lcd = LCD_C0220BIZ ( );
ST7036 lcd = ST7036 ( 2, 20, 0x78 );

const int lcd_resetPin = 8;
const int resetPin = 2;

void reset()
{
lcd.setCursor(0,0);
return;
}

void setup ()
{
  pinMode(lcd_resetPin, OUTPUT);
  pinMode(resetPin, INPUT_PULLUP);
  digitalWrite(lcd_resetPin, LOW);
  digitalWrite(lcd_resetPin, HIGH);
  Serial.begin ( 57600 );
  lcd.init ();
  lcd.setContrast(10);
  attachInterrupt(digitalPinToInterrupt(resetPin), reset, FALLING);
}

void loop()
{
  alphabet();
}

void alphabet()
{
  lcd.clear ();
  lcd.print("ALPHABET!");
  delay(1000);
  lcd.clear();
  lcd.setCursor ( 0, 0 );
  lcd.print ("a");
  delay (200);
  lcd.print ("b");
  delay (200);
  lcd.print ("c");
  delay (200);
  lcd.print ("d");
  delay (200);
  lcd.print ("e");
  delay (200);
  lcd.print ("f");
  delay (200);
  lcd.print ("g");
  delay (500);
  lcd.print ("h");
  delay (200);
  lcd.print("i");
  delay(200);
  lcd.print("j");
  delay(200);
  lcd.print("k");
  delay(200);
  lcd.print("l");
  delay(100);
  lcd.print("m");
  delay(100);
  lcd.print("n");
  delay(100);
  lcd.print("o");
  delay(100);
  lcd.print("p");
  delay(500);
  lcd.setCursor ( 1, 0 );
  lcd.print("q");
  delay(200);
  lcd.print("r");
  delay(200);
  lcd.print("s");
  delay(500);
  lcd.print("t");
  delay(200);
  lcd.print("u");
  delay(200);
  lcd.print("v");
  delay(500);
  lcd.print("w");
  delay(500);
  lcd.print("x");
  delay(500);
  lcd.print("y");
  delay(200);
  lcd.print("&");
  delay(200);
  lcd.print("z");
  delay(1000);
}

So, I’m kind of back where I started.

Also, just having [return] in the ISR doesn’t make anything happen.

Thanks though.

collin_bc: So, I'm kind of back where I started.

You obviously have not studied the links in Reply #2.

The demo Several Things at a Time is an extended example of BWoD and illustrates the use of millis() to manage timing without blocking. It may help with understanding the technique.

And you can print the alphabet with a few lines of code - something like this

void loop() {
 static char currentLetter = 'a';
 lcd.print (currentLetter);
 currentLetter ++;
 if (currentLetter > 'z') {
   currentLetter = 'a';
 }
}

...R

I totally did not know that about printing the alphabet!

From what I understand about the BWoD and Several things at a time, the idea is to avoid using delay whenever possible and use millis() instead. I'll try that.

Appreciate the feedback, thanks.