Has anyone written code to read the RPM from a computer fan. I think they use a hall sensor but I'm not sure.
Has anyone written code to read the RPM from a computer fan. I think they use a hall sensor but I'm not sure.
Yes I have. I wrote a test program to do just exactly that. I will post the basics of it tomorrow.
Dave Purola,
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.
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
Hey Guys well i think that nice info about computer fan Rpm sensor.Thanks!!
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?
Found a special chip from Microchip for exactly that task - TC670: http://www.farnell.com/datasheets/87877.pdf
Maxim also has almost similar chip - MAX6684, which is a bit expensive, but much simpler to use and no programming required.
Bookmarks