void state1();
void state2();
void state3();
void state4();
void state5();
void state6();
void (*states[])(void) = {
state1, state2, state3, state4, state5, state6
};
void setup() {
Serial.begin(115200);
}
void loop() {
for(int i = 0; i < 6; i++){
states[i]();
}
}
void state1() {
if(Serial) {Serial.println("State 1");}
delay(2000);
}
void state2() {
if(Serial) {Serial.println("State 2");}
delay(2000);
}
void state3() {
if(Serial) {Serial.println("State 3");}
delay(2000);
}
void state4() {
if(Serial) {Serial.println("State 4");}
delay(2000);
}
void state5() {
if(Serial) {Serial.println("State 5");}
delay(2000);
}
void state6() {
if(Serial) {Serial.println("State 6");}
delay(2000);
}
#define C6 1047
volatile bool pedRequest = false;
const int RED_TRAFFIC = 8;
const int AMBER_TRAFFIC = 7;
const int GREEN_TRAFFIC = 6;
const int DONT_CROSS = 5;
const int CROSS = 4;
const int PED_BUTTON = 2;
const int PED_SOUNDER = 3;
void setup() {
Serial.begin(115200);
pinMode(RED_TRAFFIC, OUTPUT);
pinMode(AMBER_TRAFFIC, OUTPUT);
pinMode(GREEN_TRAFFIC, OUTPUT);
pinMode(DONT_CROSS, OUTPUT);
pinMode(CROSS, OUTPUT);
pinMode(PED_BUTTON, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(PED_BUTTON), intHandler, FALLING);
}
void intHandler() {
pedRequest = true;
}
void state1() {
int leds[] = {
RED_TRAFFIC, AMBER_TRAFFIC, GREEN_TRAFFIC,
DONT_CROSS, CROSS};
if(Serial) {Serial.println("Testing LEDs");}
for (int i = 0; i < 5; i++) {
digitalWrite(leds[i], HIGH);
delay(500);
digitalWrite(leds[i], LOW);
}
if(Serial) {Serial.println("Testing Sound");}
for(int i = 0; i < 5; i++) {
tone(PED_SOUNDER, C6, 250);
delay(500);
}
noTone(PED_SOUNDER);
if(pedRequest) {
pedRequest = false;
if(Serial) {
Serial.println("Pedestrian Button Pressed");
}
}
}
void state2() {
if(Serial) {
Serial.println("State 2");
}
unsigned long startMillis = millis();
digitalWrite(GREEN_TRAFFIC, LOW);
digitalWrite(DONT_CROSS, HIGH);
digitalWrite(AMBER_TRAFFIC, HIGH);
do {
}while((unsigned long)(millis() - startMillis) < 3000);
}
unsigned long milliMe;
unsigned long stopVal = 2000ul;
unsigned long startVal = 0xFFFFFFFF;
unsigned int target = 1000;
void setup() {
Serial.begin(115200);
startVal -= 10000;
milliMe = startVal;
}
void loop() {
unsigned long lastMilli = milliMe;
for(int i = 0; i < 32767; i++) {
milliMe++;
if((unsigned long)(milliMe - lastMilli) >= target) {
Serial.print("Simulated mills() at: ");
Serial.print(milliMe);
Serial.print(", lastMilli: ");
Serial.print(lastMilli);
Serial.println(" difference >= target");
lastMilli = milliMe;
}
if(milliMe < startVal && milliMe > stopVal) {
break;
}
}
}
The complete program
#define C6 1047
#define BEEP 250
#define THRD_SEC 330
#define HALF_SEC 500
#define SECS_3 3000
#define SECS_2 2000
#define SECS_7 7000
#define SECS_6 6000
#define MAX_WAIT 10000
void state1();
void state2();
void state3();
void state4();
void state5();
void state6();
void (*states[])(void) = {
state1, state2, state3, state4, state5, state6
};
volatile bool pedRequest = false;
const int RED_TRAFFIC = 8;
const int AMBER_TRAFFIC = 7;
const int GREEN_TRAFFIC = 6;
const int DONT_CROSS = 5;
const int CROSS = 4;
const int PED_BUTTON = 2;
const int PED_SOUNDER = 3;
void setup() {
pinMode(RED_TRAFFIC, OUTPUT);
pinMode(AMBER_TRAFFIC, OUTPUT);
pinMode(GREEN_TRAFFIC, OUTPUT);
pinMode(DONT_CROSS, OUTPUT);
pinMode(CROSS, OUTPUT);
pinMode(PED_BUTTON, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(PED_BUTTON), intHandler, FALLING);
}
void loop() {
for(int i = 0; i < 6; i++){
states[i]();
}
}
void intHandler() {
pedRequest = true;
}
void state1() {
pedRequest = false;
unsigned long startMillis = millis();
digitalWrite(DONT_CROSS, HIGH);
digitalWrite(GREEN_TRAFFIC, HIGH);
digitalWrite(AMBER_TRAFFIC, LOW);
while(true) {
unsigned long currentMillis = millis();
if(pedRequest) {
if((unsigned long)(currentMillis - startMillis) >= MAX_WAIT) {
break; // pedestrian request and minimum time condition met
}
}
}
}
void state2() {
unsigned long startMillis = millis();
digitalWrite(GREEN_TRAFFIC, LOW);
digitalWrite(DONT_CROSS, HIGH);
digitalWrite(AMBER_TRAFFIC, HIGH);
do {
}while((unsigned long)(millis() - startMillis) < SECS_3);
}
void state3() {
unsigned long startMillis = millis();
digitalWrite(RED_TRAFFIC, HIGH);
digitalWrite(AMBER_TRAFFIC, LOW);
digitalWrite(DONT_CROSS, HIGH);
do {
}while((unsigned long)(millis() - startMillis) < SECS_3);
}
void state4() {
unsigned long startMillis = millis();
unsigned long lastMillis = startMillis;
digitalWrite(RED_TRAFFIC, HIGH);
digitalWrite(CROSS, HIGH);
digitalWrite(DONT_CROSS, LOW);
tone(PED_SOUNDER, C6, BEEP);
while(true) {
unsigned long currentMillis = millis();
if((unsigned long)(currentMillis - lastMillis) >= HALF_SEC){
tone(PED_SOUNDER, C6, BEEP);
lastMillis = currentMillis;
}
if((unsigned long)(currentMillis - startMillis) >= SECS_7) {
break; // timed end of state 4
}
}
noTone(PED_SOUNDER);
}
void state5() {
unsigned long startMillis = millis();
unsigned long trafficMillis = startMillis;
unsigned long pedMillis = startMillis;
digitalWrite(AMBER_TRAFFIC, HIGH);
digitalWrite(RED_TRAFFIC, LOW);
digitalWrite(CROSS, HIGH);
while(true) {
unsigned long currentMillis = millis();
if((unsigned long)(currentMillis - trafficMillis) >= HALF_SEC){
digitalWrite(AMBER_TRAFFIC, digitalRead(AMBER_TRAFFIC) ^ 1);
trafficMillis = currentMillis;
}
if((unsigned long)(currentMillis - pedMillis) >= THRD_SEC){
digitalWrite(CROSS, digitalRead(CROSS) ^ 1);
pedMillis = currentMillis;
}
if((unsigned long)(currentMillis - startMillis) >= SECS_6) {
break; // timed end of state 5
}
}
}
void state6() {
unsigned long startMillis = millis();
unsigned long lastMillis = startMillis;
digitalWrite(DONT_CROSS, HIGH);
digitalWrite(CROSS, LOW);
digitalWrite(AMBER_TRAFFIC, HIGH);
while(true) {
unsigned long currentMillis = millis();
if((unsigned long)(currentMillis - lastMillis) >= HALF_SEC){
digitalWrite(AMBER_TRAFFIC, digitalRead(AMBER_TRAFFIC) ^ 1);
lastMillis = currentMillis;
}
if((unsigned long)(currentMillis - startMillis) >= SECS_2) {
break; // timed end of state 6
}
}
}
extern volatile unsigned long timer0_millis;
void resetMillis(){
uint8_t oldSREG = SREG; // copy the status Register
cli(); // disable interrupts
timer0_millis = 0; // zero the millis counter
SREG = oldSREG; // reset the status Register
}
#define BOUNCE_TIME 50
volatile bool pedRequest = false;
volatile bool suspRequest = false;
unsigned long suspenseTime = millis(); // used to debounce button
bool suspended = false;
const int RED_TRAFFIC = 8;
const int AMBER_TRAFFIC = 7;
const int GREEN_TRAFFIC = 6;
const int DONT_CROSS = 5;
const int CROSS = 4;
const int PED_BUTTON = 2;
const int PED_SOUNDER = 9;
const int REMOTE_SUSPEND = 3;
pinMode(REMOTE_SUSPEND, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(REMOTE_SUSPEND), suspHandler, FALLING);
void suspHandler() {
unsigned long currentMillis = millis();
if((unsigned long)(currentMillis - suspenseTime) > BOUNCE_TIME) {
suspRequest = true;
suspenseTime = currentMillis;
}
}
void state7() {
unsigned long trafficMillis = millis();
unsigned long pedMillis = trafficMillis;
digitalWrite(AMBER_TRAFFIC, HIGH);
digitalWrite(RED_TRAFFIC, LOW);
digitalWrite(CROSS, HIGH);
digitalWrite(DONT_CROSS, LOW);
digitalWrite(GREEN_TRAFFIC, LOW);
while(true) {
if(suspRequest) { return;}
unsigned long currentMillis = millis();
if((unsigned long)(currentMillis - trafficMillis) >= HALF_SEC){
digitalWrite(AMBER_TRAFFIC, digitalRead(AMBER_TRAFFIC) ^ 1);
trafficMillis = currentMillis;
}
if((unsigned long)(currentMillis - pedMillis) >= THRD_SEC){
digitalWrite(CROSS, digitalRead(CROSS) ^ 1);
pedMillis = currentMillis;
}
}
}
void loop() {
for(int i = 0; i < 6; i++){
if(suspRequest) {
suspRequest = false;
suspended = !suspended;
if(suspended) {
states[0] = state7;
i = 0;
} else {
states[0] = state1;
i = 1; // restart at pedestrian safe point
}
}
states[i]();
}
}