Arduino ATtiny Fan or Any DC Motor PWM Speed Controller




Introduction: Arduino ATtiny Fan or Any DC Motor PWM Speed Controller

About: hacker working as hacker

I've made fumes extractor from old Dell fan. It's quite powerful: 110mm 12V 0,6A, but unfortunately it's horribly noisy on full speed. I decided to make speed controller for it. I wanted it to be as simple as possible, mounted on fan, thus powered from it's voltage line (12V), potentiometer controlled.

I chose ATtiny45 because main circuit would consist only of ATtiny and potentiometer. Alternative was 555 timer, but I wanted it simpler!

My fan had wire for PWM control, but there's nothing stopping you from using it with any DC motor with additional transistor!

I'll show how to program any ATtinyX5 or ATtinyX4 with Arduino IDE, how I've done my controller, how to use it with any DC motor, and how tu use zener diode as simplest voltage regulator.

Check out my blog's post about this project!

Step 1: Prepare Arduino IDE

In Arduino IDE (version 1.6.4 or newer is needed) open preferences window (File>Preferences) and add

into Additional Boards Manager URLs.

Than open Boards Manager from Tools menu, search for attiny and install ATtiny extra Boards.

Now you can select your ATtiny from Tools>Board and Tools>Micro menus.

I used ATtiny45 @ 1MHz - It's internal oscillator, so no crystal is needed. You can also choose 8MHz, but It's not necessary to speed it up so much.

For Attiny85 I recommend 1MHz internal oscillator, BOD disabled option. You can also use ATtiny25 @ 1MHz for this simple motor or fan controller.

Step 2: Prepare ATtiny

You need to set ATtiny's fuses in order to use it as Arduino. This means programming some internal memory, so tiny could know what clock source to use and some other important stuff. It is done by "Burn bootloader" in Arduino IDE Tools menu. Unfortunately ATtinys do not have hardware serial interface so they do not have real bootloader. You need AVR programmer (AVR is family of Atmel microcontrollers containing ATtinys and ATmegas used by Arduino) to program them every time.

Any Arduino board is suitable to be used as AVR ISP (in system programmer).

for UNO and other ATmega328 based boards connect:

13 to SCK ATtinyX5 pin 7
12 to MISO ATtinyX5 pin 6
11 to MOSI ATtinyX5 pin 5
10 to RST ATtinyX5 pin 1
5V to ATtinyX5 pin 8
GND to ATtinyX5 pin 4

For any other AVR programmer connect corresponding signals together: MISO to MISO and so on...

Chose programmer you use from Tools > Programmer and Burn bootloader.

Step 3: Program and Assembly

Here's code:

#define sensorPin A3 //input pin for the potentiometer - phisical pin 2
#define pwmPin 4 // select the pin for the fan driver - phisical pin 3 void setup() { pinMode(pwmPin, OUTPUT); } void loop() { analogWrite(pwmPin, map(analogRead(sensorPin),0,1023,0,255)); delay(10); }

Do not disconnect ATtiny from programmer and upload code . You can try it out on LED. Turning potentiometer should dim it.

I wanted It to be attached to fan and powerd from fan's supply, so I used Zener diode as voltage regulator, which was laying in my component box for quite long time. Zener diode needs series resistor, which is limiting current flowing through it and load circuit (ATtiny in this case). I experimentally figured that I need ~100ohm, but one 100ohm resistor was getting quite hot (12V/100ohm=120mA 120mA*12V=~1,5W !!!) small through hole resistors are usually rated 1/4W or 1/2W, so I decided to use 3 x 330ohm resistors in parallel (0,5W/resistor). They do not overheat. But you can use 5 x 470ohm to be sure. Also more convenient would be use of LDO (e.g. 7805) but I had that diode..

I used this controller with fan, which has 4 wires: red for 12V, black for GND, yellow for speed signal out, and blue for PWM control. For this kind of fan you just need to connect pwmPin to fan's blue wire. For any other fan or DC motor you'll need N-MOSFET transistor connected in series with that motor. source should be connected to higher voltage than drain, and gate to pwmPin (see attached schematic).

Be the First to Share


    • One Board Contest

      One Board Contest
    • Jewelry Challenge

      Jewelry Challenge
    • Anything Goes Contest 2021

      Anything Goes Contest 2021



    4 years ago

    Not a bad circuit, but a few things I would suggest.

    1. Definitely switch to a voltage regulator. LM7805 would be fine.

    How you have it now can source a maximum of 63mA or ~44mW (3 330 ohm resistors is equivalent to 110 ohms.

    Max current = 7v (voltage drop across resistors)/110ohms = 63mA.

    Max power = 63mA * 7V = 45mW.

    Using 1/4W resistors should be okay, but definitely do not use 1/8W.

    With the fan turned up all the way, the pot is drawing 15mA, so 25% of the total available current. My guess is the ATtiny uses about another 15mA min, though likely closer to 30-40 with the PWM clock running....So you're cutting it very close.

    2. Add a filter cap across the ATtiny's VCC & GND pins.

    3. Add a small RC filter between pot and ATtiny to help smooth out the input. I typically use a 1Hz filter, so a 1uF cap and 160k resistor (or 10uF cap and 16k, etc).

    4. Finally I'd use a different mosfet. The IRF540 has an Vgs(on) of 10v, so driving it with 5v, and depending on the fan current, could cause enough source-drain resistance to heat it up. Probably not bad, but a logic level would be more appropriate.


    Reply 4 years ago

    You are right about supply cap. I should add ~100nF. Logic level MOSFET should be used with 5V circuit, or another BJT as amplifier should be added. I used this circuit with PC fan, so output was connected directly to fan PWM input and I didn't think about that.
    Pot will draw 5V/100k=50uA, and washer position has nothing to do with that. RC filter is not necessary, it's stable.
    Zener diode LDO works different than you think. Here's tutorial . Max current will be 12V/110r=110mA. So 100mA should be safe to draw, because Z-diode needs some current passing through, and 100mA is more than enough for ATtiny driving one PWM and ADC.


    4 years ago


    I have an program please Cheack it

    i want to use attiny85 to control fan speed using an tempracher sensor but project is not working please cheack the code

    please replay me as soon as possible

    int sensorPin = A3;

    int PWM = 4;

    int sensorVal;

    int PWMVal;

    #define sensorPin A3

    #define pwmPin 4

    void setup() {

    // put your setup code here, to run once:

    pinMode(sensorPin, INPUT);

    pinMode(PWM, OUTPUT);



    void loop() {

    // put your main code here, to run repeatedly:

    //this code prints sensor value to the console



    //read sensor value and set upper limit cap

    sensorVal = analogRead(sensorPin);

    if(sensorVal >500){

    sensorVal = 500;


    //map and assign pwm values to the fan output 0 to 255 corresponds to 0 to 100%

    PWMVal = map(sensorVal, 450, 500, 100, 255);

    //set 450 as out cutout or cut in limit where the fan switches from off to the lower PWM limit

    if(sensorVal <450){

    PWMVal = 0;


    //write the PWM value to the pwm output pin

    analogWrite(PWM, PWMVal);



    Reply 4 years ago

    I assume that you want to use analog temperature sensor.
    I see few mistakes:
    1. Small ATtinys don't have hardware seria,l so you can use software serial library instead.
    2. You define with macro and integer variables with same names. Delete #define ones, because they are constant. Google #define to understand how it works. And never again try to define few variables/constants with same name!
    I'm not shure why do you map sensor value to 100-255 and then set that to zero when sensor is lower than 450. That might be logical mistake, but I don't know what do you want to do..
    Try that chip with potentiometer instead sensor. It's simpler and faster.