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