Blackfin:
Maybe a bit more advanced than you want but reasonably elegant:
//fire detectors
const byte pinSensor1 = 51;
const byte pinSensor2 = 52;
const byte pinSensor3 = 53;
//
const byte pinExtinguisher1 = 31;
const byte pinExtinguisher2 = 32;
const byte pinExtinguisher3 = 33;
//
const byte pinIndicatorLED1 = 34; //just guessed at these; if LED "blinking" is just tied to relay on-time, things can be simplified
const byte pinIndicatorLED2 = 35;
const byte pinIndicatorLED3 = 36;
//defines
#define LED_PER_DIV_2 125 //LED blinking period is 250mS (this constant defines LED toggle period)
#define MIN_DETECT_ACTIVE_TIME 1000ul //mS minimum time for detector to "see" fire before moving to extinguish
#define EXTINGUISH_ACTIVE_TIME 5000ul //mS extinguisher discharge time
//state names
#define ST_IDLE 0
#define ST_TIME_DETECT 1
#define ST_TIME_EXTINGUISH 2
typedef struct
{
byte stateFM; //state variable
byte pinDetector; //pin assigned to the detector
byte pinExtinguisher; //pin assigned to the extinguisher (relay)
byte pinIndicatorLED; //pins assigned to the LED indicator for this instance
bool bLEDEnable; //if true, LED blinking for this room is enabled
unsigned long timeEvent; //used for timing detect and extinguish events
}structFireManagement;
structFireManagement FireManagement[3]=
{
{ //room 1
.stateFM = ST_IDLE,
.pinDetector = pinSensor1,
.pinExtinguisher = pinExtinguisher1,
.pinIndicatorLED = pinIndicatorLED1,
.bLEDEnable = false,
.timeEvent = 0
},
{ //room 2
.stateFM = ST_IDLE,
.pinDetector = pinSensor2,
.pinExtinguisher = pinExtinguisher2,
.pinIndicatorLED = pinIndicatorLED2,
.bLEDEnable = false,
.timeEvent = 0
},
{ //room 3
.stateFM = ST_IDLE,
.pinDetector = pinSensor3,
.pinExtinguisher = pinExtinguisher3,
.pinIndicatorLED = pinIndicatorLED3,
.bLEDEnable = false,
.timeEvent = 0
}
};
void setup()
{
//detectors
pinMode( pinSensor1, INPUT );
pinMode( pinSensor2, INPUT );
pinMode( pinSensor3, INPUT );
//extinguisher relays
pinMode( pinExtinguisher1, OUTPUT );
pinMode( pinExtinguisher2, OUTPUT );
pinMode( pinExtinguisher3, OUTPUT );
//LED indicators
pinMode( pinIndicatorLED1, OUTPUT );
digitalWrite( pinIndicatorLED1, LOW );
pinMode( pinIndicatorLED2, OUTPUT );
digitalWrite( pinIndicatorLED2, LOW );
pinMode( pinIndicatorLED3, OUTPUT );
digitalWrite( pinIndicatorLED3, LOW );
//can add debug messages where desired...
Serial.begin(9600);
}//setup
void loop()
{
//state machine handles all room fire detection and extinguishing tasks and timing
StateMachine();
//LED handler blinks LEDs for rooms on fire
LEDHandler();
}//loop
void StateMachine( void )
{
static byte
roomIndex = 0;
//each pass through the SM services one room (pointed to by roomIndex)
//each room object tracks its own state via stateFM
switch( FireManagement[roomIndex].stateFM )
{
case ST_IDLE:
//check if fire detection signal has gone low
if( digitalRead( FireManagement[roomIndex].pinDetector ) == LOW )
{
//has gone low; get the time now to time the low pulse and move to detect timing state
FireManagement[roomIndex].timeEvent = millis(); //note how each object has its own time variable...
FireManagement[roomIndex].stateFM = ST_TIME_DETECT;
}//if
break;
case ST_TIME_DETECT:
//during timing, if detect pin goes high, just return to idle state
if( digitalRead( FireManagement[roomIndex].pinDetector ) == HIGH )
FireManagement[roomIndex].stateFM = ST_IDLE;
else
{
//still low; check if period has elapsed
if( millis() - FireManagement[roomIndex].timeEvent >= MIN_DETECT_ACTIVE_TIME )
{
//yes; turn on extinguisher, enable LED blink and get time for timing duration
digitalWrite( FireManagement[roomIndex].pinExtinguisher, LOW );
FireManagement[roomIndex].timeEvent = millis();
FireManagement[roomIndex].bLEDEnable = true;
FireManagement[roomIndex].stateFM = ST_TIME_EXTINGUISH;
}//if
}//else
break;
case ST_TIME_EXTINGUISH:
//timing extinguisher duration here; has time elapsed?
if( millis() - FireManagement[roomIndex].timeEvent >= EXTINGUISH_ACTIVE_TIME )
{
//yes; turn off the extinguisher, disable the LED blink and return to idle
digitalWrite( FireManagement[roomIndex].pinExtinguisher, HIGH );
FireManagement[roomIndex].bLEDEnable = false;
FireManagement[roomIndex].stateFM = ST_IDLE;
}//if
break;
}//switch
//bump roomIndex to point to next room
//0, 1, 2 then back to 0...
roomIndex++;
if( roomIndex > 2 )
roomIndex = 0;
}//StateMachine
void LEDHandler( void )
{
static bool
bState = false;
static unsigned long
timeLED = 0;
unsigned long
timeNow;
//toggle boolean variable; its state will be driven to enabled LEDs
timeNow = millis();
if( timeNow - timeLED > LED_PER_DIV_2 )
{
timeLED = timeNow;
bState ^= true;
}//if
//this is quick so we can do all three rooms in one loop
for( byte i=0; i<3; i++ )
{
//if LED blinking is enabled...
if( FireManagement[i].bLEDEnable == true )
//drive indicator LED for this room based on bState (toggling variable)
digitalWrite( FireManagement[i].pinIndicatorLED, (bState==true)?HIGH:LOW );
else
//not enabled; just turn indicator LED off
digitalWrite( FireManagement[i].pinIndicatorLED, LOW );
}//for
}//LEDHandler
Wow your code is really cool, in looking it over and understanding it right now, going to test it later, thank you!