PDA

View Full Version : Computer Fan RPM Sensor Reading



CocaColaKid
- 15th March 2004, 03:22
Has anyone written code to read the RPM from a computer fan. I think they use a hall sensor but I'm not sure.

Dave
- 15th March 2004, 17:24
Yes I have. I wrote a test program to do just exactly that. I will post the basics of it tomorrow.

Dave Purola,

CocaColaKid
- 15th March 2004, 18:37
That would be great Dave. I'm curious as to how you did it. I want to PWM some fans based on temperature but I need to know the RPM so I don't get them down to the stall point.

Dave
- 18th March 2004, 11:53
Coka, Here is a small program I experimented with to do the fan RPM readout. The pulse output from the fan needs to be pulled up to 5 volts. At least on the 5 or so different fans I tryed. Enjoy...

' PROGRAM: FREQTEST.bas
'
' WRITTEN BY DAVID PUROLA 9/18/2003
' WRITTEN FOR PIC18F452-I/L MICROPROCESSOR
' MODIFIED FOR NEW HARDWARE PCB #:211976.REV.1
'
DEFINE OSC 40 'OSCILLATOR = 40 Mhz.
DEFINE LOADER_USED 1 'USE BOOT LOADER
DEFINE NO_CLRWDT 1 'DO NOT INSERT CLRWDT's
DEFINE BUTTON_PAUSE 20 '20 Ms. DELAY FOR BUTTON USE
DEFINE LCD_DREG PORTD 'LCD DATA BUS ON PORT D
DEFINE LCD_DBIT 4 'LCD DATA BUS ON PORTD.7:4
DEFINE LCD_RSREG PORTD 'R/S REGISTER ON PORT D
DEFINE LCD_RSBIT 2 'R/S ON PORTD.2
DEFINE LCD_EREG PORTD 'E-CLOCK ON PORT D
DEFINE LCD_EBIT 3 'E-CLOCK ON PORTD.3
DEFINE LCD_BITS 4 'DATA BUS ONLY 4 BITS
DEFINE LCD_LINES 2 'LCD DISPLAY LINES

' ************************************************** ******************
' Declare Port Variables
' ************************************************** ******************
' VAR PORTA.0 '1-ANALOG INPUT #0
' VAR PORTA.1 '1-ANALOG INPUT #1
' VAR PORTA.2 '1-ANALOG INPUT #2
' VAR PORTA.3 '1-ANALOG INPUT #3
WATCH_DOG VAR PORTA.4 '0-RUN LED & WATCH DOG TOGGLE INPUT TO ADM690LAN
' VAR PORTA.5 '1-ANALOG INPUT #4
BUSBAT VAR PORTB.0 '1-VDD OUTPUT FROM MCP-201
BUSFALT VAR PORTB.1 '1-~FAULT OUTPUT FROM MCP-201
' VAR PORTB.2 '1-SPARE TO PIN 2 J-9
' VAR PORTB.3 '1-SPARE TO PIN 4 J-9
CS_WAKE VAR PORTB.4 '0-CHIP SELECT/WAKE TO MCP-201
' VAR PORTB.5 '1-SPARE TO PIN 6 J-9
RX2 VAR PORTB.6 '1--SECONDARY RS-232 RECEIVE LINE
TX2 VAR PORTB.7 '0-SECONDARY RS-232 TRANSMIT LINE
UCN_STB VAR PORTC.0 '0-UCN5832A DATA STROBE
CCP2 VAR PORTC.1 '0-J-12 PIN 2 CCP2/PWM
CCP1 VAR PORTC.2 '0-J-12 PIN 1 CCP1/PWM
SCL VAR PORTC.3 '1-SCL-I2C (24LC128)
SDA VAR PORTC.4 '0-SDA-I2C (24LC128)
BUTT0 VAR PORTC.5 '1-ROTARY ENCODER BUTTON
TX1 VAR PORTC.6 '0-PRIMARY RS-232 TRANSMIT LINE
RX1 VAR PORTC.7 '1-PRIMARY RS-232 RECEIVE LINE
A_IN VAR PORTD.0 '1-ROTARY ENCODER CHANNEL-A
B_IN VAR PORTD.1 '1-ROTARY ENCODER CHANNEL-B
REGSEL VAR PORTD.2 '0-REGISTER SELECT TO DISPLAY
ECLK VAR PORTD.3 '0-"E" CLOCK TO DISPLAY
DB4 VAR PORTD.4 '0-DATA BIT 4 TO DISPLAY
DB5 VAR PORTD.5 '0-DATA BIT 5 TO DISPLAY
DB6 VAR PORTD.6 '0-DATA BIT 6 TO DISPLAY
DB7 VAR PORTD.7 '0-DATA BIT 7 TO DISPLAY
CLOCK VAR PORTE.0 '0-CLOCK FOR DATA INPUT & OUTPUT TO 4014 & UCN5832A
P_S_DATA VAR PORTE.1 '0-P/S INPUT TO 4014 & DATA INPUT TO UCN5832A
DAT_IN VAR PORTE.2 '1-DATA INPUT FROM 4014

' ************************************************** ******************
' Define Program Constants
' ************************************************** ******************
PULSE CON 5 'PULSE FOR STROBING LATCHES ~10uS.
PARITY CON 8192 'PARITY EQUIV.
INVERT CON 16384 'INVERT EQUIV.
MSBFIRST CON 1 'ELIMINATE USING "MODEDEFS.BAS"
MSBPRE CON 0 '""
LSBPRE CON 1 '""
MSBPOST CON 2 '""
LSBPOST CON 3 '""
BAUD CON 32 'BAUD RATE (19200) FOR EXTERNAL USE
ADSTOR CON $F0 'A/D CALIBRATION STORAGE STARTING LOCATION (16 BYTES)
MESSTABLE CON $7000 'MESSAGE LOOKUP TABLE ADDRESS IN PROGRAM FLASH MEMORY

' ************************************************** ******************
' Declare Variables
' ************************************************** ******************
POINTER1 VAR WORD '""
POINTER2 VAR WORD '""
POINT2LO VAR POINTER2.LOWBYTE
POINT2HI VAR POINTER2.HIGHBYTE

' ************************************************** ******************
' DO NOT CHANGE THESE LINES
' ************************************************** ******************
TRISA = %101111 'INITIALIZE PORT DIRECTIONS
TRISB = %01101111
TRISC = %10101100
TRISD = %00000011
TRISE = %00000100

OSCCON = 0 'SET SYSTEM CLOCK SWITCH BIT
RCON = %00011111 'CLEAR IPEN,RI,TO,PD,POR,BOR
INTCON2 = %11000000 'NO PULL-UPS,INTEDG0 RISING,INTEDG1,INTEDG2,TMR01P,RBIP
INTCON3 = %00000000 'CLEAR INT2IP,INT1IP,INT2IE,INT1IE,INT2IF,INT1IF
PIE1 = %00000000 'CLEAR ALL INTERRUPT ENABLE BITS
PIE2 = %00000000 'CLEAR ALL INTERRUPT ENABLE BITS
IPR1 = %00000000 'SET ALL INTERRUPT PRIORITY BITS TO LOW
IPR2 = %00000000 'SET ALL INTERRUPT PRIORITY BITS TO LOW
PIR1 = %00000000 'CLEAR ALL INTERRUPT FLAGS
PIR2 = %00000000 'CLEAR ALL INTERRUPT FLAGS
ADCON0 = %10000001 'FOSC/64,AN0,A/DONE,A/D OFF
ADCON1 = %11000010 'RIGHT JUST,A/D CLOCK SELECT,RA0:RA3,RA5 ANALOG PINS, RE0:RE2 DIGITAL PINS
LVDCON = %00001111 'CLEAR IRVST,LVDEN,AND SELECT LVDIN
WDTCON = %00000000 'DISABLE WATCH DOG TIMER
T0CON = %00000000 'PRESCALER,WRITE PRESCALER 1/2, TURN OFF TIMER 0
T1CON = %10000100 'WRITE PRESCALER 1/1, TURN OFF TIMER 1
T2CON = %00000100 'WRITE PRESCALER 1/1, TURN ON TIMER 2
T3CON = %10000100 'WRITE PRESCALER 1/1, TURN OFF TIMER 3

GOTO COLD

'************************************************* ********************
'------------ INITIALIZATION OF HARDWARE AFTER RESET -----------------
'************************************************* ********************
COLD:
CLEAR
TX1 = 1 'INITIALIZE SERIAL DATA TRANSMIT LINE (1ST)
TX2 = 1 'INITIALIZE SERIAL DATA TRANSMIT LINE (2ND)
REGSEL = 0 'SEY REGISTER SELECT FOR DISPLAY LOW
ECLK = 0 'INITIALIZE E-CLOCK TO DISPLAY
UCN_STB = 0 'INITIALIZE UCN5832A DATA STROBE LINE
P_S_DATA = 0 'SET PARALLEL/SERIAL SELECT LINE TO 4014B
CLOCK = 0 'INITIALIZE DATA CLOCK TO 4014B's & UCN5832A

ASM
PutMulResult macro Const32
MOVE?CB low Const32, R2
MOVE?CB low (Const32 >> 8), R2 + 1
MOVE?CB low (Const32 >> 16), R0
MOVE?CB low (Const32 >> 24), R0 + 1
endm
ENDASM

'************************************************* ********************
'MAIN LOOP FOR PROGRAM
'************************************************* ********************
LOOP:
INTERRUPTBIT = INTCON.7 'SAVE STATUS OF INTERRUPT ENABLE BIT
INTCON.7 = 0 'DISABLE ALL INTERRUPTS
PULSIN CCP1,1,POINTER1 'MEASURE HIGH PULSE
INTCON.7 = INTERRUPTBIT 'RE-ENABLE ALL INTERRUPTS
IF POINTER1 > 0 THEN
@ PutMulResult 15000000 ' Load PBP internal vars Max= 2,147,483,648
POINTER2 = DIV32 POINTER1 ' Divide 15000000/(PERIOD/2)
ELSE
POINTER2 = 0
ENDIF
LCDOUT $FE,$80,DEC5 POINTER2
GOTO LOOP 'DO IT AGAIN and AGAIN and AGAIN

END

markspend01
- 17th August 2013, 16:58
Hey Guys well i think that nice info about computer fan Rpm sensor.Thanks!!

CuriousOne
- 26th December 2019, 16:43
I'd like to control rotation of PC fan (whenever it is rotating or not), but do not want to constantly call PULSIN. Is there some way of timer/interrupt combo, to do this in background?

CuriousOne
- 27th December 2019, 20:55
Found a special chip from Microchip for exactly that task - TC670: http://www.farnell.com/datasheets/87877.pdf

CuriousOne
- 27th December 2019, 21:05
Maxim also has almost similar chip - MAX6684, which is a bit expensive, but much simpler to use and no programming required.