// Arduino IoT Shower
// vgmlr
// 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("");
client.print("
");
client.print("
");
client.print(settemp);
client.print("
");
client.print("");
client.print("");
client.print("");
client.print("");
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();
}