Skip to main content

Differential Temperature Controller


Differential Temperature Controller

We had a need to control the temperature inside of our Solar Equipment Bay up at the Ranch. The Bay sits outside on our porch, and for some hours during the day, the sun shines directly on it. When this happens the interior acts like an oven, quickly heating up and subjecting the charge controller and inverter to temperatures that approach their maximum rating.

We decided that part of the solution would be ventilation fans installed on the enclosure. We didn’t want the fans to run full time, since this is a solar system, and total power is limited by what we generate. Also, it didn’t make sense to allow the fans to turn on when outside temperatures were higher than inside temperatures. So I thought that a differential temperature controller would be ideal.

In Operation

With this system, the fans would stay off as long as the temperature inside the box was below 80 degrees, or when the inside temperature was lower than the outside temperature.

When these conditions go away, the fans turn on and remain on until the interior cools below 80 degrees, or the outside temperature exceeds the interior temperature. They stay on for an additional two minutes (just to reduce the number of cycles), then turn off.

A differential temperature controller on EBay or Amazon run around $135 to $150. By using a $8 Arduino Nano microcontroller, and a few other parts, I was able to build one for under $20.

The installation for this system is documented on the Ranch Website at .

The circuit is minimal, with most of the Arduino legs left disconnected. There is a 7805 to drop the 12 volts down to 5 volts for the Arduino. And there is a TIP-120 Darlington Amplifier to take the output of the Arduino and drive two fans off of the 12 volt input.

Here is the schematic…

Differential Temperature Controller Schematic

There is a neat tool called “Fritzing” that allows you to build a virtual circuit on a breadboard on your computer, and it will create a schematic for you. The neat part is the visual wiring diagram, though


Finally, here is the real thing in operation at the Ranch


In Operation


Note** If you cut and paste the following code into your Arduino IDE, you may get some errors referring to stray XXX, with some numbers where the XXX is.

This is because of the way browsers save some characters as non-ascii characters. I found that in particular, the quote marks in the various Serial.print and Serial.println statements are misinterpreted. To fix this, you can erase the quote marks, and retype them in your Arduino IDE. Then save and recompile the sketch. That fixed it for me.

Alternatively, you may try downloading the code form the diff_thermo.ino link just above this note. Good luck, and have fun. Randy WB0SMX

Here is the main chunk of code…

Hacked from the “multiple” demo of the Dallas 1-wire ds18b20 library.

#include <DallasTemperature.h>
// Data wire is plugged into port 3 on the Arduino
#define ONE_WIRE_BUS 3

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

// arrays to hold device addresses
// Change the addresses to match your ds18b20 devices
DeviceAddress insideThermometer = { 0x28, 0xE5, 0x27, 0x96, 0x05, 0x00, 0x00, 0xA8 };
DeviceAddress outsideThermometer = { 0x28, 0xAB, 0xA6, 0x96, 0x05, 0x00, 0x00, 0xC8 };

// Global variables
float InsideTempC, InsideTempF, OutsideTempC, OutsideTempF;
float HighTempSetpoint = 80.0;
boolean Cooling = false;
int timer = 0;
// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int fan = 13;
void setup(void)
// initialize the digital pin as an output.
pinMode(fan, OUTPUT);
digitalWrite(fan, LOW); // turn the Fan off (LOW is the voltage level)
// start serial port
Serial.println(“Dallas Temperature IC Control Library Demo”);

// Start up the library
// set the resolution as defined above
sensors.setResolution(insideThermometer, TEMPERATURE_PRECISION);
sensors.setResolution(outsideThermometer, TEMPERATURE_PRECISION);
// confirm the resolution was set
Serial.print(“Inside Thermometer Resolution: “);
Serial.print(sensors.getResolution(insideThermometer), DEC);
Serial.print(“Outside Thermometer Resolution: “);
Serial.print(sensors.getResolution(outsideThermometer), DEC);

// function to get the temperature for a device
float getTemperature(DeviceAddress deviceAddress)
float tempC = sensors.getTempC(deviceAddress);
return tempC;

// function to print a device’s resolution
void printResolution(DeviceAddress deviceAddress)
Serial.print(“Resolution: “);


void loop(void){
// No need to go as fast as we can
// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
Serial.print(“Requesting temperatures…”);
OutsideTempC = getTemperature(outsideThermometer);
OutsideTempF = DallasTemperature::toFahrenheit(OutsideTempC);
InsideTempC = getTemperature(insideThermometer);
InsideTempF = DallasTemperature::toFahrenheit(InsideTempC);
// print the device information
Serial.print(“Inside Temperature: “);
Serial.print(“Temp C: “);
Serial.print(” Temp F: “);

Serial.print(“Outside Temperature:”);
Serial.print(” “);
Serial.print(“Temp C: “);
Serial.print(” Temp F: “);

// Turn on Fans if inside temp is above setpoint
// … and inside temp is higher than outside temp
if((InsideTempF > HighTempSetpoint)&&(InsideTempF > OutsideTempF))
digitalWrite(fan, HIGH); // turn the Fan on (HIGH is the voltage level)
Cooling = true;
timer = 0;
// keep track of delay to shut off fan
else if (((InsideTempF < HighTempSetpoint)&&(Cooling == true))||((InsideTempF <= OutsideTempF)&&(Cooling == true)))
timer += 1;
Serial.print(“timer = “);
// once we have been cool enough for about 2 minutes, turn off the fan
// assumes loop delay of 10000 ms set above
if (timer >= 12)
digitalWrite(fan, LOW); // turn the Fan off (LOW is the voltage level)
Cooling = false;
timer = 0;
if (Cooling == true)
Serial.println(“Fan is ON”);

Migrated Comments:

2 Responses to “Differential Temperature Controller”

  1. Toni Says:

    I’m beginner in electronics and Arduino technics, so, please, be patient with my maybe stupid questions.
    I’m thinking about constructing similar differential temperature controller as yours, so I’m studding your one and have two questions about your circuit:

    1. Did you think about MOSFET instead of TIP 120 transistor to power the motor? Why did you choose TIP 120?

    2. Did you know Arduino Micro can be powered in the range from 6-20 V (7-12V recomended)? (
    If you did – why did you use voltage regulator?

    Thanks in advance



  2. wb0smx Says:

    Hi Toni. Good questions.
    I have limited experience with the Arduino line of controllers. I referenced the book, “Arduino Workshop”, by John Boxall to determine how to drive an electric motor with the Arduino. He recommends a TIP120 Darlington transistor. I had one of these handy, so I settled on that design. It seems that a suitable MosFet may work as well, but I was just too lazy to pursue it, when I already had a solution.

    As for the operating voltage, the Temperature sensors require somewhere around 3 – 5 volts. Since I needed this voltage, I decided to use it for the Arduino, as well. It has been running for 2 years in this configuration with no failures. So I think it will be OK with that voltage.

    Good luck in your project. It has worked out very well for me.
    Thanks and 73… Randy WB0SMX


Popular posts from this blog

Building the W8NX Short Trap Dipole

Yaesu G-450XL Rotator Repair

JuncTek Battery Monitor MQTT Controller