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