Skip to content

Instantly share code, notes, and snippets.

@wmealing
Last active August 29, 2015 14:14
Show Gist options
  • Save wmealing/d2c1d3ef39b6c61a7a7d to your computer and use it in GitHub Desktop.
Save wmealing/d2c1d3ef39b6c61a7a7d to your computer and use it in GitHub Desktop.
#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