DC Motor Speed Control using PWM with PIC Microcontroller

DC Motor Speed Control using PWM with PIC Microcontroller

I already posted about Interfacing DC Motor with PIC Microcontroller. In our robotics applications we may have to control the speed of the DC Motor. In this tutorial we will see how to control the speed of a DC Motor using Pulse Width Modulation (PWM). By using PWM we can easily control the average power delivered to a load and by thus we can easily control the speed of the DC Motor.

You may think that a variable resistor in series with a DC Motor can control its speed. There are three reasons for “Resistor is not a good choice for controlling the speed of a DC Motor”.

  • The main problem is that the motor is a varying electrical load so a resistor can’t do this task. It needs more power during start up than in running state. It draws more current also when a mechanical load is applied to motor shaft.
  • The resistor drops excess energy as heat. Thus it is not good for a battery powered device.
  • We all know that motor requires more current, so resistors with higher power rating are required to drop excess energy.

PWM can be easily generated using the inbuilt CCP module of a PIC Microcontroller. CCP stands for Capture/Compare/PWM. CCP modules are available with a number of PIC Microcontrollers. Most of them have more than one CCP  module. MikroC Pro for PIC Microcontroller provides built in library routines for PWM which makes our task very simple. Please refer the following articles.

In this example project DC Motor is interfaced with PIC Microcontroller using L293D Motor Driver. Two Push Button switches are provided to control the speed of the motor. Here we are using 12V DC Motor and average DC value delivered to motor can be varied by varying the duty ratio of the PWM. The average DC Voltage of 0% duty cycle is 0V, 25% duty cycle is 3V, 50% duty cycle is 6V, 75% duty cycle is 9V and for 100% duty cycle 12V.


Circuit Diagram – DC Motor Speed Control

DC Motor Speed Control using PWM with PIC Microcontroller
DC Motor Speed Control using PWM with PIC Microcontroller

Note: VDD and VSS of the pic microcontroller is not shown in the circuit diagram. VDD should be connected to +5V and VSS to GND.

Two push button switches are connected to 1st and 2nd pins of PORTD which is used to control the duty ratio of the generated PWM. Pressing the UP switch increases the duty cycle, which increases the motor speed while pressing the DOWN switch decreases the duty cycle, which decreases the motor speed. Here we use CCP1 module of PIC 16F877A to generate PWM and it is given to the enable pin of L293D. The direction of rotation of motor can be control using the 1st and 2nd pins of PORTB.

MikroC Code

void main()
{
  short duty  = 0; //initial value for duty

  TRISD = 0xFF; //PORTD as input
  TRISC = 0x00; //PORTC as output
  TRISB = 0x00; //PORTB as output
  PORTB = 0x02; //Run motor in anticlock wise

  PWM1_Init(1000);  //Initialize PWM1
  PWM1_Start();  //start PWM1
  PWM1_Set_Duty(duty); //Set current duty for PWM1

  while (1)        // endless loop
  {
     if (!RD0_bit && duty<250) //if button on RD0 pressed      
     {       
        Delay_ms(40);       
        duty = duty + 10;  //increment current_duty     
        PWM1_Set_Duty(duty);  //Change the duty cycle      
     }     
     if (!RD1_bit && duty >0) //button on RD1 pressed
     {
       Delay_ms(40);
       duty = duty - 10;  //decrement duty
       PWM1_Set_Duty(duty);
     }
    Delay_ms(10);      // slow down change pace a little
  }
}

The parameter of PWM1_Set_Duty() is duty ratio which ranges from 0 to 255, ie 0 means 0% duty cycle and 255 means 100% duty cycle.

I think the program is self explanatory, so if you have doubts please comment below.

You can download the hex file, MikroC source code, Proteus files etc here…

DC Motor Speed Control with PIC Microcontroller

Share this post

  • hi sir. can i know is this code program can use in pic c compiler. if cant how to change it

  • sir , i hove a doubt about how to stop the dc motor? using pic 16f877a ..please send me souce code.

  • when I simulate this on proteus, on one fixed value of duty cycle the speed keeps on increasing. Infact it should remain constant for a a single value of duty cycle. You think is that a software draw back ?

  • the motor about which i am talking is a DC series wound motor which is used as starter motor in automobiles.these motors are powered by 12V dc supply by battery and what i know is that speed of dc motor depends on applied voltage and i think there is no other way than PWM by which speed of DC motor could be varied over a range. so please help me if i am wrong about this and would it be possible to control this type of motor by this method.

  • hello sir, i don’t know much about electronics as a mechanical engineer but i want to know, by this method described above can we control the speed of a heavy motor like 1.5kw to 2kw power capacity or there is any other way?
    thanks in advance

  • Just connect a potentiometer to the ADC input of a microcontroller. As the input voltage varies, adc result will also vary. You can easily convert this to PWM.

  • the coding is

    #include

    #include

    #include”xc.h”

    #include

    #define byte unsigned char

    void main()

    {

    short duty = 0; //initial value for duty

    TRISD = 0xFF; //PORTD as input

    TRISC = 0x00; //PORTC as output

    TRISB = 0x00; //PORTB as output

    PORTB = 0x02; //Run motor in anticlock wise

    PWM1_Init(1000); //Initialize PWM1

    PWM1_Start(); //start PWM1

    PWM1_Set_Duty(duty); //Set current duty for PWM1

    while (1) // endless loop

    {

    if (!RD0_bit && duty0) //button on RD1 pressed

    {

    __delay_ms(40);

    duty = duty – 10; //decrement duty

    PWM1_Set_Duty(duty);

    }

    __delay_ms(10); // slow down change pace a little

    }

  • hey guys i need help to solve this question?
    draw a circuit to Turn ’ON’ the ignition circuit when
    the interior light is ‘OFF’ AND when your student number has been entered.

    After 3 failed attempts at entering
    the student number the required number will default to ‘25122015’.

    Once ‘ON’ the ignition must stay
    ‘ON’ even if the interior light is switched ‘ON’

    This must be simulated in Circuit
    Wizard.

  • Sir ..Good evening………..
    How can we control the speed a DC motor by receiving a sms or alert signal

  • hey i used the foolowing code

    unsigned int temp_res;

    unsigned short temp_duty;

    void main()

    {
    ADCON1 = 0x80; // Configure analog inputs and Vref

    PORTC = 0;

    TRISC = 0; //all PORTC pins output

    // Initialize and start the PWM unit

    PWM1_Init(5000);

    PWM1_Start();

    while(1){

    temp_res = Adc_Read(0); // Get results of
    AD conversion

    //from channel
    0 (RA0 pin)

    temp_duty = (temp_res/4); // Convert the 10
    bit value

    //to 8 bits

    PWM1_Set_Duty(temp_duty); // Set the duty
    value

    Delay_ms(20000); // Slow everything down a
    little

    }

    }

    the value of servo remains const at -90 degree .

    its value is not changing with adc values

  • hi ligo . i am using adxl 345 and using dc servo . i wish to know after the conversion of analog values from adxl by pic microcontroller 16f452 how will i give this digital value to pwm so that my motor rotaes proportionally with the adxl tilting.
    thnx in advance

  • sir i want to the circuit diagram of pic controller of 230v but above circuit only give 12v,i am want 230v so pls reply me

  • sir,
    And need the circuit diagram of automatic railway gate on/off controller .If u having please send me

  • sir, may I know how the unique code is generated from an ir sensor when it sense the ir remote pulse. and how can we get the codes…….?
    can u help us…..

  • sir,
    whether we can control the same ckt with remote.
    if you having any circuit diagram means please mail me.

  • i want to know how to control the direction of motor using push button,which means it have forward button and reverse button.thank you

  • sir i want to use two stepper motors. i am using a3967 driver kit so i need to controlled them step by step in horizontal and vertical manner as i am building a xy scanner so suggest me some help for it

  • hey Ligo, can you tell me the rating of the motors for which this cct is applicable? and is it verified in terms of hardware ???…..

  • Sir, Here the pwm signals are being generated but in which part of the code are we sending them to Inputs of L293D (RB10 and RB11) ??

  • xc8.exe –pass1 –errformat=”Error at file %%f line %%l column %%c: (%%n) %%s” –warnformat=”Warning at file %%f line %%l column %%c: (%%n) %%s” –msgformat=”Message at file %%f line %%l column %%c: (%%n) %%s” -G –chip=16F877A -O”main.p1″ “../main.c”

    Microchip MPLAB XC8 C Compiler (Free Mode) V1.31

    Copyright (C) 2014 Microchip Technology Inc.

    License type: Node Configuration

    Warning at file line column : (1273) Omniscient Code Generation not available in Free mode

    Warning at file ../main.c line 15 column 1: (361) function declared implicit int

    Warning at file ../main.c line 16 column 1: (361) function declared implicit int

    (908) exit status = 1

    make: *** [main.p1] Error 1

    Warning at file ../main.c line 17 column 1: (361) function declared implicit int

    Error at file ../main.c line 21 column 18: (195) expression syntax

    Error at file ../main.c line 23 column 13: (194) “)” expected

    Error at file ../main.c line 27 column 18: (195) expression syntax

    Error at file ../main.c line 29 column 13: (194) “)” expected

    Error at file ../main.c line 33 column 10: (194) “)” expected

    Error at file ../main.c line 34 column 1: (285) no identifier in declaration

    Warning at file ../main.c line 34 column 1: (374) missing basic type; int assumed

    Error at file ../main.c line 34 column 1: (314) “;” expected

    Error at file ../main.c line 35 column 1: (285) no identifier in declaration

    Warning at file ../main.c line 35 column 1: (374) missing basic type; int assumed

    Error at file ../main.c line 35 column 1: (314) “;” expected

    Error code 2

  • how to do if i want to control the speed by using 5 switches
    means that i have 5 speed. (just like fan)

  • This wish is reversible reversible how dear?, You can edit the code to help me please? Thank you

  • Hi Mate, I want to use this for a robotic arm, I am planing to use 2 DC motors for 2 joints (Each motor for each joints). I decided to use L293 motor driver full bridge IC. My question is should I use two L293 IC for 2 motors? both joints moves up and down wards. not side movement.
    I am designing my own PCB board on Altium designer. so plzz give me clear full circuit the with PIC16f877A and L193 for 2 motors. Thank you and have a nice day

  • sir ,
    i want to make a temperature controlled fan using pic168f77a i connected a temperature sensor in to pic’s adc input port A0.. and tried with your above program with slight modification.. but it shows error . it shows we want to initialise the identifier TRISD,C,B.. and lot of other errors..
    can you please help me..?

  • hi i am doing project on people counting system and home automation so as number of people increase temperature increase it is necessary and if yes so i can control the speed by pwm ? i am mot using temperature sensor. thanks

  • hello iwant to control dc motor and feed back to micro controller by using vco ineed the program in micro c

  • is it possible to run a 3V DC motor directly from the microcontroller? or do i need a motor driver for it to turn?

  • Hello, it will work..
    Did you tried it in hardware..??
    If it is not working in hardware.. try connecting the EN1 pin to VDD and check whether the motor is working……..
    if it works.. then reconnect it to ccp pin… then try reducing the pwm frequency…

  • The above microcontroller have ADC…. I think the above microcontroller is enough for you… since I think you are dealing with slowly varying analog signals…………..
    A driver is required.. to drive the motor..

  • two questions

    1) Can this setup receive an analog signal to the microcontroller? does it have ADC? Basically what type of micro controller is used to monitor an analog signal in real time and compute the motor speed based on a function of the incoming analog signal? (or would a DSP be more suited for this)

    2)is it always necessary to have a motor driver between the microcontroller and the motor? Or are do there exist microcontrollers that can directly control the motor speed?

  • PLEASE GIVE ME THE FUTURE USE AND APPS OF

    SPEED
    CONTROL OF A DC MOTOR USING MICROCONTROLLER 8051

  • To display speed in rpm you need more than one seven segment.. You can use above link and Hex() covert a number to its 7 segment code…
    The speed of the dc motor can be find using an IR transmitter and Receiver, by counting the no. of times IR beam is cutting in a minute…….

  • okay, thanks! And what about the coding part ? If i want to display the speed in rpm

  • Yes.. of course… .. Note that for 18f series.. output register is LAT… not PORT… PORT is used for reading data……You need to change the output registers of above program as LAT… no other changes in program..

  • For the speed control of 3 phase induction motor you need 3 pwm channel.. but the above pic has only two.. but you can generate a Software generated pwm using interrupts of CCP module……
    You need to vary the frequency of the pwm to control the speed of three phase induction motor..

  • what about 3ph induction motor i wanna connect potentiometer with pic to controlled motor speed i need pic code of this case any one help me

  • Hey great documents, thanks. Sir, I need to do a pic16f84a project that controls dc motor gonna use mosfet, i need to speed it up and slow it down with a pwm technique can you help me with circuit and assm code if you have some time?

  • Yes you can generate continuous pwm by changing dutycycle…
    The parameter of PWM1_Set_Duty() is duty ratio which ranges from 0 to 255, ie 0 means 0% duty cycle and 255 means 100% duty cycle.

  • I want to generate continuous pwm on the basis of voltage. Can it possible that one pin generate pwm continuously while my program observing voltage continuously with out disturbing PWM. IN this program you add 10 in duty cycle how much duty it increase.Thanks

  • hi,
    I am using a pic18f452 with a crystal 4Mhz …. Do i have to change the constant 1000 ???

  • Nop, since we are using MikroC compiler, there are only some modifications… To set direction of io pins use TRIS register, to read data from io pins use PORT register but for write data to io pins use LAT register…
    In the above program change PORT register to LAT, it will work..

  • am trying 2 run it with pwm from pic16f887 but it keeps implying that somrthing is wrong with my signal ,.. so am thinking of substituting the ESC with a motor driver IC .. good idea or not ?

  • Brushless DC Motors uses a 3 phase AC motor that has connected to a Electronic Speed Controller (ESC) circuit…. so there is no use of DC PWM controller in this case……..

  • can i use this setup to drive brushless outrunner motors ?
    i have tries using ESC with very little luck
    thank you !

  • Hi..I had a doubt that rather than using switch to control duty cycle is it possible for us to write a code and accordingly generate pwm?

  • Yes, it may be said like that as the motor is not fully ON or OFF …. …. You can incorporate fuzzy logic concept in to above code, for eg: speed control of FAN according to the room temperature…

  • thank u so much..is there a fuzzy logic concept in the above code or can we incorporate the fuzzy logic concept into the above code.?

  • You can use the above program for pic 18f452 with some modifications. As shown above TRIS registers are used to set the direction of a pin while to write a data to a output pin LAT register is used. But for reading a port PORT register is used as above………. You can use the above functions in mikroc for 18f452

  • HI…ur posts are very useful and informative…i was wondering if you could provide me with the details of doing this same task with a pic18f452.


  • >