Here is my final state diagram, wiring schematic, and code (though I might change some threshold values). The code is excessively long and definitely not optimized; it was just the easiest way to understand what was going on so I can more easily debug. It should be relatively self-explanatory therefore. The state diagram from which the code was derived is similarly not optimal for the same reason.
And I figured out that the reason the bell & buzzer weren’t going off during the demo was because I turned on the batteries improperly, as in apparently I need to turn on the Arduino last, otherwise it will enter some strange inescapable state-change path. I don’t have it all figured out but it’s hopefully enough such that the effectiveness of Murphy’s Law won’t be consistent.
HELP REQUEST!
I’m having no luck photographing it and I honestly have no idea how to videoscenario it so if anyone has any suggestions or can offer help it would be greatly appreciated!
[State Diagram & Wiring Schematic]
[Code]
#include
// PINS //
int soapLED_R = 10; // warning light
int soapLED_G = 9; // indicates soap being dispensed
int soapLED_B = 8; // standard light [GB=white]
int sinkLED = 11; // indicates running water [B]
int soapsensor = 0;
int sinksensor = 1;
int toiletswitch = 12; // indicates motion detected [into toilet!]
int flushbutton = 13;
int lockbutton = 7;
int doorswitch = 4;
int signservo = 3;
int locksolenoid = 2;
int speaker = 5;
int bell = 6;
Servo sign;
// STATES //
int State = 0;
const int Blank = 0;
const int Locked = 1;
const int Wash = 2;
const int LockWash = 3;
const int Flush = 4;
const int Toilet = 5;
const int DUnlock = 6;
const int DLeaving = 7;
const int DSoap = 8;
const int DRinse = 9;
const int Clean = 10;
const int CLeaving = 11;
const int TUnlock = 12;
const int TLeaving = 13;
const int TSoap = 14;
const int TWater = 15;
int LockState = 0;
const int Auto = 0;
const int Manual = 1;
// OUTPUT CONDITIONS //
int Reward = 0;
const int Off = 0;
const int On = 1;
int Buzzer = 0;
int Sign = 0;
const int Bl_Bl = 125; // in: blank out: blank
const int Wa_Bl = 107; // in: wash out: blank
const int Wa_Di = 87; // in: wash out: dirty
const int Ri_Bl = 68; // in: rinse out: blank
const int Fl_Bl = 51; // in: flush out: blank
const int Fl_Fl = 31; // in: flush out: flush
const int Th_Cl = 13; // in: thanks out: clean!
int Soap = 0;
const int White = 0; // standard light
const int Red = 1; // warning light
const int Green = 2; // indicates soap being dispensed
int Sink = 0;
int Lock = 0;
// ANALOG INPUT THRESHOLDS //
int soapmin = 30;
int soapmax = 100;
int sinkmin = 100;
int sinkmax = 300;
// OTHER //
int lockbuttonpress = 0;
int dooropentime = 0;
int sinkontime = 0;
void setup()
{
Serial.begin(9600);
pinMode(soapLED_R, OUTPUT); // digital
pinMode(soapLED_G, OUTPUT); // digital
pinMode(soapLED_B, OUTPUT); // digital
pinMode(sinkLED, OUTPUT); // digital
pinMode(soapsensor, INPUT); // analog
pinMode(sinksensor, INPUT); // analog
pinMode(toiletswitch, INPUT); // digital
pinMode(flushbutton, INPUT); // digital
pinMode(lockbutton, INPUT); // digital
pinMode(doorswitch, INPUT); // digital: LOW when closed, HIGH when open
pinMode(signservo, OUTPUT); // digital PWM
pinMode(locksolenoid, OUTPUT); // digital
pinMode(speaker, OUTPUT); // digital
pinMode(bell, OUTPUT); // digital
State = Blank;
LockState = Auto;
Reward = Off;
Buzzer = Off;
Sign = Bl_Bl;
Soap = White;
Sink = White;
Lock = Off;
lockbuttonpress = 0;
dooropentime = 0;
sinkontime = 0;
sign.attach(signservo);
sign.setMaximumPulse(2400);
sign.setMinimumPulse(544);
sign.write(Bl_Bl);
}
void loop()
{
// SWITCH STATES //
switch(State)
{
case Blank:
if(lockbuttonpress==0 && digitalRead(lockbutton)==HIGH && digitalRead(doorswitch)==LOW)
{ lockbuttonpress=1; State=Locked; }
if(digitalRead(lockbutton)==LOW) {lockbuttonpress=0;}
if(analogRead(soapsensor)1000) {sinkontime=0; State=Clean;} }
if(analogRead(sinksensor)>sinkmax) {sinkontime=0;}
if(digitalRead(flushbutton)==HIGH) {State=Flush;}
if(digitalRead(toiletswitch)==HIGH) {State=Toilet;}
break;
case Flush:
if(lockbuttonpress==0 && digitalRead(lockbutton)==HIGH)
{ lockbuttonpress=1; State=DUnlock;}
if(digitalRead(lockbutton)==LOW) {lockbuttonpress=0;}
if(digitalRead(doorswitch)==HIGH)
{ dooropentime=millis(); State=DLeaving; }
if(analogRead(soapsensor)1000) {dooropentime=0; State=Blank;}
if(analogRead(soapsensor)1000) {sinkontime=0; State=Clean;} }
if(analogRead(sinksensor)>sinkmax) {sinkontime=0;}
if(digitalRead(flushbutton)==HIGH) {State=Flush;}
if(digitalRead(toiletswitch)==HIGH) {State=Toilet;}
break;
case DRinse:
if(lockbuttonpress==0 && digitalRead(lockbutton)==HIGH)
{ lockbuttonpress=1; State=DUnlock;}
if(digitalRead(lockbutton)==LOW) {lockbuttonpress=0;}
if(digitalRead(doorswitch)==HIGH)
{ dooropentime=millis(); State=DLeaving; }
if(analogRead(soapsensor)1000)
{ dooropentime=0; State=Blank;}
break;
case TUnlock:
if(lockbuttonpress==0 && digitalRead(lockbutton)==HIGH && digitalRead(doorswitch)==LOW)
{ lockbuttonpress=1; State=Toilet; LockState=Manual; }
if(digitalRead(lockbutton)==LOW) {lockbuttonpress=0;}
if(digitalRead(doorswitch)==HIGH) {dooropentime=millis(); State=TLeaving;}
if(analogRead(soapsensor)1000) {dooropentime=0; State=Blank;}
if(analogRead(soapsensor)