Last active
August 29, 2015 14:14
-
-
Save wmealing/d2c1d3ef39b6c61a7a7d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SM.h> | |
#include <SoftwareSerial.h> | |
// These are required by the shield in use. | |
#define BT_RX_PIN 2 | |
#define BT_TX_PIN 3 | |
// Aliases for the PINS that control power to each of the valves | |
#define CLEAN_WATER_VALVE 4 | |
#define WASTE_WATER_VALVE 5 | |
#define SOLENOID_CONTROL_PIN_1 6 | |
#define SOLENOID_CONTROL_PIN_2 7 | |
#define CLOSED 0 | |
#define OPEN 1 | |
#define LIQUID_SENSOR_PIN A0 | |
// Time between checks (seconds) | |
#define CHECK_INTERVAL 60 | |
// time to allow for drain (seconds). | |
#define DRAINTIME 60 | |
// time to allow for filling (seconds). | |
#define FILLTIME 20 | |
// the value on the sensor it should be above | |
// to be considered "full" | |
#define PEE_THRESHOLD 500 | |
// time after it empties before it checks again.a | |
#define POST_CLEAN_DELAY 360 | |
int sensorValue = 0; // variable to store the value coming from the sensor | |
int needs_msg = 1; | |
SoftwareSerial bt(2,3); // RX, TX | |
// create simple statemachine, start by setting up the comms. | |
SM StateMachine(setupComms); | |
// Initial state, setup the comms. | |
State setupComms(){ | |
Serial.begin(9600); | |
bt.begin(9600); | |
bt.println("$$$"); | |
pinMode(BT_RX_PIN, INPUT); | |
pinMode(BT_TX_PIN, OUTPUT); | |
send("\r\n+STBD=9600\r\n"); | |
send("\r\n+STPIN=3333\r\n"); | |
send("\r\n+STOAUT=1\r\n"); | |
delay(4000); // This delay is required. | |
send("\r\n+INQ=1\r\n"); // make the slave bluetooth inquirable | |
send("The slave bluetooth is inquirable!"); | |
delay(4000); // This delay is required. | |
bt.flush(); | |
send("Ready for commands"); | |
StateMachine.Set(normalOperation); | |
} | |
State normalOperation() { | |
if (needs_msg) { | |
send("Ready for commands"); | |
needs_msg = 0; | |
} | |
if (bt.available()) { | |
needs_msg = 1; | |
StateMachine.Set(handleBT); | |
} | |
else { | |
StateMachine.Set(checkLevels); | |
} | |
} | |
State handleBT() { | |
switch (bt.read()){ | |
case 'f': | |
send("User initiated force evac"); | |
StateMachine.Set(cleanTank); | |
break; | |
default: | |
send("Unknown bt command"); | |
StateMachine.Set(normalOperation); | |
} | |
} | |
State checkLevels() { | |
sensorValue = analogRead(LIQUID_SENSOR_PIN); | |
if (sensorValue >= PEE_THRESHOLD) { | |
send("condutivity detected"); | |
StateMachine.Set(cleanTank); | |
} | |
else { | |
// FIXME: remove next line for better usability | |
send("All systems nominal"); | |
StateMachine.Set(normalOperation); | |
} | |
} | |
State cleanTank() { | |
drainTank(); | |
fillTank(); | |
drainTank(); | |
// ensure both valves are closed | |
setValve(WASTE_WATER_VALVE, CLOSED); | |
setValve(CLEAN_WATER_VALVE, CLOSED); | |
StateMachine.Set(normalOperation); | |
} | |
void send(const char* str) { | |
bt.println(str); | |
Serial.println(str); | |
} | |
// Parameters, the ValveNumber you wish to | |
void setValve(int ValvePin, int Position) { | |
// force both control pins low, so we never have a chance | |
// of setting both high at any time. | |
digitalWrite(SOLENOID_CONTROL_PIN_1, LOW); | |
digitalWrite(SOLENOID_CONTROL_PIN_2, LOW); | |
// Turn on the Valve pin | |
digitalWrite(ValvePin, HIGH); | |
switch(Position) { | |
// Move the valve to the closed position. | |
case CLOSED: | |
digitalWrite(SOLENOID_CONTROL_PIN_1, HIGH); | |
digitalWrite(SOLENOID_CONTROL_PIN_2, LOW); | |
break; | |
// Move the valve to the open position. | |
case OPEN: | |
digitalWrite(SOLENOID_CONTROL_PIN_1, HIGH); | |
digitalWrite(SOLENOID_CONTROL_PIN_2, LOW); | |
break; | |
// Warn the user via serial connection that we havne't setup this pin. | |
// bail immediately in an attempt to not mess things up. | |
default: | |
bt.print("[e] invalid state: position - "); | |
bt.println(Position); | |
Serial.println("INVALID POSITION"); | |
return; | |
} | |
// Turn off the Valve pin, once the solenoid changed state (on/off) | |
digitalWrite(ValvePin, LOW); | |
} | |
void setup() | |
{ | |
pinMode(LIQUID_SENSOR_PIN, INPUT); | |
pinMode(CLEAN_WATER_VALVE, OUTPUT); | |
pinMode(WASTE_WATER_VALVE, OUTPUT); | |
pinMode(SOLENOID_CONTROL_PIN_1, OUTPUT); | |
pinMode(SOLENOID_CONTROL_PIN_2, OUTPUT); | |
} | |
void drainTank() { | |
send("\n[i] opening waste water valve"); | |
setValve(WASTE_WATER_VALVE, OPEN); | |
send("\n[i] waiting for waste to drain"); | |
delay(DRAINTIME); | |
send("\n[i] closing waste water valve"); | |
setValve(WASTE_WATER_VALVE, CLOSED); | |
} | |
void fillTank() { | |
send("\n[i] open clean water valve"); | |
setValve(CLEAN_WATER_VALVE, OPEN); | |
send("\n[i] waiting for fill"); | |
delay(FILLTIME); | |
send("\n[i] close clean water valve"); | |
setValve(CLEAN_WATER_VALVE, CLOSED); | |
} | |
void loop() { | |
EXEC(StateMachine); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment