// water fill system with test modes
// conveyor runs
// bucket breaks light beam
// conveyor stops
// water dispenses for 5 sec
// conveyor starts again
// -repeat-
const int senseWaterStn = 3;  // Sensor pin (IR sensor, water station)
const int drive         = 7;  // conveyor belt
const int waterfill     = 11; // Water valve pin (water fill station) / relay 1
const int PinRunLed     = 13;
int stnLst;
const unsigned long MsecWaterFill = 5000;
      unsigned long msecWater;
      unsigned long msec;
enum { StnOcc   = LOW,  StnEmp  = HIGH };
enum { DriveOff = LOW,  DriveOn = HIGH };
enum { WaterOff = LOW,  WaterOn = HIGH };
enum { LedOff   = LOW,  LedOn   = HIGH };
enum { Idle, Stop, Start, Move, Fill, Test };
int    state = Idle;
// -----------------------------------------------------------------------------
void setup () {
    Serial.begin(9600);
    pinMode     (senseWaterStn, INPUT_PULLUP);
    stnLst    = digitalRead (senseWaterStn);
    pinMode      (drive,        OUTPUT);
    pinMode      (waterfill,    OUTPUT);
    pinMode      (PinRunLed,    OUTPUT);
    pinMode      (PinRunLed,    LedOff);
    state = Stop;
    Serial.println ("ready");
}
// -----------------------------------------------------------------------------
void loop ()
{
    msec = millis ();
    // monitor serial interfae
    if (Serial.available ())  {
        switch (Serial.read ())  {
        case 'd':
            if (state == Test)
                digitalWrite (drive, !digitalRead (drive)); //toggle
            break;
        case 'r':           // need to enter 'r' to run
            Serial.println ("Run mode");
            state = Start;
            break;
        case 't':           // need to enter 'r' to run
            Serial.println ("Test mode");
            state = Test;
            allOff ();
            break;
        case 'w':
            if (state == Test)
                digitalWrite (waterfill, !digitalRead (waterfill)); //toggle
            break;
        case '\n':          // catch newline
            break;
        default:            // any key stops
            state = Stop;
            break;
        }
    }
    // don't run automationin Test mode
    if (Test != state)
        runStMach ();
    // monitor sensors
    int stn = digitalRead(senseWaterStn);
    if (stnLst != stn)  {
        stnLst  = stn;
        if (StnOcc == stn)
            Serial.println ("water station ocupied");
        else
            Serial.println ("water station empty");
    }
}
// -----------------------------------------------------------------------------
void
allOff ()
{
    Serial.println ("all-off");
    digitalWrite (waterfill, WaterOff);
    digitalWrite (drive,     DriveOff);
    digitalWrite (PinRunLed, LedOff);
}
// -----------------------------------------------------------------------------
void
runStMach ()
{
    // state machine
    switch (state)  {
    case Idle:      // do nothing
        break;
    case Stop:
        Serial.println (" STOP");
        allOff ();
        state = Idle;
        break;
    case Start:
        Serial.println ("start conveyor");
        digitalWrite (PinRunLed, LedOn);
        digitalWrite (drive,     DriveOn);
        state =  Move;
        break;
    case Move:
        if (digitalRead(senseWaterStn) == LOW)  {
            Serial.println ("water station sensor broken - water fill on");
            digitalWrite (drive,     DriveOff);
            digitalWrite (waterfill, WaterOn);
            msecWater = msec;
            state     = Fill;
        }
        break;
    case Fill:
        if (msec - msecWater >= MsecWaterFill)  {
            Serial.println ("water time-out - water fill off, conveyor on");
            digitalWrite (waterfill, WaterOff);
            digitalWrite (drive,     DriveOn);
            state     = Move;
        }
        break;
    }
}