Media server fan control

Construction date: June 24, 2014IMG_0013

Cost: 48 dollars

Time to build: 6

Status: Completed

 

*New update* 7/9/2014

I have competed a good section of the code it is very close to finished all three fans can be controlled and the three temp sensors are reporting stable reading back to the micro controller. I have also finished most of the prototype board so everything is hard mounted now I will be loading pictures of the progress soon.  I have already reflected the most recent code below. This includes a optional funny text loading bit that can be removed if so desired.

*old update*

A friend asked if I could make a fan controller and I said I could. Then I told him just go buy one. He stated that many of the fan controllers at the 50 dollar price range did not have many features. This of course surprised me and I looked into building one for him. Only the best “cheapest” parts were sourced for the build and I ended up with a design I could be proud of.

Basic features will include:

  • Work with the server voltages
  • Have 3 zone fan control
  • Have 3 zone temperature input
  • Display readings to a USB serial monitor

Possible extra features include:

  • Color matching (Done)
  • Sensing when fans rpm’s are low
  • Sense if fan is not turning
  • Small serial display for fan rpm/temp
  • A uber load text wall for no good reason (Done)
  • Monkeys (Done)

Parts list:

Mostly sourced from Sparkfun electronics

COM-00523 Electrolytic Decoupling Capacitors – 10uF/25V 1 $0.45
DEV-12640 Pro Micro – 5V/16MHz 1 $19.95
PRT-00115 Female Headers 1 $1.50
PRT-00116 Break Away Headers – Straight 1 $1.50
PRT-12070 Solder-able Breadboard 1 $4.95
ROB-09187 Servo Cable – Female to Female 3  $8.85
SEN-10988 Temperature Sensor – TMP36 3  $4.50

Odds and ends include:

Solder
.1 uf caps 3 meh
PWM fan to test 1 $9.95

 

IMG_0010

 

Below is code for reading temperature with the TMP36

 


int pwmPin0 = 3; // digital pin 3
int pwmPin1 = 5; // digital pin 5
int pwmPin2 = 6; // digital pin 6
int pwmVal0 = 0;
int pwmVal1 = 0;
int pwmVal2 = 0;
unsigned int rpm0; // Zone 1
unsigned int rpm1; // Zone 2
unsigned int rpm2; // Zone 3
String stringRPM0;
String stringRPM1;
String stringRPM2;
const int numReadings0 = 10;
const int numReadings1 = 10;
const int numReadings2 = 10;
int readings0[numReadings0]; // the readings from the analog input
int readings1[numReadings1];
int readings2[numReadings2];
int index0 = 0; // the index of the current reading
int index1 = 0;
int index2 = 0;
int total0 = 0; // the running total
int total1 = 0;
int total2 = 0;
int average0 = 0; // the average
int average1 = 0;
int average2 = 0;
int sensorPin0 = 18;
int sensorPin1 = 19;
int sensorPin2 = 20; //the analog pin the TMP36's Vout (sense) pin is connected to
 //the resolution is 10 mV / degree centigrade with a
 //500 mV offset to allow for negative temperatures
const int threshold = 65000; 

/*
 * setup() - this function runs once when you turn your Arduino on
 * We initialize the serial connection with the computer
 */
void setup()
{
 pinMode(pwmPin0, OUTPUT); // sets the pin as output
 pinMode(pwmPin1, OUTPUT); // sets the pin as output
 pinMode(pwmPin2, OUTPUT); // sets the pin as output
 Serial.begin(9600); //sets baud rate
 digitalWrite(2, HIGH); // Starts reading
 digitalWrite(4, HIGH); // Starts reading
 digitalWrite(7, HIGH); // Starts reading
 for (int thisReading0 = 0; thisReading0 < numReadings0; thisReading0++)
 readings0[thisReading0] = 0;
 for (int thisReading1 = 0; thisReading1 < numReadings1; thisReading1++)
 readings1[thisReading1] = 0;
 for (int thisReading2 = 0; thisReading2 < numReadings2; thisReading2++)
 readings2[thisReading2] = 0;
delay(5000); // delay in between reads for stability
Serial.println("Recalibrating orbital satilites");
delay(100); // delay in between reads for stability
Serial.println(".");
delay(200); // delay in between reads for stability
Serial.println("..");
delay(300); // delay in between reads for stability
Serial.println("...");
delay(500); // delay in between reads for stability
Serial.println("....");
delay(800); // delay in between reads for stability
Serial.println(".....");
delay(1000); // delay in between reads for stability
Serial.println("starting monkey motivator");
delay(100); // delay in between reads for stability
Serial.println("starting monkey task: make tea");
delay(100); // delay in between reads for stability
Serial.println("calibrating canned whoop-ass cannon");
delay(100); // delay in between reads for stability
Serial.println("opening communications with starship enterprise");
delay(100); // delay in between reads for stability
Serial.println("calibratiing temp sensors");
delay(100); // delay in between reads for stability
Serial.println("pausing for tea break");
delay(1000); // delay in between reads for stability
Serial.println("searching for waldo");
delay(3000); // delay in between reads for stability
Serial.println("calculating winning lottery numbers");
delay(100); // delay in between reads for stability
Serial.println("Loading goat simulator");
delay(2000); // delay in between reads for stability
Serial.println("Acheivement unlocked: licking helicopters");
delay(100); // delay in between reads for stability 

}

void loop()

{
 // subtract the last reading: Zone 1
 total0= total0 - readings0[index0];
 // read from the sensor:
 readings0[index0] = analogRead(sensorPin0);
 // add the reading to the total:
 total0= total0 + readings0[index0];
 // advance to the next position in the array:
 index0 = index0 + 1; 

 // if we're at the end of the array...
 if (index0 >= numReadings0)
 // ...wrap around to the beginning:
 index0 = 0; 

 // subtract the last reading: Zone 2
 total1= total1 - readings1[index1];
 // read from the sensor:
 readings1[index1] = analogRead(sensorPin1);
 // add the reading to the total:
 total1= total1 + readings1[index1];
 // advance to the next position in the array:
 index1 = index1 + 1; 

 // if we're at the end of the array...
 if (index1 >= numReadings1)
 // ...wrap around to the beginning:
 index1 = 0; 

 // subtract the last reading: Zone 3
 total2= total2 - readings2[index2];
 // read from the sensor:
 readings2[index2] = analogRead(sensorPin2);
 // add the reading to the total:
 total2= total2 + readings2[index2];
 // advance to the next position in the array:
 index2 = index2 + 1; 

 // if we're at the end of the array...
 if (index2 >= numReadings2)
 // ...wrap around to the beginning:
 index2 = 0; 

 // calculate the average:
 average0 = total0 / numReadings0;
 // send it to the computer as ASCII digits
 Serial.println(average0);
 delay(1); // delay in between reads for stability 

 // calculate the average:
 average1 = total1 / numReadings1;
 // send it to the computer as ASCII digits
 Serial.println(average1);
 delay(1); // delay in between reads for stability 

 // calculate the average:
 average2 = total2 / numReadings2;
 // send it to the computer as ASCII digits
 Serial.println(average2);
 delay(1); // delay in between reads for stability 

 //getting the voltage reading from the temperature sensor

 // converting that reading to voltage
 float voltage0 = average0 * 5.0;
 voltage0 /= 1024.0; 

 // converting that reading to voltage
 float voltage1 = average1 * 5.0;
 voltage1 /= 1024.0; 

 // converting that reading to voltage
 float voltage2 = average2 * 5.0;
 voltage2 /= 1024.0; 

// Zone 1
 // print out the voltage
 Serial.print(voltage0); Serial.println(" Volts for Zone 1");

 // now print out the temperature
 float temperatureC0 = (voltage0 - 0.5) * 100 ; //converting from 10 mv per degree wit 500 mV offset
 //to degrees ((voltage - 500mV) times 100)
 Serial.print(temperatureC0); Serial.println(" Degrees C for Zone 1");

 // now convert to Fahrenheit
 float temperatureF0 = (temperatureC0 * 9.0 / 5.0) + 32.0;
 Serial.print(temperatureF0); Serial.println(" Degrees F for Zone 1"); 

 // Zone 2
 // print out the voltage
 Serial.print(voltage1); Serial.println(" Volts for Zone 2");

 // now print out the temperature
 float temperatureC1 = (voltage1 - 0.5) * 100 ; //converting from 10 mv per degree wit 500 mV offset
 //to degrees ((voltage - 500mV) times 100)
 Serial.print(temperatureC1); Serial.println(" Degrees C for Zone 2");

 // now convert to Fahrenheit
 float temperatureF1 = (temperatureC1 * 9.0 / 5.0) + 32.0;
 Serial.print(temperatureF1); Serial.println(" Degrees F for Zone 2");

 // Zone 3
 // print out the voltage
 Serial.print(voltage2); Serial.println(" Volts for Zone 3");

 // now print out the temperature
 float temperatureC2 = (voltage2 - 0.5) * 100 ; //converting from 10 mv per degree wit 500 mV offset
 //to degrees ((voltage - 500mV) times 100)
 Serial.print(temperatureC2); Serial.println(" Degrees C for Zone 3");

 // now convert to Fahrenheit
 float temperatureF2 = (temperatureC2 * 9.0 / 5.0) + 32.0;
 Serial.print(temperatureF2); Serial.println(" degrees F for Zone 3");

 unsigned long x;
 unsigned int rpm0;
 //if(pwmVal < 255)
 unsigned long y;
 unsigned int rpm1;
 //if(pwmVal < 255)
 unsigned long z;
 unsigned int rpm2;
 //if(pwmVal < 255)

{

 analogWrite(pwmPin0, pwmVal0);
 pwmVal0 = ((temperatureF0 * 1.2)+98);
 Serial.println("Zone 1 pwm value"); Serial.print(pwmVal0); // Print red value
 Serial.print("\n"); // Print a tab

 analogWrite(pwmPin1, pwmVal1);
 pwmVal1 = ((temperatureF1 * 1.2)+98);
 Serial.println("Zone 2 pwm value"); Serial.print(pwmVal1); // Print red value
 Serial.print("\n"); // Print a tab

 analogWrite(pwmPin2, pwmVal2);
 pwmVal2 = ((temperatureF2 * 1.2)+98);
 Serial.println("Zone 3 pwm value"); Serial.print(pwmVal2); // Print red value
 Serial.print("\n"); // Print a tab
 if (rpm0 > threshold)
 Serial.println("Zone 1 Fan Failure!!!"); // Print red value
 Serial.print("\n"); // Print a tab

}
//else
//{
 // Serial.println("At max Speed"); // Print red value
 // Serial.print("\n"); // Print a tab
//}

 x = pulseIn(2, HIGH);
 x += pulseIn(2, LOW);
 rpm0 = (1000000 * 60) / (x * 2);
 Serial.println("Zone 1 fan RPM");
 Serial.print(" ");
 Serial.println(rpm0);

 y = pulseIn(4, HIGH);
 y += pulseIn(4, LOW);
 rpm1 = (1000000 * 60) / (y * 2);
 Serial.println("Zone 2 fan RPM");
 Serial.print(" ");
 Serial.println(rpm1); 

 z = pulseIn(7, HIGH);
 z += pulseIn(7, LOW);
 rpm2 = (1000000 * 60) / (z * 2);
 Serial.println("Zone 3 fan RPM");
 Serial.print(" ");
 Serial.println(rpm2);
 delay(800);
}

}