DC MOTOR 2.o (PWM Control)

In this blog post I will cover the operation of a DC motor with PWM control.

PWM stands for “Pulse Width Modulation” and is a very handy tool in electronics and robotics. It can be used to dim an LED (by adjusting the average voltage [also known as the duty cycle, I’ll place some equations about how that relates]) it can also be used to control the angle of a servo motor depending on the “Time” of the pulses being produced by the micro-controller.

Now back to the DC motor and its control, based on my last blog we saw we can control motor in three different states [Forward, Backwards, and no where (if I ever edit the code I’ll add the stop position in that code)]. Now we are going to add a control method of accelerating the motor between different speeds. We will send a PWM signal in different duty cycles from the DSPIC30F4011 to the SN754410NE driver chip.

As the SN754410NE datasheet states it has a “1, 2EN and 3, 4EN” on pins 1 and 9. figura_1 These pins will be used to input the PWM signal from the  DSpic. In this scenario 25% duty cycle means 1/4th of the full speed, 50% duty cycle means 1/2 the full speed, 75% means 3/4 the full speed, and 100% duty cycle means full speed. So by having the motor move in a certain direction added with a PWM duty cycle we will have a motor moving in one direction at any given speed.



Here is the code used for the video sample below.

// DC Motor control example for dsPIC30F4011
// Written by Kevin Tighe
// Based on the code written by Ted Burke
// Last updated 28-10-2016

//important stuff
#include <xc.h>
#include 				<libpic30.h>
#include <stdio.h>
//More important stuff
_FOSC(CSW_FSCM_OFF & FRC_PLL16); // Clock speed = 7.5MHz x 16, i.e. 30 MIPS
_FWDT(WDT_OFF); // Watchdog timer off
_FBORPOR(MCLR_DIS); // Disable reset pin


#define Second 30000000

int main(void)

// Make All D pins digital outputs
TRISD = 0b0000;

// Configure PWM
// PWM period = PTPER * prescale * Tcy = 9470 * 64 * 33.33ns = 20ms
_PMOD1 = 0; // PWM channel 3 mode: 0 for complementary, 1 for independent
_PEN1H = 1; // PWM1H pin enable: 1 to enable, 0 to disable
_PTCKPS = 3; // PWM prescaler setting: 0=1:1, 1=1:4, 2=1:16, 3=1:64
PTPER = 9470; // Set PWM time base period to 20ms (15-bit value)
PDC1 = 0; // 0% duty cycle on channel 1 (16-bit value)
_PTEN = 1; // Enable PWM time base to start generating pulses

// Control motor
// Forward for 4 seconds @ 10% Power
PDC1 = 0.1 * 2 * PTPER;     // 10% duty cycle
LATD = 0b0011;                    // Forward & LED ON
__delay32(Second * 4);

//Forward for 4 seconds @ 25% Power
PDC1 = 0.25 * 2 * PTPER;      // 25% duty Cycle

LATD = 0b0011;                       // Forward & LED ON
__delay32(Second * 4);

//Backward for 4 seconds @ 50% Power
PDC1 = 0.50 * 2 * PTPER;     // 50% duty Cycle

LATD = 0b0100;                      // Backword & LED OFF
__delay32(Second * 4);

//Forward for 4 seconds @ 75% Power
PDC1 = 0.75 * 2 * PTPER;        // 75% duty cycle

LATD = 0b0011;                          // Forward & LED ON
__delay32(Second* 4);

//Forward for 4 seconds @ 25% Power
PDC1 = 1 * 2 * PTPER; // 100% duty cycle

LATD = 0b0
__delay32(Second* 4);

// Stop for 2 seconds
LATD = 0b0010;
PDC1 = 0 * 2 * PTPER; // 25% duty cycle
__delay32(Second * 2);

As some of you may have noticed I did use a 20 Volt power supply in the video, the main reason for this was at 6 volts I could not get the level of current to drive the motor at higher speeds, its also fun to watch things move fast. Any ways the motor did not move very well with low duty cycles at 6 Volts so I thought 20 Volts was a great idea (since the maximum voltage the driver chip is only 32 Volts DC), another great aspect of higher torque is you can hear the motor changing speeds very well.


I did a quick experiment with 30 volts (since the bench supply unit I had with me at the time could only go up to 30 Volts max), unfortunately I did not record but the motor moving at those speeds… Then my capacitor blew as you can see below it was not a bad explosion, should of used bigger capacitors.

if your wondering which one blew, look at the right one.

DC Motor

A DC motor is a type of electrical machine that uses Direct Current to rotate the shaft either clock wise or anti clock wise depending on the polarity applied to the motor.

A simple DC motor

The basic principal of operation for a DC motor is when current flows through the armature the electric field of the armature experiences a torque from the magnetic field caused by the rotor thus causes the armature to turn depending on the direction on which the current is flowing through the armature.

Since we know the current is proportional to the magnetic flux and torque, we can use this aspect of the motor ton control the speed of the motor, however the DSPIC30F4011 cannot supply enough current to even make the motors turn slightly, so a “driver chip” is needed, to produce the current levels to make the motor spin.  SN754410NE quad half H-bridge IC will be used.

The SN75441one job is basically take in a logic instruction (ON or OFF) into its input pins from the DSPIC and produce that same logic instruction on its output pins with greater current levels than to that which the DSPIC can produce to help create the desired torque for the DC motor.

First lets start with ON and OFF control of the DC motor to create some simple forwards and backward motion. This Circuit diagram was created with “fritzing“.


// Single Motor On Off Control example for dsPIC30F4011
// Written by Kevin Tighe
// Based on the code written from Ted Burke
// @batchloaf.wordpress.com or @roboted.wordpress.com

#define Second 30000000          // 1 second

//important stuff
#include &lt;xc.h&gt;
#include &lt;libpic30.h&gt;
#include &lt;stdio.h&gt;

//more important stuff
_FOSC(CSW_FSCM_OFF &amp; FRC_PLL16); // Clock speed = 7.5MHz x 16, i.e. 30 MIPS
_FWDT(WDT_OFF);                  // Watchdog timer off
_FBORPOR(MCLR_DIS);              // Disable reset pin

int main(void)
// Make RD0 and RD2 digital outputs
TRISD = 0b1010;
_TRISE0 = 0;                     // make RE a D/IO
// Control motor
        // Forward for 4 seconds
        LATD = 0b0001;          // forwards
        _LATE0 = 1;
        __delay32(Second * 4);

        // Backwaard for 4 seconds
        LATD = 0b0100;         // backwards
        _LATE0 = 0;
        __delay32(Second * 4);



Here is a sample of the motor in operation, I realized after watching the video that I should have added a stop. Enjoy the video!