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.
Powered by vBulletin® Version 4.1.7 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.