an example of a statically initialized array of structs
// model railroad signaling control example
#include "sim.h"
#define DetPt0 PIN_A0
// -----------------------------------------------------------------------------
// basic signal control for 6 blocks
// define block symbols
enum {
B00 = 0, B01, B02, B03, B04, B05,
Blast,
};
// define detector symbols
enum {
D00 = 0, D01, D02, D03, D04, D05,
D06, D07, D08, D09, D10, D11, D12, D13,
Dlast,
};
// define LED pins (sequentally starting at pin 5
enum {
L00 = 5, L01, L02, L03, L04, L05,
L06, L07, L08, L09, L10, L11,
L12, L13, L14, L15, L16, L17,
L18, L19, L20, L21, L22, L23,
L24, L25, L26, L27, L28, L29,
L30, L31, L32, L33, L34, L35,
Llast,
};
// signal description structure
typedef struct {
const char *desc; // descriptive string
int ledR; // leds
int ledY;
int ledG;
int blk1; // next and following block indices
int blk0;
int intLck0; // option interlock indices
int intLck1;
} Sig_t;
// signal description table
Sig_t sigs [] = {
{ "sigE00", L00, L01, L02, B02, B01 },
{ "sigE01", L03, L04, L05, B03, B02 },
{ "sigE02", L06, L07, L08, B04, B03, 0, D08 },
{ "sigE03", L09, L10, L11, B05, B04, D08 },
{ "sigE04", L12, L13, L14, B00, B05 },
{ "sigE05", L15, L16, L17, B01, B00 },
{ "sigW05", L18, L19, L20, B03, B04 },
{ "sigW04", L21, L22, L23, B02, B03 },
{ "sigW03", L24, L25, L26, B01, B02 },
{ "sigW02", L27, L28, L29, B00, B01 },
{ "sigW01", L30, L31, L32, B05, B00 },
{ "sigW00", L33, L34, L35, B04, B05 },
};
#define SIG_SIZE (sizeof(sigs)/sizeof(Sig_t))
// ---------------------------------------------------------
// allocate array for storing detector values
int detPt [Dlast];
// ---------------------------------------------------------
// process a Sig_t entry determining the signal state
void sig (Sig_t *s)
{
char str [40];
sprintf (str, "%s: blk %d %d, blk1 %d %d",
s->desc, s->blk0, detPt [s->blk0] , s->blk1, detPt [s->blk1]);
Serial.println (str);
// turn off all LEDs
digitalWrite (s->ledR, HIGH);
digitalWrite (s->ledY, HIGH);
digitalWrite (s->ledG, HIGH);
if (detPt [s->blk0] || (s->intLck0 && detPt [s->intLck0]))
digitalWrite (s->ledR, LOW); // Stop
else if (detPt [s->blk1] || (s->intLck1 && detPt [s->intLck1]))
digitalWrite (s->ledY, LOW); // Approach
else
digitalWrite (s->ledG, LOW); // Clear
}
// ---------------------------------------------------------
// read each detector, applying hysterisis and
// process each signal
void loop (void)
{
Serial.println ("\nloop:");
#define ANALOG_HI (1024 * 0.7)
#define ANALOG_LO (1024 * 0.3)
for (int d = 0; d < Dlast; d++) {
if (detPt [d])
detPt [d] = ANALOG_LO > analogRead (DetPt0 + d);
else
detPt [d] = ANALOG_HI < analogRead (DetPt0 + d);
}
for (int n = 0; n < SIG_SIZE; n++)
sig (& sigs [n]);
}
// ---------------------------------------------------------
// initialize pins
void setup (void)
{
Serial.begin (9600);
for (int d = 0; d < Dlast; d++)
pinMode (DetPt0 + d, INPUT_PULLUP);
for (int outPin = L00; outPin < Llast; outPin++)
pinMode (outPin, OUTPUT);
}