byte check_outputs (byte inputs)
{
struct OUTTRIG *trigp;
struct OUTPUT *outp;
byte out_no, outputs, i, j;
outputs = 0;
for (out_no = 0; out_no != NOUTPUTS; out_no ++) { //Check each output channel
trigp = &out_trig[out_no]; //Use ptrs for faster access
outp = &Outputs[out_no];
//If output enabled, and sensor triggered & enabled
if (outp->dev_type != DEV_TYPE_none && (inputs & outp->sns_sel) != 0) {
trigp->rpt_dly = outp->rpt_dly; //Init repeat delay time
if ((inputs & trigp->sns_sel) != 0) //If sensor was active before,
trigp->sns_rpt ++; //then incr repeat count
trigp->sns_sel |= inputs & outp->sns_sel; //Save active sensor bits
for (i = trigp->sns_sel, j = 0; i != 0; i >>= 1)
if (i & 1)
j ++; //Count number of active sensors
if (j >= outp->sns_mult //Do we have enough sensors,
&& (byte)(trigp->sns_rpt + 1) >= outp->sns_rpt //and enough repeats,
&& trigp->wait_dly == 0 //and have waited long enough,
&& (*(word *)&Time.hour) >= (*(word *)&outp->on_time) //and are within the
&& (*(word *)&Time.hour) <= (*(word *)&outp->off_time)) { //activation window?
trigp->sns_sel = 0; //Clear the repeat stats
trigp->sns_rpt = 0;
trigp->rpt_dly = 0;
Last_trig.time.hour = Time.hour; //Update the activation stats
Last_trig.time.min = Time.minute;
Last_trig.days = 0;
if (Syscfg.enabled != 0) { //Check master system enable flag
outputs |= bit_mask (out_no); //Now set the channel’s output bit
trigp->wait_dly = outp->wait_dly; //Update the wait delay time
}
}
}
}
return (outputs); //Return with bitmask of triggered
//channels
}
Listing 1—This routine implements the trigger logic for each of the eight output
channels. It checks the sensor status, repeat counters, delay timers, and activation
time to determine if an output should be activated.