Netduino home hardware projects downloads community

Jump to content

The Netduino forums have been replaced by new forums at This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.

Controlling 4-Wire PWM Fan

  • Please log in to reply
2 replies to this topic

#1 MattEric


    New Member

  • Members
  • Pip
  • 7 posts

Posted 14 February 2011 - 03:41 AM

Anybody have any experience controlling a 4-wire fan with built in PWM? I bought such a fan thinking that distributing the PWM to the fan might be smart rather than using the Netduino's PWM capability but now i'm stumped about what signals are required to talk to the fan. Any documentation i've been able to find involves a programmable pwm controller which also monitors temp sensors, and i really don't want all that as i plan to be monitoring temp sensors separately and wish to implement my own control logic. Is there a way to control the PWM Fan directly w/o a controller? I think i can read japanese better than a data sheet, but attached is the sheet for the fan i bought complete with minimal and cryptic information, notably on pages 7 & 8. Matt

Attached Files

#2 Chris Seto

Chris Seto

    Advanced Member

  • Members
  • PipPipPip
  • 405 posts

Posted 16 February 2011 - 07:07 PM

I didn't read the datasheet complelty, but my guess is that 1 pin is power (+12V) on pin is GND, one pin is TACH, and the last pin is the PWM pin, which goes to a transistor which allows/cuts power to the fan. Basically, I'll bet you can leave TACH floating (unless that's the process variable in your loop), GNd -> GND, +12 or whatever to +12, and then hook the Netduino's PWM pin to PWM on the fan.

#3 MattEric


    New Member

  • Members
  • Pip
  • 7 posts

Posted 03 March 2011 - 06:39 AM

Yep, i just hooked up the wires and it worked. I had a misunderstanding of what a PWM fan is, thinking that it had some sort of controller built in that provided the duty cycle given the right incantations, but it just is "PWM enabled" where it has some sort of FET or solid state relay that allows a PWM signal to control the fan. Which the Netduino PWM does. I first used SetDutyCycle() but the specs of the fan i have say the PWM data signal operates best at 25kHz, so i set the frequency using SetPulse(). As Philip pointed out here http://forums.netdui...pwm-demystified, I discovered that SetDutyCycle() only seems to work properly at the default 10kHz frequency, so i ended up using SetPulse() to set the duty cycle as well. The code i am using follows which is basically my customized version Dab's posting controlling an LED with Netduino's PWM http://forums.netdui.../103-pwmsample/.

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;
using PWMDevice;

namespace BlowerPWM {

    public class Program {

        // Constants
        const int cTimerPeriod = 150;       // milliseconds
        const short cInitialDutyCycle = 20; // 20% is minimum duty cycle guaranteed to start blower
        const short cDutyCycleDelta = +1;   // begin by increasing duty cycle by one
        const int ckHz = 25;                // blower spec says pwm control data is best run at 25kHz 

        public static void Main() {
            // Create a blower control object 
            PWMDeviceControl blowerControl = new PWMDeviceControl(cInitialDutyCycle, cDutyCycleDelta, ckHz);
            // Create a System.Threading.Timer instance and pass it the timer callback method
            Timer timer = new Timer(new TimerCallback(blowerControl.AdjustDutyCycle),
                                    null,                   // data object (not used)
                                    cTimerPeriod,           // time to first call back
                                    cTimerPeriod);          // time period between call backs


using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;

namespace PWMDevice {
    /* This class defines a basic controller for a PWM device that combines a Netduino PWM and a button 
     * for the user to adjust the duty cycle.  The duty cycle will increase by a constant amount as the 
     * user presses the button.  When the max duty cycle percentage is reached, continued pressing 
     * decrements the duty cycle until the minimum is reached when the direction of change is reversed again. */
    class PWMDeviceControl {
        const short cMaxDutyCycle = 100;    // percentage
        const short cMinDutyCycle = 7;      // percentage; blower stops below 8%
        private short dutyCycle;            // percentage
        private short dutyCycleDelta;       // amount to change the duty cyclc; can be + or - value
        private PWM pwm;                    // Netduino's PWM 
        private Button button;              // UI for control of duty cycle
        private uint period;                // period of PWM in microseconds
        private uint kHz;                   // frequency of PWM in kHz

        // Constructor
        public PWMDeviceControl(short initialDutyCycle, short initialDutyCycleDelta, uint kHz) {
            dutyCycle = initialDutyCycle;
            dutyCycleDelta = initialDutyCycleDelta;
            this.kHz = kHz;
            pwm = new PWM(Pins.GPIO_PIN_D5);    // Netduino's PWM; Pin 5 is PWM enabled
            button = new Button();              // button for user control of duty cycle  
            period = 1000 / kHz;    // set period to match requested frequency 
            pwm.SetPulse(period, (uint)(initialDutyCycle * 10 / kHz));      // set duration to match intial duty cycle
            //pwm.SetDutyCycle((uint)dutyCycle);  // can't seem to use this when using SetPulse()
            Debug.Print("Initial duty cycle: " + dutyCycle.ToString());
        /* This public method is called back by a timer or other event. If the user is pressing 
         * the button, it increments or decrements the duty cycle by the amount dutyCycleDelta 
         * as well as changes the direction of inc/dec when the max or min duty cycle is reached.*/
        public void AdjustDutyCycle(Object obj) {
            if (button.Pressed) {
                dutyCycle += dutyCycleDelta;        // increment/decrement the duty cycle
                pwm.SetPulse(period, (uint)(dutyCycle * 10 / kHz));
                //pwm.SetDutyCycle((uint)dutyCycle);  // can't use this when using SetPulse()
                Debug.Print("Duty cycle: " + dutyCycle.ToString());

                // check if at min or max duty cycle and change direction if so
                if (dutyCycle >= cMaxDutyCycle || dutyCycle <= cMinDutyCycle) 
                    dutyCycleDelta = (short)-dutyCycleDelta;

using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;

namespace PWMDevice  {
    class Button {
        public bool Pressed {get; private set;}
        private InterruptPort port;
        // Constructor
        public Button() { 
            Pressed = false;    // assumes button is released on start up
            port = new InterruptPort(Pins.ONBOARD_SW1,      // Netduino's onboard button
                                     true,                  // glitch filter, no noticeable effect
            port.OnInterrupt += new NativeEventHandler(AdjustButtonState);

        // adjusts button state to pressed or not pressed; this is the button interrupt handler
        private void AdjustButtonState(UInt32 data1, UInt32 data2, DateTime time) {
            Pressed = (data2 == 0);

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.