paul2021
Published © CC BY

Free hot water for Motorhome

Hot water tank for eMotorhomes Caravans or RVs powered by solar panels without flattening the battery with remote temperature monitoring.

AdvancedProtip242
Free hot water for Motorhome

Things used in this project

Hardware components

Arduino Nano 33 IoT
×1
Immersion heater
1kW 230Volt from https://www.ebay.co.uk/usr/midland_chandlers
×1
24V water heater
900Watts 24 volts immersion heater available from China / eBay
×1
Hot Water Tank
Custom made by Mc Donald. https://mcdonaldwaterstorage.com/products/bespoke-cylinders-and-tanks/bespoke-cylinders/
×1
Relay 24 Volts
×1

Story

Read more

Schematics

Hot Water Tank Arduino controller

Measures water and air temperature, prevents water temp exceeding 80C , can switch the 600W boost relay via IoT dashboard.

300W solar controller

Monitors battery voltage so that at 92% charge, it switches on the 300W water heater to keep the charge at this level to optimise battery cyclic life.

Code

IoT controller software

Arduino
Monitors water and air temperature, prevents over temperature.
// 6 July 2021 build

/*
  Sketch generated by the Arduino IoT Cloud Thing "Hot_Water_Tank"
  https://create.arduino.cc/cloud/things/9e616343-890c-45e8-a788-e54373992d4f

  Arduino IoT Cloud Variables description

  The following variables are automatically generated and updated when changes are made to the Thing

  CloudTemperatureSensor batTemp;
  CloudTemperatureSensor wtemp;
  bool overTemp;
  bool wboost;
  CloudTime boostTime;

  Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
  which are called when their values are changed from the Dashboard.
  These functions are generated with the Thing and added at the end of this sketch.
*/
#include "thingProperties.h"
#include <NTPClient.h>

// Basic sketch for Onewire temperature measureing devices. Devices can be connected in parallel on same digital pin
// note that a 4.7k resistor is needed to pull up the pin.
// for the Q hardware, digital pin 2 is used for the sensor
//Include the libraries we need
// onewire device ID = 284E1F4F351901FA is Battery temperature
// onewire device ID = 289765E32220016C is hot water temperature
#include <OneWire.h>
#include <DallasTemperature.h> // DallasTemperature(Galileo) for i586 - Version: Latest 
#define ONE_WIRE_BUS 2
#define TEMPERATURE_PRECISION 9

#define boostPin 4    // To switch on Boost relay (2 off 25V heaters)
#define overtempPin 3 // To prevent low power auto heater from turning on when high temp

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature.
DeviceAddress batTempID, wtempID; // for final version
// DeviceAddress wtempID;
// arrays to hold Temperature device addresses
// DeviceAddress tempBat = { 0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 };
// DeviceAddress tempWater   = { 0x28, 0x3F, 0x1C, 0x31, 0x2, 0x0, 0x0, 0x2 };
// ensd of Temperature defines

WiFiUDP ntpUDP;
// By default 'pool.ntp.org' is used with 60 seconds update interval and
// no offset
NTPClient timeClient(ntpUDP);

int count;
float elTime;  // elapsed time in seconds since last measurement
unsigned long currentSec = timeClient.getEpochTime();  // Epoch time = seconds since 1Jan1970

// boolean Wboost = 0;           // Turns off relay
boolean OverTemp = 0;         //turns off over temperature output
int boostTimer = -1;          // if boost timer less than one wBoost os off

//****************************************************************

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(boostPin, OUTPUT);
  pinMode(overtempPin, OUTPUT);

  Serial.begin(115200);         // Initialize serial and wait for port to open:
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  delay(1000); // wait for stabilisation)
  blinks(5);  // blink inbuilt LED 5 times to show startup
  digitalWrite(boostPin, LOW) ;
  boostTime = 1 ; // setup initial time for larger 25V heater is on, in minutes

  // Defined in thingProperties.h
  initProperties();

  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);

  /*
     The following function allows you to obtain more information
     related to the state of network and IoT Cloud connection and errors
     the higher number the more granular information you’ll get.
     The default is 0 (only errors).
     Maximum is 4
  */
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();
  boostTimer = -1 ;
  wboost = LOW;        // ensure boost is off to start with

  timeClient.begin();  // start looking for accurate time from server
  sensors.begin();     // Start up the Temp Sensor library

  Serial.print("Locating devices...");
  Serial.print("Found ");
  Serial.print(sensors.getDeviceCount(), DEC);
  Serial.println(" devices.");
  delay(1500);
  Serial.print("Parasite power is: ");
  if (sensors.isParasitePowerMode()) Serial.println("ON");
  else Serial.println("OFF");

 if (!sensors.getAddress(batTempID, 0)) Serial.println("Unable to find address for Device 0");
 if (!sensors.getAddress(wtempID, 1)) Serial.println("Unable to find address for Device ");
  sensors.setResolution(wtempID, TEMPERATURE_PRECISION);
  sensors.setResolution(batTempID, TEMPERATURE_PRECISION);




}

//****************************************************************
void loop() {


  ArduinoCloud.update();
  delay(100);
  Serial.print("Requesting temperatures...");
  sensors.requestTemperatures();
  Serial.println("DONE");
  wtemp = sensors.getTempC(wtempID);      // Hot Water Temperature
  batTemp = sensors.getTempC(batTempID);  // Battery Temp device ID

  Serial.print(" batTemp - wtemp = ");
  Serial.print(wtemp);
  Serial.print("- ");
  Serial.println(batTemp);


  if (wtemp > 78) {
    digitalWrite(overtempPin, HIGH); // turn off low power heater if water temp >78C
    overTemp = HIGH;
    digitalWrite(boostPin, LOW);     // turn off boost heater as well
    boostTimer = -1; // reset boost timer
    wboost = LOW;
  }
  if (wtemp < 72)  {
    digitalWrite(overtempPin, LOW);  // turn on heater circuit if weter temp lower
    overTemp = LOW;
  }
  Serial.print(" Timer = ");
  Serial.println(boostTimer);

  if (boostTimer > 0) {
    digitalWrite(boostPin, HIGH);
    boostTimer = (boostTimer - 2); // 2 second loops converted to minutes
    wboost = HIGH;
    blinks(2);
  }
  else {
    digitalWrite(boostPin, LOW);
    boostTimer = -1;
    wboost = LOW;
    blinks(1);
  }

  Serial.print("wboost = ");
  Serial.println(wboost);
  // ++++++++++++++++++++++++++
  boolean xboost;
  xboost = digitalRead(boostPin);
  Serial.print("xboost= ");
  Serial.println(xboost);
  

  delay(2000); // 2 second loops
}

void onOverTempChange() {
  // Do something
}

void onWboostChange() {
  boolean xboost;
  xboost = digitalRead(boostPin);
  Serial.print("xboost= ");
  Serial.println(xboost);
  if (wboost >= 1 && wtemp < 78) {
    boostTimer = (boostTime * 30) ;
    Serial.print("Boost Timer = ");
    Serial.println(boostTimer);

  }                                // Loops time = 2 seconds, converted to minutes

  Serial.println(boostTime);
}

void blinks(int howmany) {           // blinks for the number of times passed to the routine
  do {
    digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
    delay(200);                       // wait for half a second
    digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
    delay(200);                        // wait for half a second
    howmany = howmany - 1;
  } while (howmany > 0);
}


void onBoostTimeChange() {
  // Do something
}

Credits

paul2021
2 projects • 0 followers

Comments