Adding interrupt to shift register

Hey all, I'm really close to completing my project. All is left is adding interrupt to my existing code so that my light pattern will reset and starts back over instead of having the program keep running even when not in use. This is my code, I tried using the button code in the library but it doesnt work keep giving error codes. It doesnt happen when I code it in with individual ports where the LEDs are but when it's with the shift reg. It wont let me use interrupt for some reason. I have the shift reg daisy chain and they're the 74HC595n shift reg.

int latchPin = 8;
int dataPin = 11;
int clockPin = 12;
int dato = 0;
int framespeed = 300;

int first = 0;  // shifter 1
int second = 0; // shifter 2
int third = 0;  // shifter 3
int fourth = 0; // shifter 4
int fifth = 0;  // shifter 5

void setup() {
 pinMode (dataPin, OUTPUT);
 pinMode (clockPin, OUTPUT);
 pinMode (latchPin, OUTPUT);
}

void loop() {
 
 lightLeds (0b11111111, 0b00000000, 0b00000000, 0b00000000, 0b00000000); // frame 1
 lightLeds (0b00000000, 0b11111111, 0b00000000, 0b00000000, 0b00000000); // frame 2
 lightLeds (0b00000000, 0b00000000, 0b11111111, 0b00000000, 0b00000000); // frame 3
 lightLeds (0b00000000, 0b00000000, 0b00000000, 0b11111111, 0b00000000); // frame 4
 lightLeds (0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b11111111); // frame 5
}

void lightLeds (int fifth, int fourth, int third, int second, int first) {
 digitalWrite (latchPin, LOW);
 shiftOut (dataPin, clockPin, LSBFIRST, first);
 shiftOut (dataPin, clockPin, LSBFIRST, second);
 shiftOut (dataPin, clockPin, LSBFIRST, third);
 shiftOut (dataPin, clockPin, LSBFIRST, fourth);
 shiftOut (dataPin, clockPin, LSBFIRST, fifth);
 digitalWrite (latchPin, HIGH);
 delay (framespeed); 
}

You don't need interrupts. Just add some button code and if it does not work or compile, show the code (and errors).

You might want to get rid of delay in favour of millis() but I don't think that that is necessary in this case.

Well that's what I had did, I use the button code in the library for it and it stated that " buttonState " does not name a type. But when I use the same code on individual pin mode for each led it works fine. Cause I can tell it when to cut off and which one verses a shift reg it just keeps giving me error. And there will be no button I'm actually going to use the interrupt pin mode port and wire it up to a turn indicator in the car. So when apply itll pick up the signal for the flasher and when it's off itll reset the program from the beginning. Interrupt is the only feature I know that will let me do that will restarting the pattern instead of starting from wherever the pattern is when the LEDs are on. Confusing sorry...

Interrupt is the only feature I know

Then you should do some more learning. That is the LAST way I would solve this problem. If you just want the sequence to start over then write a state machine that starts the sequence from the beginning when it goes into that state. No interrupt needed and you don't have to reset the board to get the thing to start over. Just write good code.

You can get help here, but you gotta start. You get your best effort coded up and post it here with the errors or the misbehavior noted and we can help you work on it.

What we really can't do is help you go through some convoluted weird hack to kinda-sorta accomplish something just to save you having to learn to write code.

Would be nice if I have any prior knowledge at all to any type of coding. But in honesty I dont. Beside what I got now I’m not planning on being a master coder, I just need to get this one project done and that’s it. Not planning on revisiting the whole coding industry im a body man/painter and fabricator and just need this for a project vehicle but honestly if it’s that complicated I’ll figure it out.

OK
Instead of barking up the wrong tree, you should have posted your failing code and the error that you got when you got stuck; we could easily have pointed out what went wrong so it coud be corrected.

My way of teaching often differs a little from that of others, so here is how you can work towards the end result.

What you’re looking for is a counter that keeps track of your current frame in the sequence

void loop()
{
  // current frame; will be remembered between iterations of loop()
  static byte currentFrame = 0;

  ...
  ...
}

I’ve set the initial value to 0 which will indicate that the sequence is not running.

Your sequence consists of 5 frames. Each time a frame is finished, you can increment the counter.

You can use a switch/case statement to take action depending on the value of currentFrame.

void loop()
{
  // current frame; will be remembered between iterations of loop()
  static byte currentFrame = 0;

  switch (currentFrame)
  {
    case 1:
      lightLeds (0b11111111, 0b00000000, 0b00000000, 0b00000000, 0b00000000); // frame 1
      currentFrame++;
      break;
    case 2:
      lightLeds (0b00000000, 0b11111111, 0b00000000, 0b00000000, 0b00000000); // frame 2
      currentFrame++;
      break;
    case 3:
      lightLeds (0b00000000, 0b00000000, 0b11111111, 0b00000000, 0b00000000); // frame 3
      currentFrame++;
    case 4:
      lightLeds (0b00000000, 0b00000000, 0b00000000, 0b11111111, 0b00000000); // frame 4
      currentFrame++;
      break;
    case 5:
      lightLeds (0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b11111111); // frame 5
      // start sequence all over
      currentFrame = 1;
      break;
  }
}

Now you need a means to start the sequence. You have a button connected to pin 2 (or 3)? So you define a buttonPin at the top of your code where you define the other pins.

The code below make use of the internal pullup resistor so the pin doesn’t float and gives false readings

int buttonPin = 2;

int latchPin = 8;
...
...

void setup() 
{
  // shift register pins
  ...
  ...

  // button pin; connected between pin to GND
  pinMode(buttonPin, INPUT_PULLUP);
}

...
...

As the button is wired between pin and GND, a pressed button will now read low. To keep your code readable you can add a line at the top of your code.

#define ISPRESSED LOW
...
...

If you use a switch instead of a button, you can change the word ISPRESSED to something else, e.g. ISTURNING.

Now the only thing remaining is the reading the button and starting the sequence.

void loop()
{
  // current frame; will be remembered between iterations of loop()
  static byte currentFrame = 0;

  // if button is pressed
  if (digitalRead(buttonPin) == ISPRESSED)
  {
    // only if the sequence is not started
    if (currentFrame == 0)
    {
      // start the sequence
      currentFrame = 1;
    }
  else
  {
    // stop the sequence
    currentFrame = 0;

    // todo
    // switch all lights off?
    // you can use a call to lightLeds with arguments for all lights off.
  }

  ...
  ...
}

So when the button is pressed, it checks if currentFrame equals 0 (sequence not started) and in that case sets the currentFrame to the first frame of the sequence. The switch statement will now run the first case, increment the currentFrame and the next time loop is called the switch will run the second case and so on. Once the last frame is finished, the currentFrame is reset to 1 and the sequence starts all over.

If the button is released, you set currentFrame to 0. The switch/case does not have a case for that so the sequence is stopped. You might want to switch all lights off at that point; I’ll leave that up to you.

Alternatively, you can implement a case 0 in the switch that switches the lights off. It’s probably a little neater. Do not increment the currentFrame in that case.

Because your lightLeds takes 300 ms, there is no need for a debounce of the button.

Full code where case 0 is added to the switch

// button wired from pin to GND, so logic is reversed
#define ISPRESSED LOW

int buttonPin = 2;

int latchPin = 8;
int dataPin = 11;
int clockPin = 12;

int dato = 0;
int framespeed = 300;

int first = 0;  // shifter 1
int second = 0; // shifter 2
int third = 0;  // shifter 3
int fourth = 0; // shifter 4
int fifth = 0;  // shifter 5

void setup()
{
  pinMode (dataPin, OUTPUT);
  pinMode (clockPin, OUTPUT);
  pinMode (latchPin, OUTPUT);

  // button from pin to GND
  pinMode(buttonPin, INPUT_PULLUP);
}

void loop()
{
  // current frame; will be remembered between iterations of loop()
  static byte currentFrame = 0;

  // if button is pressed
  if (digitalRead(buttonPin) == ISPRESSED)
  {
    // only if the sequence is not started
    if (currentFrame == 0)
    {
      // start the sequence
      currentFrame = 1;
    }
  }
  else
  {
    // stop the sequence
    currentFrame = 0;
  }

  switch (currentFrame)
  {
    case 0:
      // switch the lights off
      ...
      ...
      // do not change current frame
      break;
    case 1:
      lightLeds (0b11111111, 0b00000000, 0b00000000, 0b00000000, 0b00000000); // frame 1
      currentFrame++;
      break;
    case 2:
      lightLeds (0b00000000, 0b11111111, 0b00000000, 0b00000000, 0b00000000); // frame 2
      currentFrame++;
      break;
    case 3:
      lightLeds (0b00000000, 0b00000000, 0b11111111, 0b00000000, 0b00000000); // frame 3
      currentFrame++;
    case 4:
      lightLeds (0b00000000, 0b00000000, 0b00000000, 0b11111111, 0b00000000); // frame 4
      currentFrame++;
      break;
    case 5:
      lightLeds (0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b11111111); // frame 5
      currentFrame = 1;
      break;
  }
}

void lightLeds (int fifth, int fourth, int third, int second, int first)
{
  digitalWrite (latchPin, LOW);
  shiftOut (dataPin, clockPin, LSBFIRST, first);
  shiftOut (dataPin, clockPin, LSBFIRST, second);
  shiftOut (dataPin, clockPin, LSBFIRST, third);
  shiftOut (dataPin, clockPin, LSBFIRST, fourth);
  shiftOut (dataPin, clockPin, LSBFIRST, fifth);
  digitalWrite (latchPin, HIGH);
  delay (framespeed);
}

Notes
1)
This will immediately terminate the sequence.
2)
With car stuff, you will probably apply a HIGH to the pin. In taht case you need a pulldown resistor
and make the following changes

#define ISPRESSED HIGH

and

 pinMode(buttonPin, INPUT); // <<-- fixed

Pdiep1289:
Would be nice if I have any prior knowledge at all to any type of coding. But in honesty I dont. Beside what I got now I'm not planning on being a master coder, I just need to get this one project done and that's it. Not planning on revisiting the whole coding industry im a body man/painter and fabricator and just need this for a project vehicle but honestly if it's that complicated I'll figure it out.

Yeah but right now you're like someone saying, "I can't get my boat running so will someone please help me waterproof my car and put skis on it!" when what you really need to do is ask for help with the boat.

If you're really just not into learning it and want someone to just give you some code, there is the "Gigs and Collaborations" section of this forum where you can pay someone to write code for you.