One of my guys at work (Parkway Brewing) told me his neighbor had a hot tub that he wanted $50 for. How it the heck can you pass that kind of offer up? He said the pump did not work.
Me being the cheap bastard that I am (thanks Dad!) figured a new pump can’t be that expensive so off we went to pick this thing up. Turns out to be a SofTub Resort 300 (an older one but still). The price on this thing is outrageous.
We brought it home and I tore it apart to check the motor. Turns out the motor works just fine! Problem is the controller is shot. Some quick searching puts the cost way out of what I am willing to spend. Never mind that MrsProbrwr has told me the hot tub is REQUIRED!
Being the technically oriented and inquisitive person I am, I start looking into building my own controller. I make beer. I have made all kinds of temperature controllers in the past. But I wanted something more “cool” Enter the Arduino!
Now, mind you I have not programmed anything since high school and that was Apple and TRS Basic (I am old). So off I go on my favorite shopping site and I order a couple Arduino Starter kits. (here and here) because, you know, more than one is good!
On that note, This is truly a catch up post as the current version uses an Arduino Pro Micro but the original was developed and built with and Arduino UNO.
Programming is actually pretty easy and I was somewhat familiar with the interfaces from my 3d Printer builds. The following is the code I wrote to run the tub. It allows for the two speed pump and temperature control. Also turns the light on!
/* Hot Tub Control program for our Softub using a single 2 speed
pump and passive heating of the water.
*/
// Define pins and variables
int recircpumppin = 4;
int jetpumppin = 5;
int lightspin = 7
;
int jetSW = 21;
int lightSW = 20;
int buttonUp = 19; //initialize pin for Up Button
int buttonDown = 18; //initialize pin for down button
int Jet;
int Light;
int TempUP;
int TempDN;
int Recirc_state = HIGH;
int Light_state; // the current state of the output pin
int Light_reading; // the current reading from the input pin
int Light_previous; // the previous reading from the input pin
int Jet_state = LOW;
int Jet_reading;
int Jet_previous = LOW;
int curTemp;
int setTemp;
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Data wire is plugged into port 6 on the Arduino
#define ONE_WIRE_BUS 6
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time = 0; // the last time the output pin was toggled
long debounce = 150; // the debounce time, increase if the output flickers
void setup()
{
// Serial.begin(9600); // open the serial port at 9600 bps
pinMode(recircpumppin, OUTPUT);
pinMode(jetpumppin, OUTPUT);
pinMode(lightspin, OUTPUT);
pinMode(jetSW, INPUT);
pinMode(lightSW, INPUT);
digitalWrite(recircpumppin, HIGH);
digitalWrite(jetpumppin, LOW);
digitalWrite(lightspin, LOW);
//Start LCD
lcd.init();
lcd.backlight();
lcd.print("RocketHound");
lcd.setCursor(0, 1);
lcd.print("Hot Tub Control");
delay(5000);
lcd.clear();
//Set Variables
setTemp = 100;
// Start up the library
sensors.begin();
}
void loop()
{
// Read pins for buttons:
Jet = digitalRead(jetSW);
Light = digitalRead(lightSW);
if (Light == HIGH)Light_Change();
if (Jet == HIGH)Jet_ON();
TempRead();
/* Check to see if temperature is overheated and turn off pumps if so
*
*/
if (curTemp > 104){
digitalWrite(recircpumppin, LOW);
digitalWrite(jetpumppin, LOW);
}
/* Adjust Set temperature buy pressing up and down buttons
buttons are on two separate pins
*/
// Increase target temp
TempUP = digitalRead(buttonUp);
if (TempUP == HIGH) {
setTemp = setTemp + 1; // If button is pushed, move Target Temp up by 1
} else {
}
// Decrease target temp
TempDN = digitalRead(buttonDown);
if (TempDN == HIGH) {
setTemp = setTemp - 1; // If button is pushed, move Target Temp down by 1
} else {
}
// Write recirc state based on temperature
if (curTemp > setTemp && Jet_state == LOW) {
digitalWrite(recircpumppin, LOW);
} else {
}
if (curTemp < setTemp && Jet_state == LOW) {
digitalWrite(recircpumppin, HIGH);
} else {
}
/* Serial.print(Jet);
Serial.print("\t");
Serial.print(Light);
Serial.print("\t");
Serial.print(TempUP);
Serial.print("\t");
Serial.print(TempDN);
Serial.print("\t");
Serial.print(Light_state);
Serial.print("\t");
Serial.println(setTemp);
*/
delay(0);
}
void Jet_ON() //turn on Jet mode and disable recirc mode
{
Jet_reading = Jet;
// if the input just went from LOW and HIGH and we've waited long enough
// to ignore any noise on the circuit, toggle the output pin and remember
// the time
if (Jet_reading == HIGH /*&& Jet_previous == LOW */ && millis() - time > debounce) {
if (Jet_state == HIGH)
Jet_state = LOW;
else
Jet_state = HIGH;
if (Jet_state == LOW)
Recirc_state = HIGH;
else
Recirc_state = LOW;
time = millis();
}
digitalWrite(jetpumppin, Jet_state);
digitalWrite(recircpumppin, Recirc_state);
// previous = state;
}
// Jets_OFF();
void Light_Change() //Turn off the lights
{
Light_reading = Light;
// if the input just went from LOW and HIGH and we've waited long enough
// to ignore any noise on the circuit, toggle the output pin and remember
// the time
if (Light_reading == HIGH && Light_previous == LOW && millis() - time > debounce) {
if (Light_state == HIGH)
Light_state = LOW;
else
Light_state = HIGH;
time = millis();
}
digitalWrite(lightspin, Light_state);
// previous = state;
}
void TempRead()
{
// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
// Serial.print("Requesting temperatures...");
sensors.requestTemperatures(); // Send the command to get temperatures
curTemp = sensors.getTempFByIndex(0);
//Print to LCD
lcd.clear();
lcd.print("Set Temp: ");
lcd.print(setTemp);
lcd.write(0xDF);
lcd.print("F");
lcd.setCursor(0, 1);
lcd.print("Water Temp: ");
lcd.print(curTemp);
lcd.write(0xDF);
lcd.print("F");
delay(10);
}
This is freely given but not even remotely guaranteed!
I learned a few things. The solid state relays that I used say they will run with 3-32VDC but the Arduino just doesn’t put enough out to make that happen. I used some Mosfet’s to switch 12VDC to run the SSR’s and the LED lights. The 12VDC is stepped down to 5V on the custom circuit board I built to run the logic side of the board.
I picked up some parts from Amazon (Here, Here, Here, Here, and Here Plus some more… ) and built it all into this:
After all of it I may be $300 into it now. But… I also learned a lot about programming and I can use that in other projects in the future!