Deep_Sky
Published

PC Chassis Fans

Manual and temperature controlled PC chassis fans.

IntermediateWork in progress2,183
PC Chassis Fans

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
×1
Rotary Encoder with Push-Button
Rotary Encoder with Push-Button
×1
Standard LCD - 16x2 White on Blue
Adafruit Standard LCD - 16x2 White on Blue
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

Schematic

Schematic connection

Code

PC_Chasis_Fan.ino

Arduino
PC Chassis Fans
#include <Adafruit_PWMServoDriver.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
//#include "writeAnything.h"

/*
-VCC-5V
  |
 NTC - Vout
  |
  R(fixed)
  |
 GND
 ----Scaling Formula----
Reference Point        ADC Reading      
   ===========          ==========
      x1(min)             a1(min)
      x2(max)             a2(max)
      
 X - x1          A - a1
---------  =  -----------
x2 - x1          a2 - a1

==>  X = (x2 - x1)*(A - a1)/(a2 - a1) + x1

temp = ((110 - 0)*(average_sensor - 498))/191;
*/
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
#define ledPin 13
LiquidCrystal_I2C lcd(0x3C,16,2);  //sometimes the adress is not 0x3f. Change to 0x27 if it dosn't work.//0x3C is that A0 and A1 are shorted

short ThermistorPin = 0;// Analog input pin for thermistor voltage
short Temp_Pot = 1; //Temperature Potentiometer PIN

boolean f_encoder_a;
boolean f_encoder_b;
boolean r_encoder_a;
boolean r_encoder_b;
boolean f_encoder_sw;
boolean r_encoder_sw;
uint8_t f_pwmnum= 0;
uint8_t r_pwmnum= 1;

boolean switch_temp;
int Vo;// Integer value of voltage reading
float R = 9870.0;// Fixed resistance in the voltage divider
float logRt,Rt,T;
float c1 = 2.108508173e-03, c2 = 0.7979204727e-04, c3 = 6.535076315e-07;//Water Sersor R=10kOhm-25 degree Celcius.   B=3435
int pot_raw;
float pot_map;

boolean f_encoder_a_prev;
boolean r_encoder_a_prev;
boolean f_encoder_sw_prev;
boolean r_encoder_sw_prev;
boolean f_fan_raw;
boolean r_fan_raw;
boolean trig_a;
boolean trig_b;

unsigned int f_counter;
unsigned int r_counter;
unsigned int f_counter_temp;
unsigned int r_counter_temp;
unsigned int amount[3];
unsigned short f_rpm_amount;
unsigned short r_rpm_amount;
unsigned short f_encoder_sw_counter;
unsigned short r_encoder_sw_counter;
unsigned short f_counter_th;
unsigned short f_counter_hu;
unsigned short f_counter_te;
unsigned short f_counter_de;
unsigned short f_counter_12;
unsigned short f_counter_34;
int f_c;
int r_c;
//RPMreading//
int f_frequency;
int r_frequency;
int f_freq_counter;
int r_freq_counter;

unsigned long currentMicros;
unsigned long previousMicros = 0;
const long interval = 1000000;
void setup() {
  pwm.begin();
  pwm.setPWMFreq(1600);  // This is the maximum PWM frequency
    Wire.setClock(300000); //I2C clock frequency 300kHz
  Serial.begin(9600);
    f_counter = EEPROM_int_read(0);
    r_counter = EEPROM_int_read2(10);
  lcd.init(); // Initializing LCD  
  lcd.begin(16, 2);
  lcd.backlight(); //lcd backlight o


  pinMode(2, INPUT);
  pinMode(3, INPUT);
  pinMode(4, INPUT);
  pinMode(5, INPUT);
  pinMode(6, INPUT);
  pinMode(7, INPUT); //Front Fan RPM input
  pinMode(8, INPUT); //Rear Fan RPM input
  pinMode(11, INPUT); //Front Encoder Switch
  pinMode(12, INPUT); //Rear Encoder Switch
  amount[0] = 1;
  amount[1] = 10;
  amount[2] = 100;

}

void loop() {
  temp_reading();
  rpm_reading();
  switch_temp = digitalRead(2);
  f_encoder_a = digitalRead(3);
  f_encoder_b = digitalRead(4);
  r_encoder_a = digitalRead(5);
  r_encoder_b = digitalRead(6);
  f_encoder_sw = digitalRead(11);
  r_encoder_sw = digitalRead(12);
  encoder_switch();
  encoder_reading();
  pwm_out();
  /*
  Serial.print(f_counter);
  Serial.print(" ");
  Serial.print(f_frequency_out);
  Serial.println();
  */
}

void temp_reading()
{
  Vo = analogRead(ThermistorPin);
  Rt = R*( (1023.0 / (float)Vo) - 1.0 );
  logRt = log(Rt);
  T = ( 1.0 / (c1 + c2*logRt + c3*logRt*logRt*logRt ) ) - 273.15;

  pot_raw = analogRead(Temp_Pot);
  pot_map = ((40.0 - 20.0)*(float(pot_raw) - 0.0))/(1023.0 - 0.0)+20.0;

  if(f_counter_temp<4096)
  {
   f_counter_temp = sqrt((T-pot_map))*550+500;
   r_counter_temp = sqrt((T-pot_map))*550+250;//Rear RPM less than Front
  }
} //end temp_reading
/***************************************************************************************/
void rpm_reading()
{
      //FRONT FAN RPM//
  f_fan_raw = digitalRead(7);
  if(f_fan_raw==false&&trig_a==false)
  {
    f_freq_counter++;
    trig_a = true;
  }
  if(f_fan_raw==true&&trig_a==true)
  {
    trig_a = false;
  }
     //REAR FAN RPM//
   r_fan_raw = digitalRead(8);  
     if(r_fan_raw==false&&trig_b==false)
  {
    r_freq_counter++;
    trig_b = true;
  }
  if(r_fan_raw==true&&trig_b==true)
  {
    trig_b = false;
  }
  currentMicros = micros();
  if(currentMicros<previousMicros){previousMicros = currentMicros;}
  if(currentMicros-previousMicros>=interval)
{
  f_frequency = f_freq_counter * 60;
  f_frequency=f_frequency/2;
  r_frequency = r_freq_counter * 60;
  r_frequency=r_frequency/2;
  
    Serial.print(f_counter);
  Serial.print(" ");
  Serial.print(f_frequency);
  Serial.println();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(f_counter);
  lcd.setCursor(0, 1);
  lcd.print(f_frequency);

  lcd.setCursor(5, 0);
  lcd.print(r_counter);
  lcd.setCursor(5, 1);
  lcd.print(r_frequency);
  lcd.setCursor(10, 0);
  lcd.print(T);
  lcd.setCursor(15, 0);
  lcd.print("C");
  lcd.setCursor(10, 1);
  lcd.print("S:");
  lcd.setCursor(12, 1);
  lcd.print(pot_map);
  f_freq_counter = 0;
  r_freq_counter = 0;
  previousMicros = currentMicros;
}
}//end rpm_reading
void encoder_switch()
{
                   //FRONT//
  if(f_encoder_sw==false){f_encoder_sw_prev = f_encoder_sw;}
  if(f_encoder_sw==true&&f_encoder_sw_prev==false)
  {
    f_encoder_sw_counter++;
    if(f_encoder_sw_counter>2){f_encoder_sw_counter = 0;}
    f_encoder_sw_prev = f_encoder_sw;
  }
  switch (f_encoder_sw_counter)
  {
    case 0:
          f_rpm_amount = amount[0];
    break;
    case 1:
          f_rpm_amount = amount[1];
    break;
    case 2:
         f_rpm_amount = amount[2];
    break;
  }
                     //REAR//
  if(r_encoder_sw==false){r_encoder_sw_prev = r_encoder_sw;}
  if(r_encoder_sw==true&&r_encoder_sw_prev==false)
  {
    r_encoder_sw_counter++;
    if(r_encoder_sw_counter>2){r_encoder_sw_counter = 0;}
    r_encoder_sw_prev = r_encoder_sw;
  }
  switch (r_encoder_sw_counter)
  {
    case 0:
          r_rpm_amount = amount[0];
    break;
    case 1:
          r_rpm_amount = amount[1];
    break;
    case 2:
         r_rpm_amount = amount[2];
    break;
  }
}//end encoder_switch
/***************************************************************************/

// reading FRONT Fan conrolling value to EEPROM using 2bytes
int EEPROM_int_read(int addr) {    
  byte raw[2];
  for(byte i = 0; i < 2; i++) raw[i] = EEPROM.read(addr+i);
  int &f_c = (int&)raw;
  return f_c;
}

// writing FRONT Fan conrolling value to EEPROM using 2bytes
void EEPROM_int_write(int addr, int f_c) {
  if (EEPROM_int_read(addr)!= f_c){//  
    byte raw[2];
    (int&)raw = f_c;
    for(byte i = 0; i < 2; i++) EEPROM.write(addr+i, raw[i]);
  }
}
// reading REAR Fan conrolling value to EEPROM using 2bytes
int EEPROM_int_read2(int addr) {    
  byte raw[2];
  for(byte i = 0; i < 2; i++) raw[i] = EEPROM.read(addr+i);
  int &num = (int&)raw;
  return num;
}

// writing REAR Fan conrolling value to EEPROM using 2bytes
void EEPROM_int_write2(int addr, int num) {
  if (EEPROM_int_read2(addr)!= num){//  
    byte raw[2];
    (int&)raw = num;
    for(byte i = 0; i < 2; i++) EEPROM.write(addr+i, raw[i]);
  }
}

void encoder_reading()
{
            //FRONT//
 if(f_encoder_a != f_encoder_a_prev) //Increasing
 {
      if(f_encoder_b != f_encoder_a) 
      {
        if(f_encoder_a_prev==true)
         {
          if((f_counter+f_rpm_amount)<4096)
           {
            f_counter = f_counter + f_rpm_amount;
            EEPROM_int_write(0, f_counter);
           }
         }
        f_encoder_a_prev = f_encoder_a;
      }   
      else                        //Decreasing
      {
        if(f_encoder_a_prev==true)
          {
           if(f_counter>200)
           {
            f_counter = f_counter - f_rpm_amount;
            EEPROM_int_write(0, f_counter);
           }
          }     
        f_encoder_a_prev = f_encoder_a;      
      }   

  }
             //REAR//
  if(r_encoder_a != r_encoder_a_prev) //Increasing
 {
      if(r_encoder_b != r_encoder_a) 
      {
        if(r_encoder_a_prev==true)
         {
          if((r_counter+r_rpm_amount)<4096)
           {
            r_counter = r_counter + r_rpm_amount;
            EEPROM_int_write2(10, r_counter);
           }
         }
        r_encoder_a_prev = r_encoder_a;
      }   
      else                           //Decreasing
      {
        if(r_encoder_a_prev==true)
          {
           if(r_counter>200)
           {
            r_counter = r_counter - r_rpm_amount;
            EEPROM_int_write2(10, r_counter);
           }
          }     
        r_encoder_a_prev = r_encoder_a;      
      }   
         
  }
    
}//end encoder_reading

void pwm_out()
{
      if(switch_temp==true)
      {
       pwm.setPWM(f_pwmnum, 0, f_counter % 4096 );
       pwm.setPWM(r_pwmnum, 0, r_counter % 4096 );
      }else
      {
       pwm.setPWM(f_pwmnum, 0, f_counter_temp % 4096 );
       pwm.setPWM(r_pwmnum, 0, r_counter_temp % 4096 );
      }
}

Credits

Deep_Sky

Deep_Sky

1 project • 17 followers

Comments