Just came to a finish of a code that reads 4 temps, controls 4 fans and reads the 4 fans RPM. Thought I'd put it up before I add other features. It comes in parts cause the code is long.
/* * This code does 3 basic things. * * 1. It reads the temperature from four TMP36 analogue sensors. This reading * compares to the internal 2,56 volt reference and the sensors are fed by an * LP2950 3,3 volt regulator connected to the Arduino Mega 2560's internal 5 * volt. If the TMP36 sensors would measure 125 degrees Celsius they would produce * 1,75 volt on their vout pin but that it theory as I am not planning to * measure higher temperatures then around 60 C which would translate to 1,1 volt. * The analogue pins reads this voltage by getting a value between 0 and 1024. The code * converts this value to degrees Celsius by dividing the reference voltage which I * measuered to 2577 mV with 1024 and then subtracting 500 mV and then divide the * lot with 10. The degrees Celsius I will be able to display on an LCD or whatever. * However I also do a copy of the ADC-pin reading and constrain this value to * inbetween 300 and 450 which represents about 25 to 63 degrees Celsius. This value * I put in a map algorithm that do a linear conversion of the temp value to a value * that I use for setting the fan contol pins duty cycle between 20 and 320. * * 2. It produces a 25 kHz 5 volt p-p squarewave signal on four pins that can be * modulated in duty cycle between 0 and 100%. Those pins controls one 12 volt * PWM fan each. The duty cycle value is set by the map algorithm described above. * I use pin 11 and 12 controlled by timer 1 and 5 and 2 controlled by timer 3 * for this. * * 2. It reads the length of the DC fans built in hall sensor(s) activity. * The readings are in microseconds and with a formula this can be converted * and presented as Revolutions Per Minute (RPM) and/or percentage spinning * of the fans max revolutions per time unit. To avoid to much flickering when * displaying this value it runs to a smoothing algorithm as well that adds the * last four measurements and displays that total value divided by 4. * I tested to use the internal built in 20k pullup resistors but the microamp * current is not enough for stable readings so instead I use external 2,4 k * resistors that gives around 2 mA of current per pin. This current gets shorted * to ground by the fans internal mosfets that takes the reading from high to low * two times per revolution. Noctua recommends up to 5 mA in their specs. * * PS. In my first versions of the code I tried working with arrays as long as * possible but I ran in to problem when trying to attatch the OCR duty cycle * values to the PWM values in an array so I rewrote it all to straight code, * hence the length of it all since I do everything four times in the code. */ const int tmpPin0 = A12; // Temp pin assignments const int tmpPin1 = A13; const int tmpPin2 = A14; const int tmpPin3 = A15; const int pwmPin0 = 11; // PWM pin assignments const int pwmPin1 = 12; const int pwmPin2 = 5; const int pwmPin3 = 2; const int hallSensorPin0 = 13; // Hall sensor pin assignments const int hallSensorPin1 = 9; const int hallSensorPin2 = 22; const int hallSensorPin3 = 23; int tmpReading0; // Variables for the temp int tmpReading1; // sensor Readings int tmpReading2; int tmpReading3; int tmpConstr0; // Variables for the temp int tmpConstr1; // sensor Voltages int tmpConstr2; int tmpConstr3; int tmpDegree0; // Variables for temp int tmpDegree1; // sensor Degrees Celsius int tmpDegree2; int tmpDegree3; int pwm1A = 120; // Variables for the duty int pwm1B = 120; // cycles (0-320 = 0-100%) int pwm3A = 120; // Boot up values 120 int pwm3B = 120; unsigned long highPulseTime0; // Variables for the durations unsigned long highPulseTime1; // of the high pulses unsigned long highPulseTime2; unsigned long highPulseTime3; unsigned long lowPulseTime0; // Variables for the durations unsigned long lowPulseTime1; // of the low pulses unsigned long lowPulseTime2; unsigned long lowPulseTime3; unsigned long newPulseTime0; // Variables for the durations unsigned long newPulseTime1; // of the new pulses, ie high unsigned long newPulseTime2; // plus low pulse unsigned long newPulseTime3; int revsPerMinute0; // Variables for RPM values int revsPerMinute1; // calculated from the pulse times int revsPerMinute2; int revsPerMinute3; int smoothedRevsPerMinute0; // Variables for the int smoothedRevsPerMinute1; // smoothed RPM values int smoothedRevsPerMinute2; int smoothedRevsPerMinute3; int percentage0; // Variables for percentage value int percentage1; // calculated from their RPM values int percentage2; // and their max RPM values int percentage3; const int samples = 4; // No of samples used for smoothing const int maxRevFan0 = 1140; // Constants for each fans maximum const int maxRevFan1 = 1570; // revs per minute const int maxRevFan2 = 2180; const int maxRevFan3 = 1550;