This was written in about 5 minutes to test 12V DC fans noise and airflow characteristics before installing them in a PC. The code will run on any of the current generation PICAXE chips at their native frequency (i.e. not overclocked via the setfreq command or poking registers). The pins used need to be modified to suit the selected chip.
speedup, slowdown and power are all input pins interfacing to switches. The PICAXE-08M was used for this so the pwm pin is pin 2 (hardware limitation). PWM frequency is set to 25kHz, above the human hearing range to avoid audible whining due to magneto-restriction, and a reasonable compromise on efficiency. Duty cycle is set as an integer between 0 and 160 i.e. 50% = 80, 75% = 120, 100% = 160. Pauses are used as a rudimentary method to debounce the input switches – 200ms was adequate for the tactile switches I had on hand, though some momentary push-buttons may need longer. You may wish to set the minimum value to something other than 0, eg 32 (20% duty cycle) so that fans never turn completely off, or to prevent stalling at low speeds.
Input switches need to be connected via a 10k resistor to ground and a 1k resistor in series with the input pin. The fan can be driven via a NPN transistor and a 1k resistor in series with the transistor base. RevEd recommends you use a darlington transistor, although a BD139 NPN transistor worked just fine for me and only became lukewarm in operation with a fan rated at 200mA current. Ensure you use a diode (1N4004 or similar) across the fan to suppress back emf. I had two power supplies on hand so ran the PICAXE-08M from 5V and the fan off 12V directly. See the PICAXE Interfacing Circuits (#3) manual for more information on wiring up external input/output devices.
symbol speedup = Pin4 'Input switch symbol slowdown = Pin3 'Input switch symbol power = Pin1 'Input switch symbol dutycycle = b0 symbol state = b1 dutycycle = 160 'Initialise to 100% duty cycle init: pwmout 2, 39, 160 'Run motor at full speed for 4 secs at power-on to start reliably pause 4000 main: If speedup = 1 Then Faster 'If switch pressed, increase speed If slowdown = 1 Then Slower 'If switch pressed, decrease speed If power = 1 Then Mode 'Toggle motor on/off if switch pressed goto main Faster: 'Increase duty cyce by 5% If dutycycle = 160 Then main 'Do nothing if already at max dutycycle = dutycycle + 8 pwmout 2, 39, dutycycle pause 200 'Switch debounce goto main Slower: 'Decrease duty cycle by 5% If dutycycle = 0 Then main 'Do nothing if already at min. Change 0 to a higher value eg 15 'to set a minimum speed. dutycycle = dutycycle - 8 pwmout 2, 39, dutycycle pause 200 'Switch debounce goto main Mode: 'If on, switch off. If off, switch on etc. If state = 0 Then state = 1 pwmout 2, 39, 160 dutycycle = 160 pause 200 'Switch debounce ElseIf state = 1 Then state = 0 pwmout 2, OFF pause 200 'Switch debounce EndIf goto main