Arduino Controlled PC Water Cooling System info center.

This is actually a side project for my COD MW2 case mod found here. I plan on building a water pump cover that has a 16x2 or 20x4 LCD that will display several parameters about the water cooling system including: 2 temperature locations, 2 Fan RPM readings, Pump RPM, liquid flow rate and possibly even an audio alarm in the event of pump / flow failure.

This is what I have so far.


The 2 10k thermistors are 2 temp sensors from Bits Power which use a 10k thermistor epoxied into the stop fitting. The 10k Trim pot is there to set the contrast on the LCD.

What I have left to do

  • Figure out flow meter
  • Figure out how to read pump rpm (PPM signal on yellow wire?)
  • Write code
  • Set alarm parameters.

My fritzing page on this project. (Download all the files there)

Here is the beginning of the code. All of my code is still in the dev phaze. Right now I have it outputting the correct temp in C and F to the Display now.

[code]#include <LiquidCrystal.h>
#include <math.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
double Thermistor(int RawADC) {
long Resistance;
double Temp;
Resistance=((10240000/RawADC) - 10000);
Temp = log(Resistance);
Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));
Temp = Temp - 273.15;
return Temp;

void printDouble(double val, byte precision) {

lcd.print (int(val));
if( precision > 0) {
unsigned long frac, mult = 1;
byte padding = precision -1;
while(precision–) mult *=10;
if(val >= 0) frac = (val - int(val)) * mult;
else frac = (int(val) - val) * mult;
unsigned long frac1 = frac;
while(frac1 /= 10) padding–;
while(padding–) Serial.print(“0”);
lcd.print(frac,DEC) ;

void setup() {
lcd.begin(16, 2);

#define ThermistorPIN 0
#define Thermistor2PIN 1
double temp;
void loop() {
lcd.setCursor(0, 0);
lcd.print("Sensor 1 ");
lcd.setCursor(0, 1);
lcd.print(“Sensor 2 “);
//uncomment the next 4 lines for temp display in F
//temp = (temp * 9.0)/ 5.0 + 32.0;



Code sources

The water pump I have selected outputs RPM signals similar to a standard three wire PC fan. In fact you can plug the signal wire to the CPU fan header on a motherboard and if your pump dies or stops sending a signal it will shut your PC down to prevent a CPU failure due to heat. While a nice feature for safety, it will be much cooler to see the RPM at which your pump is running than knowing your CPU wont melt if it dies right?

Since the Fan and Pump RPM signals are so similar, and my water pump has not arrived yet I decided to dev using a 120mm PC fan. The following schematic should explain how to wire things up.


This is pretty simple to hook up. First you need to run the Signal wire (almost always yellow) to the breadboard. Then from it connect a jumper wire to Arduino Digital Pin 2. Also from the sensor wire you need to connect a 10k resistor to the Arduino’s 5V pin. This is a simple pull-up resistor. We also need to make sure that we connect the fans ground line to one of the Arduino’s ground pins. Next just connect the fans power wire to the PSUs 12v line and the fans ground wire to the PSUs ground.

Now upload the following code to your Seeeduino, and then open the serial terminal. Again I would like to thank Crenn from for his help figuring out the code. Please note that this code will change in the final part of the project. The Fan / Pump RPM will be displayed on the LCD from the first post in this thread.

[code]//code by Crenn from
//project by Charles Gantt from

/*To disable interrupts:
cli(); // disable global interrupts

and to enable them:
sei(); // enable interrupts

                               //Varibles used for calculations

int NbTopsFan;
int Calc;

                              //The pin location of the sensor

int hallsensor = 2;

typedef struct{ //Defines the structure for multiple fans and their dividers
char fantype;
unsigned int fandiv;

//Definitions of the fans
fanspec fanspace[3]={{0,1},{1,2},{2,8}};

char fan = 1; //This is the varible used to select the fan and it’s divider, set 1 for unipole hall effect sensor
//and 2 for bipole hall effect sensor

void rpm () //This is the function that the interupt calls

          //This is the setup function where the serial port is initialised,
         //and the interrupt is attached

void setup()
pinMode(hallsensor, INPUT);
attachInterrupt(0, rpm, RISING);
void loop ()
NbTopsFan = 0; //Set NbTops to 0 ready for calculations
sei(); //Enables interrupts
delay (1000); //Wait 1 second
cli(); //Disable interrupts
Calc = ((NbTopsFan * 60)/fanspace[fan].fandiv); //Times NbTopsFan (which is apprioxiamately the fequency the fan is spinning at) by 60 seconds before dividing by the fan’s divider
Serial.print (Calc, DEC); //Prints the number calculated above
Serial.print (" rpm\r\n"); //Prints " rpm" and a new line

You should see an RPM output in the serial terminal. It is accurate within 10-15 RPM of the fans actual RPM which is close enough for me. If your RPM output seems to be double what it should be your fan may have a bipolar Hall efect sensor and its counting each pass of the magnets pole as a single RPM when each should be 1/2 an RPM. No worries though as this is an easy fix. Just simply change the " char fan = 0 code from 0 to 1. Upload the modified code and you should be seeing accurate RPM numbers.

Next time we will cover how to measure and display the liquid flow rate of the system.

What I have left to do:[/SIZE]

  • Work out flow meter design and schematic
  • Determine alarm parameters
  • Complete code and refine it.

My fritzing page on this project.(Download all the files there)
Reading PC Fan / Water Pump RPM with an Arduino

The problem is that it takes an entire second to count RPM, which will delay the updates to your LCD. This may be acceptable or not. If you have a fast RPM and don’t care about precision, you can reduce the sampling interval to 500 msecs or even 250 msecs.

One other way to count RPM is to count the time in msecs it takes between each HIGH of the rpm sensor, then use this formula: rpm = 60 secs/min * 1000 msecs/sec * timebetweenpulses msecs

What some people do is use the pulses-per-one-second method for fast RPMs and then switch to time-between-pulses for slow RPMs.


Hey Karen,

Yes as the polling time decreases so does the accuracy. Having it poll for 1 second is acceptable for this project but I may move down to .5 seconds as I will have a total of 4 hall effect sensors to poll data from.

The RPMs we see from PC fans and water pumps are pretty high. Fans are around 1600-2000 rpm and most water pumps run in the 3600-4000 rpm range. My hope is to have the project sound an alarm if the rpm drops below 2800 rpm or stops completely.

I am working with a friend on a completely new code for the fan and pump RPM. We are having to work in a multiplexer to switch between hall effect sensors because the ATMega 128 and 328 both only have 2 interrupts. I am expecting project completion to be some time in July.

The only thing I have not deved is the water flow rate. I do have some Water Flow Sensors on the way from Seeed Studio though. They will not be hard to set up, I will just have to modify my existing code and convert their rpm into liters per hour flow.

Here are a few photos and a schematic of my development setup. The pump is a CPX Pro from Temp sensors are from Bitspower and contain 10k thermistors, the fan is a generic NZXT 120mm

I am getting close to wrapping this project up. I am just waiting on my flow sensors to arrive and some multiplexers. As soon as everything gets here and I confirm that things work like I planned I will be using Seeed’s PCB service to make some arduino shield style boards.

Wonderful project well explained! :slight_smile:

Thanks Eric!!

I am still working on refining the board but thought I would post my latest revision to the schematic. This was created in Eagle. I will get a new fritzing schematic up soon.

Click the image for a full sized version.
Click the image for a full sized version.

Just wanted to add a quick update to this. I have also added PWM PC fan control and have finished my standalone board design.