Parts list
| Part | Qty | Approx. | Buy |
|---|---|---|---|
| Arduino Uno R3 (CH340 clone) | 1 | ₹450 | Buy Arduino Uno R3 (CH340 clone) |
| DS18B20 waterproof probe, stainless, 3 m lead (high-temperature cable) | 2 | ₹600 | Buy DS18B20 waterproof probe, stainless, 3 m lead (high-temperature cable) |
| 4.7 kΩ resistor | 1 | ₹2 | Buy 4.7 kΩ resistor |
| 16×2 LCD with I2C backpack (PCF8574, 0x27) | 1 | ₹180 | Buy 16×2 LCD with I2C backpack (PCF8574, 0x27) |
| 3-core cable from the terrace (10–15 m) + junction box | 1 | ₹250 | Buy 3-core cable from the terrace (10–15 m) + junction box |
| Aluminium tape + pipe insulation to cover the probes | 1 | ₹100 | Buy Aluminium tape + pipe insulation to cover the probes |
| 5 V 1 A USB adapter + cable | 1 | ₹120 | Buy 5 V 1 A USB adapter + cable |
| Total | ₹1,702 |
Affiliate disclosure: “Buy” links may earn FlashReady a small commission at no extra cost to you. Prices are indicative.
Wiring
| Arduino Uno R3 | Part · pin | Wire | Notes |
|---|---|---|---|
| D2 | DS18B20 (1-Wire) · DQ | yellow | Tank probe — both probes share the one 1-Wire bus |
| 5V | DS18B20 (1-Wire) · DQ | red | Via 4.7 kΩ — One pull-up for the whole bus |
| 5V | DS18B20 (1-Wire) · VDD | red | |
| GND | DS18B20 (1-Wire) · GND | black | |
| D2 | DS18B20 (1-Wire) #2 · DQ | yellow | Cold-inlet probe, same bus |
| 5V | DS18B20 (1-Wire) #2 · VDD | red | |
| GND | DS18B20 (1-Wire) #2 · GND | black | |
| SDA | 16×2 LCD + I2C backpack · SDA | blue | |
| SCL | 16×2 LCD + I2C backpack · SCL | yellow | |
| 5V | 16×2 LCD + I2C backpack · VCC | red | |
| GND | 16×2 LCD + I2C backpack · GND | black |
Board quirks: Many ETC (glass-tube) solar heaters have a thermowell or sensor pocket on the tank — slide the probe in there. If yours doesn’t, tape the probe tightly to the hot outlet pipe right at the tank with aluminium tape and cover it with pipe insulation. Never drill the tank. Tanks can reach 80–90 °C on summer afternoons. Use a probe with high-temperature (silicone/PTFE) cable; the common PVC-lead probes are rated only to about 70 °C at the cable. Both probes share D2. The sketch picks them by index (TANK_INDEX = 0, COLD_INDEX = 1); if the Serial Monitor shows the tank reading on “cold”, swap the two numbers. A long 1-Wire cable from the terrace works at 10–15 m with one 4.7 kΩ pull-up at the Uno. For longer runs, lower the pull-up to 2.2 kΩ and use twisted pair.
Code
// Solar water heater "how much hot water?" display — Arduino Uno + 2x DS18B20 + 16x2 I2C LCD
// Both DS18B20 probes on D2 (one 1-Wire bus) with a 4.7 kΩ pull-up to 5V.
// Probe "tank": in the tank's sensor pocket or on the hot outlet pipe under the insulation.
// Probe "cold": on the cold-water inlet pipe. The LCD shows both, and how many 20-litre
// buckets of 40 °C bath water the tank can give after mixing with cold water.
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
constexpr uint8_t BUS_PIN = 2;
constexpr uint8_t TANK_INDEX = 0; // swap 0/1 if the Serial Monitor shows them the wrong way round
constexpr uint8_t COLD_INDEX = 1;
constexpr float TANK_LITRES = 150; // your heater's size (100 / 150 / 200 L)
constexpr float BATH_C = 40; // comfortable bath water
constexpr float BUCKET_L = 20;
constexpr float SCALD_C = 65;
OneWire bus(BUS_PIN);
DallasTemperature probes(&bus);
LiquidCrystal_I2C lcd(0x27, 16, 2);
bool ok(float c) { return c > -50 && c < 100 && c != 85.0; } // -127 = missing, 85 = power-on value
void setup() {
Serial.begin(115200);
probes.begin();
lcd.init();
lcd.backlight();
lcd.print(F("Solar heater"));
Serial.print(F("Probes found: "));
Serial.println(probes.getDeviceCount());
}
void loop() {
probes.requestTemperatures();
float tank = probes.getTempCByIndex(TANK_INDEX);
float cold = probes.getTempCByIndex(COLD_INDEX);
char line[17];
lcd.setCursor(0, 0);
if (!ok(tank)) {
lcd.print(F("Tank probe? "));
} else if (!ok(cold)) {
snprintf(line, sizeof line, "Tank %3dC cold ?", (int)tank);
lcd.print(line);
} else {
snprintf(line, sizeof line, "Tank %3dC Cold%2d", (int)tank, (int)cold);
lcd.print(line);
}
lcd.setCursor(0, 1);
if (!ok(tank)) {
lcd.print(F("check D2 + 4.7k "));
Serial.println(F("Tank probe not found - check the 1-Wire bus on D2 and the 4.7k pull-up"));
} else {
// Mixing: hot + cold to reach BATH_C. Litres of bath water = tank x (Th - Tc) / (Tbath - Tc).
float tc = ok(cold) ? cold : 25;
float bathL = tank > BATH_C && BATH_C > tc ? TANK_LITRES * (tank - tc) / (BATH_C - tc) : 0;
int buckets = (int)(bathL / BUCKET_L);
if (tank >= SCALD_C) snprintf(line, sizeof line, "HOT! %2d buckets ", buckets);
else if (buckets > 0) snprintf(line, sizeof line, "~%2d buckets @40C", buckets);
else snprintf(line, sizeof line, "Not hot yet ");
lcd.print(line);
Serial.print(F("tank="));
Serial.print(tank, 1);
Serial.print(F(" cold="));
Serial.print(cold, 1);
Serial.print(F(" bathL="));
Serial.print(bathL, 0);
Serial.print(F(" buckets="));
Serial.println(buckets);
}
delay(5000);
}// Solar water heater "how much hot water?" display — Arduino Uno + 2x DS18B20 + 16x2 I2C LCD
// Both DS18B20 probes on D2 (one 1-Wire bus) with a 4.7 kΩ pull-up to 5V.
// Probe "tank": in the tank's sensor pocket or on the hot outlet pipe under the insulation.
// Probe "cold": on the cold-water inlet pipe. The LCD shows both, and how many 20-litre
// buckets of 40 °C bath water the tank can give after mixing with cold water.
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
constexpr uint8_t BUS_PIN = 2;
constexpr uint8_t TANK_INDEX = 0; // swap 0/1 if the Serial Monitor shows them the wrong way round
constexpr uint8_t COLD_INDEX = 1;
constexpr float TANK_LITRES = 150; // your heater's size (100 / 150 / 200 L)
constexpr float BATH_C = 40; // comfortable bath water
constexpr float BUCKET_L = 20;
constexpr float SCALD_C = 65;
OneWire bus(BUS_PIN);
DallasTemperature probes(&bus);
LiquidCrystal_I2C lcd(0x27, 16, 2);
bool ok(float c) { return c > -50 && c < 100 && c != 85.0; } // -127 = missing, 85 = power-on value
void setup() {
Serial.begin(115200);
probes.begin();
lcd.init();
lcd.backlight();
lcd.print(F("Solar heater"));
Serial.print(F("Probes found: "));
Serial.println(probes.getDeviceCount());
}
void loop() {
probes.requestTemperatures();
float tank = probes.getTempCByIndex(TANK_INDEX);
float cold = probes.getTempCByIndex(COLD_INDEX);
char line[17];
lcd.setCursor(0, 0);
if (!ok(tank)) {
lcd.print(F("Tank probe? "));
} else if (!ok(cold)) {
snprintf(line, sizeof line, "Tank %3dC cold ?", (int)tank);
lcd.print(line);
} else {
snprintf(line, sizeof line, "Tank %3dC Cold%2d", (int)tank, (int)cold);
lcd.print(line);
}
lcd.setCursor(0, 1);
if (!ok(tank)) {
lcd.print(F("check D2 + 4.7k "));
Serial.println(F("Tank probe not found - check the 1-Wire bus on D2 and the 4.7k pull-up"));
} else {
// Mixing: hot + cold to reach BATH_C. Litres of bath water = tank x (Th - Tc) / (Tbath - Tc).
float tc = ok(cold) ? cold : 25;
float bathL = tank > BATH_C && BATH_C > tc ? TANK_LITRES * (tank - tc) / (BATH_C - tc) : 0;
int buckets = (int)(bathL / BUCKET_L);
if (tank >= SCALD_C) snprintf(line, sizeof line, "HOT! %2d buckets ", buckets);
else if (buckets > 0) snprintf(line, sizeof line, "~%2d buckets @40C", buckets);
else snprintf(line, sizeof line, "Not hot yet ");
lcd.print(line);
Serial.print(F("tank="));
Serial.print(tank, 1);
Serial.print(F(" cold="));
Serial.print(cold, 1);
Serial.print(F(" bathL="));
Serial.print(bathL, 0);
Serial.print(F(" buckets="));
Serial.println(buckets);
}
delay(5000);
}Compiled for uno on avr 1.8.8 with OneWire 2.3.8 · 3 Nov 2026
How it works
A solar water heater on the terrace is common across India — Bengaluru, Pune and much of the south have them on almost every house. But nobody inside knows whether the water is hot until the tap has run cold water for a minute. On cloudy monsoon days, or after the whole family has bathed, the answer matters: is there enough for one more bath, or should the electric backup go on?
How it works
Two DS18B20 probes share one 1-Wire bus on D2 with a single 4.7 kΩ pull-up. One reads the tank (in its sensor pocket or on the hot outlet), the other the cold inlet pipe. Every 5 seconds the Uno reads both and shows them on the 16×2 LCD.
The useful number is the second line. Bath water is hot water mixed with cold to about 40 °C. Energy balance says:
litres of 40 °C water = tank litres × (tank °C − cold °C) ÷ (40 − cold °C)
So a 150 L tank at 60 °C with 25 °C inlet water gives 150 × 35 ÷ 15 = 350 L of 40 °C water — about 17 buckets of 20 L. The LCD shows ~17 buckets @40C. Below 40 °C it shows “Not hot yet”, and above 65 °C it says HOT! — mix in cold water first; 65 °C scalds skin in a couple of seconds.
The estimate assumes the whole tank is at the measured temperature. Real tanks are hotter at the top, so take it as a good guide, not a promise.
Why these parts
- DS18B20 — sealed, accurate, and several can share one data wire down from the terrace.
- Uno + I2C LCD — simple, 5 V, and the LCD is readable from the bathroom door.
India notes
In north Indian winters the inlet water can be 10 °C, which makes each degree in the tank worth less bath water — the formula accounts for that. Also check that the overhead tank feeding the heater never runs dry: an empty ETC heater in the sun can crack its glass tubes.
Troubleshooting
The LCD says “Tank probe?”
The Uno can’t find the probe. Check the pull-up between DQ and 5V, the three wires at the terrace junction box (water gets in there in the monsoon), and that “Probes found: 2” prints at start.
The bucket count seems too high
Probe on the outlet pipe reads hotter than the tank average while water is flowing, and much colder at night. Use the sensor pocket if you can, and set TANK_LITRES to your heater’s real size (it’s on the label).
Readings jump to 85 °C
85 °C is the DS18B20’s power-on value — a supply dip on the long cable. The sketch ignores it; if it happens often, add a 100 nF capacitor across VDD and GND at the probe.
Upgrades
- Switch an electric backup heater element only when the tank is below 40 °C at 6 a.m. (through a contactor, electrician-wired).
- Send the morning tank temperature to your phone with an ESP32.
- Log the daily peak temperature to see when the glass tubes need cleaning.



