HOW can I add a pushbutton to my traffic light intersection?

I have the basics down, I can make the pushbutton work but I can't have write timing. I want:
if the pushbutton is pressed it speeds up the time and makes the light green faster
IM STUCK ON HOW TO DO THAT
Problem: the green light doesn't turn off and there is a error that I don't know how to resolve. and it goes green after the button is pressed, I want it to go green but faster still in order.
PLS HELP

CODE

// digital input/output pins in use.
int green1 = 1;
int yellow1 = 2;
int red1 = 3;

int green2 = 4;
int yellow2 = 5;
int red2 = 6;

int pbutton = 12;

//variables
int status = 0;

void setup()
{
Serial.begin(9600);
pinMode(pbutton, INPUT);

pinMode(green1, OUTPUT);
pinMode(yellow1, OUTPUT);
pinMode(red1, OUTPUT);

pinMode(green2, OUTPUT);
pinMode(yellow2, OUTPUT);
pinMode(red2, OUTPUT);
}
void loop()
{
digitalWrite (red1, HIGH); //Both lights are red to stop traffic from both ways.
digitalWrite (red2, HIGH); //On the other side the lights signal red meaning the cars can't cross.
delay (1000);

digitalWrite (red1, LOW);

digitalWrite (green1, HIGH); //Here is where the first way allows cars to cross horizontally.
delay (4000);
digitalWrite (red2, HIGH); //On the other side the lights signal red meaning the cars can't cross.

digitalWrite (green1, LOW); //Cars should not begin to cross after the green signal is off.

digitalWrite (yellow1, HIGH); //The lights turn yellow in order to slow down the cars and warns the driver to stop soon.
delay (4000);
digitalWrite (yellow1, LOW);

digitalWrite (red1, HIGH); // The red light stop the cars from travelling horizontally.

digitalWrite (red2, HIGH);
delay (1000);

digitalWrite (red2, LOW);

digitalWrite (green2, HIGH); //The lights turn green for vertical traffic.
delay (4000);
digitalWrite (green2, LOW);

digitalWrite (yellow2, HIGH); //The lights turn yellow in order to slow down the cars.
delay (4000);
digitalWrite (yellow2, LOW);

digitalWrite (red2, HIGH); // The red light stop the cars from travelling vertically

digitalWrite (red1, LOW);

int button_status = digitalRead(pbutton);

if (button_status == HIGH && status == 0) {
digitalWrite(green1, HIGH);
Serial.println("LED Turned ON");
status = 1; }
else if (button_status == LOW && status == 1)
{
digitalWrite(green1,LOW );
Serial.println("LED Turned OFF");
status = 0;}
delay (100);
}

You have over 18secs of delays before the code even tries to read the push button..

Consider rewriting all you code using millis for your timing.

Then you can add code to reduce the time the system stays in RED when the button is pushed easily and responsively.

Don't use delay(). You will have to remove all delays from your code before you can add a button.

The way to eliminate delays is to change the way your loop() works. Instead of working through a linear sequence of operations, it must check its inputs and set its outputs thousands of times per second. The most important input is the millis() timer. This lets you work out when it is time to change the outputs from one state to another state.

There must be at least one variable to remember this state. When you know what state you are in, you know how long you have to wait and what state to move to next. If something different happens, like a button is pushed, then you may move to a different state.

Here's an example that should (YMMV) of your logic using millis() to time things instead of delay(). Once you get the hang of this method you'll find you can do a lot things while waiting for mundane things like traffic light "delays()".

NOTE: Compiled error-free for a 2560. Still may not work so be prepared to debug. I based the sequences on your original code but may have made an error in transcription. Not the most efficient code by any means; it's mean to show you how you can be doing multiple things at once while maintaining decent timing of events. Repeat to yourself: delay() is evil...

// digital input/output pins in use.
int green1 = 1;
int yellow1 = 2;
int red1 = 3;

int green2 = 4;
int yellow2 = 5;
int red2 = 6;

int pbutton = 12;

#define TFC_ONE     1
#define TFC_TWO     2
#define TFC_ON      true
#define TFC_OFF     false

#define BTNTMR_INTERVAL 30      //read button once every xx mS
//
#define TFCTMR_INIT     1000L   //all timers in mS
#define TFCTMR_STATE1   4000L
#define TFCTMR_STATE2   4000L
#define TFCTMR_STATE3   1000L
#define TFCTMR_STATE4   4000L
#define TFCTMR_STATE5   4000L
#define TFCTMR_STATE6   4000L       //you had ~100mS; I extended this to a more realistic number
#define TFCTMR_SHRTEN_LIM   1000L   //current state shortened to this

//traffic light states
#define TFC_STATE_INIT  0
#define TFC_STATE_1     1
#define TFC_STATE_2     2
#define TFC_STATE_3     3
#define TFC_STATE_4     4
#define TFC_STATE_5     5
#define TFC_STATE_6     6

//variables
//want these visible outside their function; easy way is to declare global
unsigned long
    timerTFCEvent,
    timerTrafficLights;
byte
    stateTrafficLights = TFC_STATE_INIT;

void setup()
{
    Serial.begin(9600);
    pinMode(pbutton, INPUT);

    pinMode(green1, OUTPUT);
    pinMode(yellow1, OUTPUT);
    pinMode(red1, OUTPUT);

    pinMode(green2, OUTPUT);
    pinMode(yellow2, OUTPUT);
    pinMode(red2, OUTPUT);

    //R, Y, G
    //set initial lamp states to both red
    SetLights( TFC_ONE, TFC_ON, TFC_OFF, TFC_OFF );
    SetLights( TFC_TWO, TFC_ON, TFC_OFF, TFC_OFF );
    timerTFCEvent = TFCTMR_INIT;
    timerTrafficLights = millis();
    
    
}//setup

void SetLights( int instance, 
                bool R, 
                bool Y, 
                bool G )
{
    if( instance == TFC_ONE )
    {
        digitalWrite( red1, R ? HIGH:LOW );
        digitalWrite( yellow1, Y ? HIGH:LOW );
        digitalWrite( green1, G ? HIGH:LOW );
        
    }//if
    else
    {
        digitalWrite( red2, R ? HIGH:LOW );
        digitalWrite( yellow2, Y ? HIGH:LOW );
        digitalWrite( green2, G ? HIGH:LOW );
        
    }//else
                    
}//SetLights

void loop()
{    
    ProcessLights();
    ReadButton();
    
}//loop


void ProcessLights( void )
{
    unsigned long
        timeNow;
    
    timeNow = millis();
    if( timeNow - timerTrafficLights < timerTFCEvent )
        return;

    timerTrafficLights = timeNow;

    //this logic could be done with a set of arrays but this works...
    
    switch( stateTrafficLights )
    {
        case    TFC_STATE_INIT:
            //setup for state 1
            //digitalWrite (red1, LOW);
            //digitalWrite (green1, HIGH); //Here is where the first way allows cars to cross horizontally.
            //delay(4000);
            SetLights( TFC_ONE, TFC_OFF, TFC_OFF, TFC_ON );
            SetLights( TFC_ONE, TFC_ON, TFC_OFF, TFC_OFF );
            timerTFCEvent = TFCTMR_STATE1;
                    
        break;

        case    TFC_STATE_1:
        //setup for state 2
            //digitalWrite (red2, HIGH); //On the other side the lights signal red meaning the cars can't cross.
            //digitalWrite (green1, LOW); //Cars should not begin to cross after the green signal is off.
            //digitalWrite (yellow1, HIGH); //The lights turn yellow in order to slow down the cars and warns the driver to stop soon.
            //delay (4000);
            SetLights( TFC_ONE, TFC_OFF, TFC_ON, TFC_OFF );
            SetLights( TFC_TWO, TFC_ON, TFC_OFF, TFC_OFF );
            timerTFCEvent = TFCTMR_STATE2;
            stateTrafficLights = TFC_STATE_2;

        break;

        case    TFC_STATE_2:
            //setup for state 3
            //digitalWrite (yellow1, LOW);
            //digitalWrite (red1, HIGH); // The red light stop the cars from travelling horizontally.
            //digitalWrite (red2, HIGH);
            //delay (1000);
            SetLights( TFC_ONE, TFC_ON, TFC_OFF, TFC_OFF );
            SetLights( TFC_TWO, TFC_ON, TFC_OFF, TFC_OFF );
            timerTFCEvent = TFCTMR_STATE3;
            stateTrafficLights = TFC_STATE_3;
            
        break;
        
        case    TFC_STATE_3:
            //setup for state 4
            //digitalWrite (red2, LOW);
            //digitalWrite (green2, HIGH); //The lights turn green for vertical traffic.
            //delay (4000);
            SetLights( TFC_ONE, TFC_ON, TFC_OFF, TFC_OFF );
            SetLights( TFC_TWO, TFC_OFF, TFC_OFF, TFC_ON );
            timerTFCEvent = TFCTMR_STATE4;
            stateTrafficLights = TFC_STATE_4;
            
        break;

        case    TFC_STATE_4:
            //setup for state 5
            //digitalWrite (green2, LOW);
            //digitalWrite (yellow2, HIGH); //The lights turn yellow in order to slow down the cars.
            //delay (4000);
            SetLights( TFC_ONE, TFC_ON, TFC_OFF, TFC_OFF );
            SetLights( TFC_TWO, TFC_OFF, TFC_ON, TFC_OFF );
            timerTFCEvent = TFCTMR_STATE5;
            stateTrafficLights = TFC_STATE_5;
            
        break;

        case    TFC_STATE_5:
            //setup for state 6
            //digitalWrite (yellow2, LOW);
            //digitalWrite (red2, HIGH); // The red light stop the cars from travelling vertically
            //digitalWrite (red1, LOW);
            SetLights( TFC_ONE, TFC_OFF, TFC_OFF, TFC_OFF );
            SetLights( TFC_TWO, TFC_ON, TFC_OFF, TFC_OFF );
            timerTFCEvent = TFCTMR_STATE6;
            stateTrafficLights = TFC_STATE_6;
            
        break;

        case    TFC_STATE_6:
            //setup for initial state
            SetLights( TFC_ONE, TFC_ON, TFC_OFF, TFC_OFF );
            SetLights( TFC_TWO, TFC_ON, TFC_OFF, TFC_OFF );
            timerTFCEvent = TFCTMR_INIT;
            stateTrafficLights = TFC_STATE_INIT;

        break;
           
    }//switch
    
}//ProcessLights

void ReadButton( void )
{
    unsigned long
        timeNow,
        timeLeft;    
    static unsigned long
        timerReadInterval = millis(); 

    timeNow = millis();
    if( timeNow - timerReadInterval < BTNTMR_INTERVAL )
        return;

    timerReadInterval = timeNow;
    
    //works on states 1 (1G/2R and 1R/2G)
    if( (stateTrafficLights == TFC_STATE_1) || (stateTrafficLights == TFC_STATE_4) )
    {
        if( digitalRead(pbutton) == HIGH )
        {
            //only shorten time to 1-second (e.g.) but don't do it if there's
            //1-sec or less remaining for that state
            timeLeft = timeNow - timerTrafficLights;
            if( timeLeft <= TFCTMR_SHRTEN_LIM )
                return;
                
            timerTrafficLights = timeNow - TFCTMR_SHRTEN_LIM;
            
        }//if
        
    }//if
    
}//ReadButtons
timerTrafficLights = millis() + TFCTMR_STATE1;

Do not add times. This will glitch once every 49 days and it may lock up for 49 days at that point.

Always use unsigned long and always use subtraction. Every use of millis should look something like this...

  if(millis()-lastTime > period) {
    lastTime = millis()

MorganS:
Do not add times. This will glitch once every 49 days and it may lock up for 49 days at that point.

Always use unsigned long and always use subtraction. Every use of millis should look something like this...

  if(millis()-lastTime > period) {

lastTime = millis()

A great point. Should have caught that.

MorganS:
Do not add times. This will glitch once every 49 days and it may lock up for 49 days at that point.

As long as timerTrafficLights is also an unsigned long, it should not glitch, ever. If timerTrafficLights is near rollover, and TFCTMR_STATE1 takes it over, the result is a quite small number: the remainder after the overflow. A bit later millis() rolls over itself, and after the expected number of millis have passed it becomes again greater than timerTrafficLights. No problem there.

Indeed you shouldn't do the addition when making a comparison, that's where the 49-day problem happens.

Blackfin:
Here's an example that should (YMMV) of your logic using millis() to time things instead of delay(). Once you get the hang of this method you'll find you can do a lot things while waiting for mundane things like traffic light "delays()".

I didn't go through the code in detail (let alone tested it, of course) but it looks like you got the at least the basic concept implemented: a finite state machine is what's called for indeed. Looks good to me.

wvmarle:
As long as timerTrafficLights is also an unsigned long, it should not glitch, ever. If timerTrafficLights is near rollover, and TFCTMR_STATE1 takes it over, the result is a quite small number: the remainder after the overflow. A bit later millis() rolls over itself, and after the expected number of millis have passed it becomes again greater than timerTrafficLights. No problem there.

Indeed you shouldn't do the addition when making a comparison, that's where the 49-day problem happens.
I didn't go through the code in detail (let alone tested it, of course) but it looks like you got the at least the basic concept implemented: a finite state machine is what's called for indeed. Looks good to me.

Just to remove the chance of the glitch I edited my post to correct the timing scheme. Thanks all.

@wvmarle Yes it is a problem. Several thousand milliseconds before the rollover it sets the future time to a small number. The next iteration of the loop sees that "now" is greater than the target time. So it proceeds with the next step immediately. So the lights flicker extremely rapidly for those few seconds or minutes.

If the now+period addition happens to land on or near the maximum long integer value AND the loop cycle takes so long that it doesn't query millis() in that last millisecond then "now" cylcles back to zero with a future time for the next step scheduled 49 days in the future. This coincidence should be rare but it is not impossible.

Ah, yes. I see it. I'm used to adding time to a certain variable during millis() based timing, but then it's only to catch up to the current millis() value, like this:

if (millis() - lastActionDone >= actionInterval) {
  lastActionDone += actionInterval;

which does not have the problem of that glitch (lastActionDone will never be greater than the current millis()), but ensures that the action is done at that frequency (on average) even if for whatever reason you're sometimes late in checking the time.

In contrast setting lastActionDone = millis() makes the next time actionInterval runs ms later than this time, so delays start to add up. This may or may not be an issue and both ways may or may not be desirable.