ifkaz
assuming you're still interested in code to support a RR crossing with both road and pedestrian crossings, i wrote code I tested on a multifunction board to do same
the multifunction board has 4 7-segment displays, but there interface is serial. i assume you can use the code from the original link for a directly interface 7-seg display.
you'll also need to borrow the servo code from the original link, add support for a train photo sensor on either side of the crossing using either an LDR or photo transistor and a green LED for the pedestrian crossing.
the code is more dense, fewer sub-functions and essentially a state machine although management of states is spread out
i assume it is a better starting point for your project
// RR/Road/Pedestrian crossing
// Road LED indicates when train is crossing
// Pedestrian crossing button triggers 9 second timer
// and road LED
// drive 7-seg displays on MultiFuction boardj
#include <TimerOne.h>
// -----------------------------------------------
// constants for multiplexed 7-segment display
#define Latch 4
#define Clock 7
#define Data 8
#define LED0 10
#define LED1 11
byte pins [] = { Latch, Clock, Data, LED0, LED1 };
const byte SEGMENT_MAP_DIGIT[] = {
0xC0, 0xF9, 0xA4, 0xB0, 0x99,
0x92, 0x82, 0xF8, 0X80, 0X90
};
const byte DISP_MAP [] = { 1, 2, 4, 8 };
#define N_DISP sizeof(DISP_MAP)
byte disp [N_DISP] = {};
// -----------------------------------------------
#define ButPed A1
#define ButTrain A2
#define LedPed 13
#define LedRoad 12
enum { ST_CLEAR, ST_TRAIN, ST_PEDESTRIAN };
enum { GO = HIGH, STOP = LOW };
// -----------------------------------------------------------------------------
// shift 16-bits from data into the shift register
void output (
uint16_t data)
{
digitalWrite (Latch, LOW);
for (unsigned i = 0; i < 16; i++, data <<= 1) {
digitalWrite (Data, 0 != (data & 0x8000));
digitalWrite (Clock, HIGH);
digitalWrite (Clock, LOW);
}
digitalWrite (Latch, HIGH);
}
// -----------------------------------------------------------------------------
// display single 7-segment digit
void
displayDigit (
byte val)
{
output ((SEGMENT_MAP_DIGIT [val] << 8) + DISP_MAP [0]);
}
// -----------------------------------------------------------------------------
// increment the display value every 300 ms
void loop (void)
{
static byte state = ST_CLEAR;
// ----------------------------------------
// maintain timer
static byte timer = 0;
displayDigit (timer);
static unsigned long msecLst = 0;
unsigned long msec = millis ();
if (msec - msecLst > 1000) { // decrement timer each second
msecLst = msec;
if (timer) {
if (0 == --timer) { // clear state when timer expires
state = ST_CLEAR;
digitalWrite (LedPed, STOP);
digitalWrite (LedRoad, GO);
}
}
}
// ----------------------------------------
// maintain pedestrian crossing switch
static byte butPedLst = HIGH;
byte butPed = digitalRead (ButPed);
if (butPedLst != butPed) {
butPedLst = butPed;
if (LOW == butPed && ST_CLEAR == state) {
msecLst = msec;
timer = 9;
state = ST_PEDESTRIAN;
digitalWrite (LedPed, GO);
digitalWrite (LedRoad, STOP);
}
}
// ----------------------------------------
// maintain train crossing detection
if (LOW == digitalRead (ButTrain)) {
state = ST_TRAIN;
timer = 0;
digitalWrite (LedPed, STOP);
digitalWrite (LedRoad, STOP);
}
else if (ST_TRAIN == state) {
state = ST_CLEAR;
digitalWrite (LedRoad, GO);
}
}
// -----------------------------------------------------------------------------
void setup (void)
{
Serial.begin (115200);
Serial.println ("RR/pedestrian crossing");
for (unsigned i = 0; i < sizeof(pins); i++) {
digitalWrite (pins [i], HIGH);
pinMode (pins [i], OUTPUT);
}
pinMode (ButPed, INPUT_PULLUP);
pinMode (LedPed, OUTPUT);
pinMode (LedRoad, OUTPUT);
digitalWrite (LedPed, STOP);
digitalWrite (LedRoad, GO);
}