loading

Collaborating water and electricity seems as almost common sense as pairing a young Petit Chablis with a spaghetti alla vongole. As an alternative to the several thousand dollar pre-installed branded electronically controlled shower, a few attempts at creating a DIY automated shower have appeared over the years, though, applied with immense exchange of existing components and not best utilizing the newer era of IoT. Here, we have sympathetically married abundantly common pre-existing shower valves with the yet to be released Arduino MKR1000 to create an automated, connected and subsequently more efficient bathing experience.

Through either the Windows 10 or Android application, you may preset an optimal temperature and begin the shower. The MKR1000 will then monitor and regulate the temperature and shower valve to create a luxurious escapade in your dirt ass poor bath room. The amount of time and temperature variation will be sent in real time to ThingSpeak where it can be monitored for display and personal analysis of water consumption.

Additional notation; the popsicle sticks were a late second amendment to gain leverage.

// Arduino IoT Shower @TVMiller
// Arduino MKR1000 Beta

// A0 Temp Tub
// A1 Temp Head
// 0 Cap 10M
// 1 Cap 1K
// 2 3 4 5 11 12 LCD
// 6 LED
// 7 Hot
// 8 Valve
// 9 Cold

// Libraries
#include SPI.h
#include WiFi101.h
#include LiquidCrystal.h
#include Servo.h
#include CapacitiveSensor.h

// WiFi
char ssid[] = "NETWORK";
char pass[] = "PASSWORD";
int keyIndex = 0;
int status = WL_IDLE_STATUS;
WiFiServer server(80);

// ThingSpeak
char thingSpeakAddress[] = "api.thingspeak.com";
String APIKey = "XXXXXXXX"; // API
const int updateThingSpeakInterval = 10 * 1000; // Interval
long lastConnectionTime = 0;
boolean lastConnected = false;
WiFiClient client;

// LCD
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// Servos
Servo hot;
Servo valve;
Servo cold;
int openturn = 0;
int closeturn = 180;
int noturn = 90;

// Servo Position Delays
int hotdelay = 450;
int valvedelay = 700;
int colddelay = 300;

// Temperature
int temptub = A0;
int temphead = A1;
int templow = 0;
int temphigh = 0;
int tempc = 0;
int pretempf = 0;

// Temperature Variable
int settemp = 42;
int preptemp = 0;
int tempvarlow = 0;
int tempvarhigh = 0;

// Map Variables
int lowvol = 400;
int highvol = 1005;
int lowc = 56;
int highc = 131;

// On Off Button
CapacitiveSensor   onoffbutton = CapacitiveSensor(0, 1);
int touchpeak = 150;

// State
// 0 = Off
// 1 = Turn On
// 2 = On
// 3 = Shut Off
int state = 0;

void setup() {
  Serial.begin(9600);

  // Servos
  hot.attach(7);
  valve.attach(8);
  cold.attach(9);
  hot.write(90);
  valve.write(90);
  cold.write(90);

  // Temperature
  pinMode(temptub, INPUT);
  pinMode(temphead, INPUT);

  // LCD
  lcd.begin(16, 2);
  lcd.clear();

  // WIFI Connection
  while ( status != WL_CONNECTED) {
    lcd.setCursor(0, 0);
    lcd.print("Connecting...");
    lcd.setCursor(0, 1);
    lcd.print(ssid);
    Serial.print("Connecting Network: ");
    Serial.println(ssid);
    status = WiFi.begin(ssid, pass);
    delay(10000);
  }
  server.begin();
  lcd.clear();
  printWifiStatus();
  delay(3000);
  lcd.clear();
}

void loop() {

  // WiFi Server Page
  if (state == 0) {
    WiFiClient client = server.available();
    if (client) {
      String currentLine = "";
      while (client.connected()) {
        if (client.available()) {
          char c = client.read();
          Serial.write(c);
          if (c == '\n') {
            if (currentLine.length() == 0) {
              client.println("HTTP/1.1 200 OK");
              client.println("Content-type:text/html");
              client.println();
              client.print("body bgcolor=\"#9999FF\"");
              client.print("div align=\"center\"");
              client.print("table cellspacing=\"0\" cellpadding=\"0\" 
border=\"0\" style=\" border:1px solid #000000;background-color:#FFFFFF;\"
tr td style=\"padding:5px;font:50px tahoma;\"");
              client.print(settemp);
              client.print("/td /tr /table");
              client.print("a href=\"/U\" img src=\"

http://yoursite.com/images/uparrow.png\"  border=\"0\" /a
a href=\"/D\" img src=\"http://yoursite.com/images/
downarrow.png\" border=\"0\" /a br /");
              client.print("br /");
              client.print("a href=\"/S\" img src=\"http://yoursite.
com/images/showeron.png\" border=\"0\" /a");
              client.print("/div");
              client.println();
              break;
            }
            else {
              currentLine = "";
            }
          }
          else if (c != '\r') {
            currentLine += c;
          }

          if (currentLine.endsWith("GET /U")) {
            settemp = settemp + 1;
          }
          if (currentLine.endsWith("GET /D")) {
            settemp = settemp - 1;
          }
          if (currentLine.endsWith("GET /S")) {
            state = 1;
          }
        }
      }
      client.stop();
    }
  }

  // On Off Button
  long touch = onoffbutton.capacitiveSensor(30);
  if (touch > touchpeak) {
    if (state == 0) {
      state = 1;
    }
    else if (state == 2) {
      state = 3;
    }
  }

  // Update ThingSpeak
  if (state == 1 || state == 2) {
    temphigh = analogRead(temphead);
    pretempf = map(temphigh, lowvol, highvol, lowc, highc);
    tempc = (pretempf - 32) * 5 / 9;
    String headtemperature = String(tempc, DEC);
    String runtime = String(state, DEC);
    if (millis() - lastConnectionTime > updateThingSpeakInterval) {
      updateThingSpeak("field1=" + runtime + "&field2=" + headtemperature);
    }
  }

  // State Operation
  if (state == 1) {
    turnon();
  }
  else if (state == 2) {
    shower();
  }
  else if (state == 3) {
    turnoff();
  }

}

void printWifiStatus() {
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());
  IPAddress ip = WiFi.localIP();
  Serial.print("http://");
  Serial.println(ip);
  long rssi = WiFi.RSSI();
  Serial.print("RSSI: ");
  Serial.print(rssi);
  Serial.println(" dBm");
  lcd.setCursor(0, 0);
  lcd.print(WiFi.SSID());
  lcd.setCursor(0, 1);
  lcd.print(ip);
}

void updateThingSpeak(String tsData) {
  if (client.connect(thingSpeakAddress, 80)) {
    client.print("POST /update HTTP/1.1\n");
    client.print("Host: api.thingspeak.com\n");
    client.print("Connection: close\n");
    client.print("X-THINGSPEAKAPIKEY: " + APIKey + "\n");
    client.print("Content-Type: application/x-www-form-urlencoded\n");
    client.print("Content-Length: ");
    client.print(tsData.length());
    client.print("\n\n");
    client.print(tsData);
    lastConnectionTime = millis();
  }
}

void turnon() {

  // LCD Temperature Display
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Set Temp:");
  lcd.setCursor(10, 0);
  lcd.print(settemp);
  lcd.setCursor(0, 1);
  lcd.print("Current:");
  lcd.setCursor(9, 1);
  lcd.print("0");

  // Hot Open Valve Tub Cold Closed
  hot.write(180);
  delay(hotdelay);
  hot.write(90);

  delay(2000);

  preptemp = settemp - 2;

  // Wait For Temp
  while (preptemp > tempc) {
    templow = analogRead(temptub);
    pretempf = map(templow, lowvol, highvol, lowc, highc);
    tempc = (pretempf - 32) * 5 / 9;
    lcd.setCursor(9, 1);
    lcd.print(tempc);
    String headtemperature = String(tempc, DEC);
    if (millis() - lastConnectionTime > updateThingSpeakInterval) {
      updateThingSpeak("&field2=" + headtemperature);
    }
  }

  // Hot Open Valve Tub Cold Open
  cold.write(180);
  delay(colddelay);
  cold.write(90);

  // Delay For While Statement
  delay(2000);

  // Wait For Temp
  while (preptemp > tempc) {
    templow = analogRead(temptub);
    pretempf = map(templow, lowvol, highvol, lowc, highc);
    tempc = (pretempf - 32) * 5 / 9;
    lcd.setCursor(9, 1);
    lcd.print(tempc);
    String headtemperature = String(tempc, DEC);
    if (millis() - lastConnectionTime > updateThingSpeakInterval) {
      updateThingSpeak("&field2=" + headtemperature);
    }
  }

  // Hot Open Valve Head Cold Open
  valve.write(180);
  delay(valvedelay);
  valve.write(90);

  // Set State On
  state = 2;

  // Update State ThingSpeak
  String runtime = String(state, DEC);
  updateThingSpeak("field1=" + runtime);

}

void shower() {

  // Get Temp Shower Head
  temphigh = analogRead(temphead);
  pretempf = map(temphigh, lowvol, highvol, lowc, highc);
  tempc = (pretempf - 32) * 5 / 9;

  // Print Shower Temp
  lcd.setCursor(9, 1);
  lcd.print(tempc);

  // Set Temperature Leeway
  tempvarlow = settemp - 2;
  tempvarhigh = settemp + 2;

  // Adjust Temperature
  if (tempc < tempvarlow) {
    cold.write(0);
    delay(100);
    cold.write(90);
    colddelay = colddelay - 100;
    delay(2000);
  }
  else if (tempc > tempvarhigh) {
    cold.write(180);
    delay(100);
    cold.write(90);
    colddelay = colddelay + 100;
    delay(2000);
  }

}

void turnoff() {

  // Get Temp Shower Head
  temphigh = analogRead(temphead);
  pretempf = map(temphigh, lowvol, highvol, lowc, highc);
  tempc = (pretempf - 32) * 5 / 9;

  // Print Shower Temp
  lcd.setCursor(9, 1);
  lcd.print(tempc);

  // Close Valve
  valve.write(0);
  delay(valvedelay);
  valve.write(90);

  // Close Hot
  hot.write(0);
  delay(hotdelay);
  hot.write(90);

  // Close Cold
  cold.write(0);
  delay(colddelay);
  cold.write(90);

  // Reset All States
  state = 0;
  templow = 0;
  temphigh = 0;
  tempc = 0;
  colddelay = 400;

  delay(1000);

  // Update ThingSpeak FINAL
  String headtemperature = String(tempc, DEC);
  String runtime = String(state, DEC);
  updateThingSpeak("field1=" + runtime + "&field2=" + headtemperature);

  delay(5000);

  // Clear LCD
  lcd.clear();
}

It seems Instructables text editor removes > and < so there might be some gaps in the code above.

Visit http://tvmiller.com/index.php?entry=entry160229-065021 for unadulterated script.

About This Instructable

298views

5favorites

License:

Bio: Privateer
More by TVMiller:Arduino Splash Resistant Toilet Foamer Arduino Motion Mute 1992 Isuzu Trooper Windshield Wiper Single Button Hack 
Add instructable to: