Steven H
Published

Servo Controlled Water Temperature

Arduino servo controlled water temperature for aquarium water refill.

IntermediateFull instructions provided1,289
Servo Controlled Water Temperature

Things used in this project

Hardware components

TM-785HB servo gearbox
×2
Adafruit 16 channel 12 bit PWM servo driver
×1
Tenergy 4.8v 2000mAH NiMH
×1
SparkFun Qwiic Keypad 12 Button
×1
SparkFun Micro OLED Breakout (Qwiic)
SparkFun Micro OLED Breakout (Qwiic)
×1
Temperature Sensor sen-11050
×1
Sparkfun Redboard Edge
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Drill / Driver, Cordless
Drill / Driver, Cordless
hacksaw

Story

Read more

Schematics

Servo controlled water temperature

Code

Servo_controlled_water_temperature.ino

Arduino
[code]
/*
  This project evolved from standing at the sink with a digital thermometer in the faucet
  stream trying to match the temperature of the aquarium, adjusting the hot and cold water
  to match as close as possible. The idea of servo controlled valves came to mind. Searching
  the internet I didn't find what I wanted. Then a youtube video showed an ordinary rc servo
  controlling a ball valve. I already had two heavy duty servos and the sink had two valves.
  The rest is this project.
*/
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 3
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
#include <Wire.h>
#include "SparkFun_Qwiic_Keypad_Arduino_Library.h"
KEYPAD keypad1;
String Str1 = "";
float setTemp = 75;     //ideal aquarium temperature
float actualTemp = 0;
int hotMin = 356;       //servo values for pwm board
int hotMax = 303;       //
int coldMin = 356;      //
int coldMax = 409;      //
int startHot = hotMax;
int startCold = coldMax;
#include <SFE_MicroOLED.h>
#define PIN_RESET 9
#define DC_JUMPER 1
MicroOLED oled(PIN_RESET, DC_JUMPER);
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
#define SERVOMIN 237
#define SERVOMAX 474
uint8_t servonum = 0;
void setup() {
  // put your setup code here, to run once:
  Wire.begin();
  keypad1.begin(Wire, 0x37);    //not the default address
  pwm.begin();
  pwm.setPWMFreq(60);
  oled.begin();    // Initialize the OLED
  oled.clear(ALL); // Clear the display's internal memory
  oled.display();  // Display what's in the buffer (splashscreen)
  delay(5000);
  sensors.begin();
  pwm.setPWM(0, 0, hotMin);
  pwm.setPWM(1, 0, coldMin);
  delay(10000);
  pwm.setPWM(0, 0, startHot);
  pwm.setPWM(1, 0, startCold);
  delay(10000);
  oled.clear(PAGE); // Clear the buffer.
  oled.setFontType(0);
  oled.display();
}
//-----------------------------------------------------------------------------
void loop() {
  // put your main code here, to run repeatedly:
  //---------------------------------------------------------------------------
  //Read desired temperature from keypad * = . # = enters value min 70F max 80F
  //---------------------------------------------------------------------------
  keypad1.updateFIFO();
  char button = keypad1.getButton();
  if (button != 0)
  {
    if (button == '#')
    {
      Str1 = (Str1.substring(0, 5));
      setTemp = (Str1.toFloat());
      if (setTemp >= 80) {    //Max temp for aquarium
        setTemp = 80;
      }
      if (setTemp <= 40) {    //40 turns valves off
        setTemp = 40;
      }
      Str1 = "";
    }
    else if (button == '*')
    {
      Str1 = Str1 + ".";
    }
    else
    {
      Str1 = Str1 + button;
    }
  }
  delay(25);
  //--------------------------------------------------------------------------
  //Read water temperature
  //--------------------------------------------------------------------------
  sensors.requestTemperatures();
  float temp1C = sensors.getTempCByIndex(0);
  oled.setCursor(0, 0);
  oled.print("Temp F: ");
  oled.setCursor(10, 12);
  oled.print(DallasTemperature::toFahrenheit(temp1C));
  actualTemp = (DallasTemperature::toFahrenheit(temp1C));
  //float temp2C = sensors.getTempCByIndex(1);
  oled.setCursor(0, 24);
  oled.print("Temp F: ");
  oled.setCursor(10, 36);
  oled.print(setTemp);
  //oled.print(DallasTemperature::toFahrenheit(temp2C));
  oled.display();
  if ((actualTemp < setTemp - 1) || (actualTemp > setTemp + 1)) {
    valves();
    delay(7500);
  }
}
//----------------------------------------------------------------------------
void valves()
{
  //--------------------------------------------------------------------------
  //Valve control of hot and cold water
  //--------------------------------------------------------------------------
  if (actualTemp < setTemp - 1 && startCold == coldMax) {
    startHot = startHot - 1;
    if (startHot <= hotMax) {
      startHot = hotMax;
    }
    pwm.setPWM(0, 0, startHot);
  }
  if (actualTemp < setTemp - 1 && startHot == hotMax) {
    startCold = startCold - 1;
    if (startCold <= coldMin) {
      startCold = coldMin;
    }
    pwm.setPWM(1, 0, startCold);
  }
  if (actualTemp > setTemp + 1 && startCold == coldMax) {
    startHot = startHot + 1;
    if (startHot >= hotMin) {
      startHot = hotMin;
    }
    pwm.setPWM(0, 0, startHot);
  }
  if (actualTemp > setTemp + 1 && startCold == coldMin) {
    startHot = startHot + 1;
    startCold = startCold + 1;
    if (startHot >= hotMin) {
      startHot = hotMin;
    }
    if (startCold >= coldMax) {
      startCold = coldMax;
    }
    pwm.setPWM(0, 0, startHot);
    pwm.setPWM(1, 0, startCold);
  }
  if (actualTemp > setTemp + 1) {
    startCold = startCold + 1;
    if (startCold >= coldMax) {
      startCold = coldMax;
    }
    pwm.setPWM(1, 0, startCold);
  }
  if (setTemp == 40) {
    startHot = hotMin;
    startCold = coldMin;
    pwm.setPWM(0, 0, startHot);
    pwm.setPWM(1, 0, startCold);
  }
}
[/code]

Credits

Steven H

Steven H

2 projects • 1 follower

Comments