Results 1 to 10 of 10

Thread: Arduino Tutorial: Reading PC Fan RPM.

  1. #1
    If you can't hack it, you don't own it! Oneslowz28's Avatar
    Join Date
    Mar 2007
    Location
    Aiken, Sc
    Posts
    5,084

    Default Arduino Tutorial: Reading PC Fan RPM.

    By Charles Gantt ( Oneslowz28 )

    Part 1: Outputting Fan RPM to the serial console


    What you will need:




    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 Arduino, and then open the serial terminal. Again I would like to thank Crenn for his help with the code.

    Code:
    //code by Crenn from http://thebestcasescenario.com
    //project by Charles Gantt from http://themakersworkbench.com
    
    
    /*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;
    }fanspec;
    
    //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 
    { 
     NbTopsFan++; 
    } 
    
                  //This is the setup function where the serial port is initialised,
                 //and the interrupt is attached
    void setup() 
    { 
     pinMode(hallsensor, INPUT); 
     Serial.begin(9600); 
     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. Check IGA Catalogue and ALDI Catalogue.

    My fritzing page on this project. (Download all the files there)
    Reading PC Fan / Water Pump RPM with an Arduino
    Last edited by DaveW; 11-21-2020 at 07:53 PM.

  2. #2
    If you can't hack it, you don't own it! Oneslowz28's Avatar
    Join Date
    Mar 2007
    Location
    Aiken, Sc
    Posts
    5,084

    Default Re: Arduino Tutorial: Reading PC Fan RPM.

    Reserved for part 2

  3. #3
    Project: Elegant-Li The boy 4rm oz's Avatar
    Join Date
    Mar 2006
    Location
    Balhannah, South Australia
    Posts
    6,411

    Default Re: Arduino Tutorial: Reading PC Fan RPM.

    Nice tutorial. I think I will be giving this a miss though, reminds me too much of java, I hate java.
    Project: Elegant-Li *NEW*
    Project: Alpha FINISHED
    Project: LEXA Revival FINISHED
    Project: LEXA FINISHED Bit-Tech MOTM Nominee October 08

  4. #4
    If you can't hack it, you don't own it! Oneslowz28's Avatar
    Join Date
    Mar 2007
    Location
    Aiken, Sc
    Posts
    5,084

    Default Re: Arduino Tutorial: Reading PC Fan RPM.

    Its pretty easy after an hour or two of playing around with the code.

  5. #5
    Resident 100HP water-cannon operator SXRguyinMA's Avatar
    Join Date
    Jun 2008
    Location
    MA
    Posts
    5,865

    Default Re: Arduino Tutorial: Reading PC Fan RPM.

    yes, I've never coded anything except basic html 8-10 years ago, and I got the hang of it rather quickly

  6. #6
    Resident 100HP water-cannon operator SXRguyinMA's Avatar
    Join Date
    Jun 2008
    Location
    MA
    Posts
    5,865

    Default Re: Arduino Tutorial: Reading PC Fan RPM.

    alright I adapted this code to work with an LCD and will add a second fan in the future. the problem I have is when the RPM drops below 1000. the readout keeps the characters to the left rather than the right. so 600rpm should be displayed "600" or even "0600" but rather is displayed "6000". and idea how to fix this? here's the code:

    Code:
    //code by Crenn from http://thebestcasescenario.com
    //project by Charles Gantt from http://themakersworkbench.com
    
    #include <LiquidCrystal.h>
    
    LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
    
    /*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;
    }fanspec;
    
    //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 
    { 
     NbTopsFan++; 
    } 
                                       //This is the setup function where the LCD is initialised,
                                       //and the interrupt is attached
    void setup() 
    { 
      pinMode(hallsensor, INPUT);      //Sets RPM pin to input
      lcd.begin(16, 2);                     //Set up the LCD's number of rows and columns
      lcd.print("  diluzio91's  ");        //First line opening message
      lcd.setCursor(0, 1);
      lcd.print("Fan Control Cntr");   //Second line opening message
      delay(5000);                        //Delay for opening message
      lcd.setCursor(0, 1);               //Clear bottom line
      lcd.print("                ");
      lcd.setCursor(0, 0);
      lcd.print(" Fan 1    Fan 2  ");  //Update top line readout
      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
       lcd.setCursor(0, 1);
       lcd.print (Calc, DEC); //Prints the number calculated above
       lcd.setCursor(4, 1);
       lcd.print ("RPM");      //Prints " RPM"
    }
    Also, how would I go about adding in a second fan to this setup? And the reading seems to fluctuate a lot. at a steady rpm, it bounces between 1500rpm and 1200

    and the setup:

  7. #7
    rawrnomnom diluzio91's Avatar
    Join Date
    Jan 2010
    Posts
    2,471

    Default Re: Arduino Tutorial: Reading PC Fan RPM.

    i dont know about adding a 2nd fan, but the reading fluctuation dosn't surprise me, my scythe would bounce around a bunch on some fans, almost not at all on others, try a couple different fans and see what you get?
    Not dead yet

  8. #8
    Resident 100HP water-cannon operator SXRguyinMA's Avatar
    Join Date
    Jun 2008
    Location
    MA
    Posts
    5,865

    Default Re: Arduino Tutorial: Reading PC Fan RPM.

    you only need one fan? well then that's easy lol

    I changed the connection point for the RPM pickup and it dropped to a ~150rpm fluctuation

  9. #9
    Fresh Paint
    Join Date
    Jan 2011
    Posts
    3

    Default Re: Arduino Tutorial: Reading PC Fan RPM.

    Setting the PORTx bit associated with the input line should provide a 20k pull-up to +5v inside the processor (see 13.2.1 of the data sheet) and http://www.arduino.cc/en/Tutorial/DigitalPins talks about this too. So maybe the resistor isn't necessary.

    The Intel 4-pin fan spec at http://www.formfactors.org/developer...e_PWM_Spec.pdf describes the RPM sense line as open-collector/open-drain and pulled up to +12v on the motherboard. I haven't had any problems with your +5v 10kohm pull-up with the couple of 3-pin fans I've tried, so I'm not sure +12v is necessary (there'd be a voltage divider to get down to 5v.)

    If I did want to go to higher voltage pullups, one thing I haven't figured out is what to do when running the fan at a voltage below 12v. Somehow it seems wrong to put any voltage above Vmotor (or whatever the red wire is called) My Vmotor outputs aren't very clean and given how they vary, pulling up to Vmotor just seems like it shouldn't work for me either. So I don't know, and I'm sticking with +5v for now. I could always chicken out and go to an optoisolator for the tach.

  10. #10

    Default Re: Arduino Tutorial: Reading PC Fan RPM.

    Quote Originally Posted by Oneslowz28 View Post

    //The pin location of the sensor
    int hallsensor = 2;
    The interrupt pin depends upon the arduino board Using

    Uno, Nano, Mini, other 328-based 2, 3
    Mega, Mega2560, MegaADK 2, 3, 18, 19, 20, 21
    Micro, Leonardo, other 32u4-based 0, 1, 2, 3, 7
    Zero all digital pins, except 4
    MKR1000 Rev.1 0, 1, 4, 5, 6, 7, 8, 9, A1, A2
    Due all digital pins
    101 all digital pins
    Quote Originally Posted by Oneslowz28 View Post
    void setup()
    {
    pinMode(hallsensor, INPUT);
    Serial.begin(9600);
    attachInterrupt(0, rpm, RISING);
    }
    attachInterrupt(0, rpm, RISING); this will not work according to the syntax . Correct one should be attachInterrupt(digitalPinToInterrupt(pin), rpm, RISING); - (pin) is hall sensor pin for example 2

    attachInterrupt(digitalPinToInterrupt(pin), ISR, mode); (recommended)
    attachInterrupt(interrupt, ISR, mode); (not recommended)
    attachInterrupt(pin, ISR, mode) ; (not recommended Arduino Due, Zero, MKR1000, 101 only)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •