Download PDF Parts List View on YouTube Download Code


I’m very excited to announce a new project here in the workshop!

I’m building a robot. This probably won’t come as Earth-shattering news on a site called “DroneBot Workshop”, but this robot is different.  Unlike the small “robot car” bases I’ve used in past projects, this will be a big robot. A capable robot.

A “real” robot!

Real robots need big motors and for my robot, I’ve chosen a couple of large DC gearmotors to do the job.  These powerful motors consume a lot of current, which means I’ll need to use a motor driver that can handle the current without burning up.

Today I’ll show you how to do exactly that, control a large DC gearmotor and change its speed and direction. I’ll be using an Arduino to create a Pulse Width Modulation (PWM) signal to regulate the motor speed and a Cytron MD10C motor driver to supply the power.

Controling DC Gearmotors with PWM

Let’s get started!

DC Gearmotors

DC gearmotors are used in many electromechanical applications in appliances, industry, and robotics.  Their high torque and low cost make them popular components for experimenters and hobbyists.

A “normal “DC motor spins at a very high speed, often several thousand RPM.  This is great for a high-speed drill but much too fast for spinning wheels to move a robot or car around.  

In a gearmotor there are, not surprisingly, a set of gears that reduce the motor speed to something more manageable, a few hundred RPM or even less.  The motor I’m using has a full-speed shaft rotation of just 110 RPM.

DC gearmotors on frame

When you reduce speed using gears you also increase torque, this inverse relationship means the slower you gear the motor down the more torque it will have.   

Most DC gearmotors, including the one I purchased for my robot, use brushed DC motors.

Pulse Width Modulation

Pulse Width Modulation, or PWM, is a method of controlling the speed of a motor. It actually has many uses beyond that, controlling lights and LED’s and data communications are a few other applications of PWM.

With PWM control the DC current applied to the motor is sent in square-wave pulses. The width of the pulses is changed to regulate motor speed, the wider the pulse the faster the motor will spin.

The pulse width is expressed as a percentage, at 50% the output is a perfect square wave. At 75% the pulse spends 75% of its time HIGH, the rest LOW.  At 25% it is HIGH 25% of the time and LOW for 75%.

This width is called the “duty cycle”.

At 100% width the pulse is constantly HIGH. The motor receives full power and spins at its rated output speed.

At 0% the signal is constantly LOW, essentially meaning no voltage at all. Obviously, this causes the motor to stop.

For a detailed explanation of PWM please see the article “Controlling DC Motors with the L298N Dual H-Bridge and an Arduino”.


A common method of controlling a DC motor is to use an “H-Bridge”. This type of controller allows you to change the polarity of the current sent to the motor.

H-Bridge Operation

An H-Bridge is an arrangement of switches that allows you to apply current to a DC motor and reverse the polarity to spin the motor in the opposite direction, as illustrated below:

H-Bridge Design Basics

By turning on two of the switches the current is directed to the motor, In the following illustration, the motor spins clockwise when the switches are turned on:

H-Bridge Design Clockwise

Turning those switches off and then turning on the remaining two switches will cause the polarity of the current to be reversed. As a result, the motor spins counterclockwise.

H-Bridge Design Counterclockwise

Of course in real life, we seldom would use switches to create an H-Bridge.

Instead, we would use an active semiconductor switch, like a transistor, to do the switching for us.

H-Bridge with Bipolar Transistors

In a traditional H-Bridge, like the L298N, the switching elements are built with bipolar transistors.

Bipolar transistors are the oldest and one of the most common types of transistor. They are inexpensive and readily available, making them ideal for use in circuits like H-Bridges.

H-Bridge Design with Bipolar Transistors

The problem with bipolar transistors is that in switching mode they act a lot like a “switched diode”, and like any diode, they have a voltage drop. A voltage drop of 0.7 volts.

While that may not sound like a lot of voltage it actually does cause a lot of issues with H-Bridge circuits based upon bipolar transistors.

First, there are two transistors, so the total voltage drop is 1.4 volts. This is significant, especially for low-voltage motors like the 6-volt ones commonly used in small robot cars. A 6-volt power supply would only deliver 4.6 volts (6 – 1.4) to the motor, causing it to operate below its peak efficiency.

Second, that voltage doesn’t just disappear. Instead, it is dissipated, mostly as heat. This is why many H-Bridge designs require big heatsinks.

There is actually a better component that can be used, one that doesn’t exhibit the problems suffered by bipolar transistor designs.

H-Bridge with MOSFETs

A metal-oxide-semiconductor field-effect transistor, or MOSFET, is a more advanced transistor that has become extremely popular in switching and amplifier circuits.

When used as switch a MOSFET acts more like a “switched resistor” than a “switched diode”.   A very low-value resistor at that.

H-Bridge Design with MOSFETs

This gives the MOSFET a very low voltage drop.  The 0.1-volt drop on the above illustration is actually just an estimate, as a MOSFET acts more like a resistor the actual voltage drop is really determined by the amount of current flowing through it.

Suffice to say that the voltage drop is extremely low.

Because the MOSFET doesn’t drop the voltage as much as a bipolar transistor it is superior to the bipolar transistor in the following ways:

  • It loses a lot less voltage, practically none at all. This makes it ideal for low-voltage applications.
  • Because of the low voltage drop, it produces far less heat. Most of the energy is used to power the motor, very little is lost in the H-Bridge.

For the large gearmotor I’m working with I’ll be using a motor driver based upon MOSFETs.

Cytron MD10C Motor Driver

When searching for a MOSFET-based H-Bridge that could power my motor I ran across several devices. Most of them were fairly expensive, often exceeding the cost of the motor itself.

There are, however, a few exceptions.

One of them is the Cytron MD10C driver board. It’s inexpensive and has some very impressive features.

Cytron MD10C Specifications

The Cytron MD10C is a MOSFET-based motor driver that is very easy to use. It has the following specifications:

  • Power supply – 5 to 30 volts DC. This is the power supply for the motor, the MD10C has an internal voltage regulator to supply its own logic circuits.
  • Maximum continuous motor current of 13 amperes.
  • Peak motor current of 30 amperes. This can be sustained for up to 10 seconds.
  • It works with both 3.3-volt and 5-volt logic systems.
  • It has a maximum PWM frequency of 20 KHz. You’ll see in a few moments how important that is.
  • It has two push buttons to test your motor connections and two LEDs to indicate motor direction.

Another feature, of course, is its low price. It’s currently available for less than 12 US dollars per unit, much less than drivers with similar specifications.

Cytron MD10C Connections

Hooking up the Cytron MD10C is very simple.

Cytron MD10C Pinouts

On one side of the board there are four screw terminals, they are as follows:

  • Power + – The 5 to 30-volt power supply Positive input.
  • Power –  – The 5 to 30-volt power supply Negative or Ground input.
  • Motor A – One side of the motor coil.
  • Motor B – The other side of the motor coil.

On the opposite end of the board you will find the input connector. It has three pins, as follows:

  • DIR – This is the Direction input, a logic-level signal that determines which direction the motor shaft will spin.
  • PWM – The Pulse Width Modulation signal input. This regulates the motor speed.
  • GND – A Ground connection.

There are also two push buttons on the board, labeled “A” and “B”.   Pressing either one of these will spin the motor in one or the other direction, depending upon which one you press. It is a nice feature as it allows you to test your motor and power supply wiring without needing a PWM controller.

The motor direction is also indicated by two LEDs, also labeled “A” and “B”.

Cytron MD10C vs L298N H-Bridge

The Cytron MD10C has several advantages over the L298N.

  • It can handle 13 amperes continuous, versus the 3 amperes that the L298N can handle.
  • It is much more efficient due to the use of MOSFETs. The MD10C has a very low voltage drop, meaning that most of the energy is sent to the motor coils.  The L298N, on the other hand, drops 1.4 volts.
  • Because of its efficiency, the Cytron MD10C does not require a heatsink. The L298N needs a good-sided heatsink to dissipate the energy absorbed by its bipolar transistors.

The high-efficiency and low heat dissipation make the Cytron MD10C ideal for robotics applications, where every bit of energy needs to be used as efficiently as possible.

L298N versus MD10C

Physically the L298N board is about half the size as the MD10C, and you should also note that the L298N can drive two motors whereas the MD10C is a single motor controller.

Cytron also manufactures the MD10A, a dual-channel version of the MD10C.

The board is packaged along with some plastic standoffs and a connector for the input, a nice touch.

Arduino PWM

We have used Pulse Width Modulation (PWM) with the Arduino in many of our designs, for DC and servo motor control as well as for regulating the intensity of LEDs.

In the Arduino IDE you can control PWM using the analogWrite command.  This command has two inputs:

  • The pin that you are sending the PWM out of.
  • The PWM value, from 0 to 255. A value of 0 indicates no speed (output held LOW) and 255 is full-speed (output held HIGH).

Not every pin on the Arduino is capable of PWM. On many Arduino (and clone) boards you’ll notice a small symbol beside the PWM-capable pins, usually a sine or square wave or tilde sign (i.e.  “~” ).

On the Arduino Uno pins 3, 5, 6, 9, 10, and 11 support pulse width modulation.

Arduino Hookup

In our Arduino PWM controller we are going to make use of another component that I’ve worked with before, the LCD Keypad Shield.  You’ll find details for using this shield in the article Using LCD Displays with Arduino.

The keypad shield has a number of push buttons and they operate in a rather unique fashion. Instead of using digital I/O pins these buttons are connected to a resistor array. The array acts as a voltage divider and every time you press a button you’ll send a different voltage out. This is read on analog input A2 on the Arduino.

Hooking up all the components for our PWM test is pretty simple.

Cytron MDC10C Arduino Hookup (no keypad)

You’ll need to supply power that is suitable for your motor, I show a 12-volt power supply here but if you have a motor with a different voltage rating then you should change this to suit your motor.  Keep in mind that the MD10C has a voltage range of 5 to 30-volts.

Make sure that your power supply has a suitable current rating for powering your motor.

There are not many connections to the Arduino at all, just the ground and the DIR and PWM pins. I’m using pin 3 as it is PWM-capable.  

Cytron MDC10C Arduino Hookup with LCD Keypad

After you get it all wired up install your keypad shield.

In my test setup, I used an additional shield, a prototyping shield with screw terminals. This is a really handy shield as it sits in between the Arduino Uno (or Mega) and the shield you are working with. Screw terminals are provided for access to every Arduino pin.


This arrangement allows me to connect to the Arduino while a shield is mounted, otherwise, you may need to do a bit of soldering to make the connections.

Basic Arduino PWM Sketch

Cytron provides an Arduino sketch that can be obtained through the MD10C Wiki, unfortunately the sketch is not really usable in the form they provide it.  Two problems actually:

  • It uses pin 2 as a PWM output, but pin 2 is not PWM-capable.
  • It uses a library for the LCD Keypad that is not very easy to find.

I’ve resolved both those issues and fixed up a bit of the code.  Here is what it looks like now:


You can get the LCD Keypad library, as well as all of the sketches used in this article, from the link in the resources section at the bottom of this article.

The sketch starts by including both the LCD Keypad library and the LiquidCrystal library. The latter is included in your Arduino IDE.

Next the keycodes are defined for the keys on the LCD keypad.

We then define the analog A2 pin to be the pin the keypad is connected to . We also define two output pins for the PWM and DIR connections.

Next we setup objects for both the LCD display and the keypad itself. Note the pins used to connect the LCD are defined here.

Finally, we define a couple of variables – one to represent the PWM value (from 0 to 255) and the other to represent the keypad button value.  The PWM value is also initialized at zero, so that the motor will be stopped when the Arduino is powered on or reset.

In the Setup section we set up the LCD display as a 16 character, 2-line display. We also define the PWM and DIR pins to be outputs.

Now onto the loop!

The loop starts with a “while(1)”  statement. This statement simply means that the code within the while statement is executed infinitely.

In the while(1) statement we first get the keypad value. We then perform an action depending upon what key is pressed.

  • If the LEFT button is pressed then we toggle the DIR pin to change motor direction.
  • If the UP button is pressed we increment the PWM speed value by 1.
  • If the DOWN button is pressed then we decrement the PWM speed value by 1.

The RIGHT button is undefined. The Reset button is connected to the Arduino Reset line and will (what else?) reset the Arduino when pressed. This is also a good way to instantly stop the motor as we initialized the PWM speed value as zero.

We then check the PWM value to ensure that it stays in the range of 0 to 255.

Finally, we write the PWM and DIR values to the LCD display.

Load the sketch to your Arduino and give it a try. You should be able to control the speed of your motor using the UP and DOWN buttons and change its direction with the LEFT button.

Using the LCD Keypad

When I tested it everything seemed to work properly. However, it isn’t perfect.

Arduino PWM Results

The controller had no problem changing the speed and direction of my motor. At the lower speeds, however, it caused the motors to emit a loud “whining” sound.

Arduino PWM Scope Waveform

When I hooked an oscilloscope to the motor leads I observed that the signal was very distorted, indicating that the transfer of energy was not 100% efficient.  I also observed that the motor was consuming a lot of current, especially at higher speeds.

Our PWM controller may be able to be improved. Let’s see what we can do to make it better.

PWM Frequency

I measured the PWM frequency that came from our Arduino controller and got a value of 488 Hz. This is obviously the source of the “whining” sound, and it also is the reason that the waveform is so distorted.

The motor coil(s) are acting like inductors and so the output of the MD10C is really part of a tuned circuit. And it looks like our circuit is out of tune!

Changing the PWM frequency could resolve this. In fact, some industrial PWM controllers use frequencies above the range of human hearing to control their motors.

Raising the PWM Frequency

Raising the PWM frequency has a lot of advantages, but like any good thing it’s possible to overdo it.

There is sort of a “sweet spot” for PWM frequency. As the frequency rises the torque of the motor can be reduced. Initially this reduction is minimal, however once you go above a certain frequency it falls rapidly.

The frequency just before this point is the ”sweet spot”. A place where the frequency is high enough to prevent “whining” and yet still allows the motor to produce full, or nearly full, torque.

My PWM Test Setup

To determine my motors “sweet spot” I disconnected the Arduino PWM output and instead used the output of a signal generator, set to deliver a 5-volt square wave.  

With the signal generator I could adjust both the frequency and the duty-cycle of the square wave, the duty-cycle gives me control over the motor speed.

As I increased the frequency I observed the waveform on the oscilloscope, as well as the sound emitted by the motors.


By the way, the top trace (which is the input signal) may look a bit rounded but in reality, it isn’t, it’s a result of being loaded down by the probe to my frequency counter!

The real business is the bottom trace, the blue pone. Note how much nicer ot looks than the original trace that I saw when examining the Arduino PWM.

Clearly raising the PWM Frequency would be a good thing to do, assuming of course that it doesn’t reduce the torque of my motors by any noticable amount.

Motor Torque Test

I decided to give my motors a “real world” test as I don’t have access to equipment that can measure the torque value.

For my test, I placed a 10 Kg (22 lb) bag of road salt onto the test platform. For those of you unfamiliar with road salt we use it in winter climates to melt ice and provide traction. Today I’m using it to test some motors!

Motor Load Test

I placed the bag of salt onto the platform, on top of a board that itself probably adds an additional pound of weight to the platform.  I set the PWM frequency to 3 KHz and the duty cycle to 50% (half speed).

The platform had no problem moving around and the total current draw was less than the unloaded current I observed when testing the original Arduino sketch.

Obviously increasing the frequency of my PWM signal is something I’ll want to do when I build my new robot.

Changing Arduino PWM Frequency

The PWM frequency that the Arduino used was 488 Hz, at least on pin 3. Turns out that had I used a different pin I could have doubled that, they are not all the same.  But that still would be only 976 Hz, an improvement but not exactly what I want.

At a glance that seems to be about the best I could do, the Arduino doesn’t seem to have a method of altering its PWM frequency. Or does it?

Turns out that you CAN alter the frequency after all. To do so requires you to understand how that frequency is established in the first place, and that brings us to the subject of the Arduino registers and timers.

Arduino Registers and Timers

Pulse width modulation is generated in the Arduino using some internal registers in the ATmega328 chip that powers the Arduino board.

The ATmega328 chip has three PWM timers, controlling 6 PWM outputs. By manually manipulating the chip’s timer registers you can change the PWM frequency.

For a detailed explanation of this an excellent source is the Secrets of Arduino PWM article on the Arduino website.

One thing that you need to be aware of. Modifying the internal timer registers will affect several other Arduino functions, including delay, tone and servo.  So be careful if yo ualso wish to use those functions in your code.

Arduino PWM High-Frequency Sketch

I found some code that originated on the Arduino forum and that was authored by a user named “macegr”. I took that function and integrated it into the code we used earlier.


The sketch is basically identical to the last one with the addition of a function called setPwmFrequency.   This function takes two inputs:

  • The PWM pin on the Arduino
  • The divisor, the amount you want to divide the master frequency by.

In the Setup I added a call to this function, otherwise, nothing else has changed.

After changing the sketch I loaded it up to the Arduino and repeated the test. This time the frequency I obtained was 3909 Hz or 3.909 KHz!

Arduino High Frequency PWM Counter

Observing the waveform on the oscilloscope I was pleased to see that it looked almost perfect. And the “real world” test with the big bag of salt worked well, the platform had no problem moving the load around even at very low speeds.

Arduino High Frequency PWM Scope

And finally, the current draw from the power supply was very low, the lowest readings I received in all my tests.

When I build my final motor controller for my robot I will definitely be using this method!


Controlling large DC motors with pulse width modulation isn’t so hard, as long as you have the right driver and controller. The Cytron MD10C is an excellent choice for motor driver and by altering the Arduino PWM frequency we can build an efficient controller to go along with it.

I hope you enjoyed this article and found it beneficial. Please look out for my new series, Build a REAL Robot, coming up very soon!


Parts List

Here are some components that you might need to complete the experiments in this article. Please note that some of these links may be affiliate links, and the DroneBot Workshop may receive a commission on your purchases. This does not increase the cost to you and is a method of supporting this ad-free website.




Code and Library – The Two sketches and the LCD Library, all in one handy ZIP file!

Cytron MD10C Users Manual – The guide for the Cytron MD10C motor driver.

Control Large DC Gearmotors with PWM & Arduino
Control Large DC Gearmotors with PWM & Arduino
Article Name
Control Large DC Gearmotors with PWM & Arduino
Controlling large DC motors can be challenging, but it doesn't have to be. Today I will introduce you to the Cytron MD10C motor driver, an H-Bridge driver constructed with MOSFETs for improved efficiency. We will also see how raising the PWM frequency can really improve motor performance.
Publisher Name
DroneBot Workshop
Publisher Logo
Notify of

Inline Feedbacks
View all comments
5 years ago

Awesome explanations! Thank you!

5 years ago

Hi Bill,

This project comes just in time, I just started a similar project with a gearmotor but it becomes a window opener. I would like to know with PWM how far the window is open, but as a beginner it becomes a big job and all help is welcome. Afterwards I would like to automate this so that the window closes in case of storm weather, rain etc …

5 years ago

How many motor you can controller with a one Cytron MD10C?

5 years ago

Great job, really useful and clear.

5 years ago

Thank you, as always, for the great videos. Question – what is the motor (model #, brand?) you used in this video?

5 years ago

Thank you very much; I look forward to seeing the video.

On a side note – would you consider doing a video on hardware debouncing of pushbuttons?

Danny Meadows WA6MQZ
5 years ago

Hi Bill
This is a Fantastic Sight Thank You!
I am using a Home brew Dual Core win 7 Computer.
Arduino 1.8.9
I load the PWM High Freq Sketch and the First one and the LCD Locks up and have no control
of the LCD Display PWM won’t move up or down DIR 0-1 won’t move.
I go to a laptop same thing HP Pavilion win 7
any help Thank You

Danial Mahmoud
4 years ago

Great article!
I was just wondering where you got those wheels from.

4 years ago

about a “synthetic” pwm:
i have done some successful servo experiments generating a pwm signal with digital output. LOW and HIGHs digital outputs with the right delayMicroseconds holding each one. all this inside a loop.
great exercise to learn pwm and inner workings.

4 years ago

That was interesting and for a minute I was hopeful. Unfortunately IDE does not recognize setPwmFrequency(pin, value).

Corey Ped
3 years ago
Reply to  Larry

why? id very much like to use this for my work project

JR Fabretti
4 years ago

MY sketch dosent work. I have checked everything connections,code,ect
when loaded my motor runs wide open.
Dir turns it on and off
keypad entry dosent change motor speed

1 year ago
Reply to  JR Fabretti

WOW, I’m late but just fot a motor and controller and ran the program and had the same problem you had. Speed don’t work and left button turns motor on and off? Have you or anyone else got it working correctly?

3 years ago

Please can show how to connect the scope and use of
Signal Generator. Thanks. Invaluable work by yourself thanks

Scott Kraemer
3 years ago

Excellent! I had made a Dog Ball Thrower, and the noise from the motors was too loud and scary for her! Now its almost silent!

3 years ago

Think you for all intérêt informations

3 years ago

Hello sir, I am driving one dc motor by varying pwm on arduino and using driver “”, and trying to display speed and time on 16×2 lcd, every things work fine for small pwm value but as pwm increases above 150 lcd shows garbage values on it, how to solve this pls help me.

David "Adam" Ramos
3 years ago

I was looking through YouTube on ways to control dc motors that have higher current and came across your channel and the video on increasing pwm frequency. I think your content is great and I really appreciate the way you present the information. Specifically how you introduce the topic, show the instruments and recap their function, explain what we should look for, and you explain how you plan to run your experiments then do it and share the results and your experimental conclusions in a way that’s easy to understand. Very interesting and informative. Thanks for taking the time to… Read more »

3 years ago

What if you wanted to control your 12v and above motor with a joystick and a receiver is pwm still necessary

3 years ago

I’m new to Arduino and am trying to build a motor controller for my small milling machine. You channel is great, but there’s a steep learning curve that I still need to grasp before I can actually build something useful.

Mithun Banerjee
3 years ago

If I want to programme Arduino to drive Cytron MD30C with interfacing Potentiometer for speed controlling and a bi polar switch for forward and reverse direction is that possible .
I need your help for the same please guide.

3 years ago

This is some top-notch work, and very easy to navigate and replicate. Thank you

3 years ago

Thank you so much for the hard work and great explanations, so useful, peter

2 years ago

Can i use pins from rc reciever to the pwm, dir and grnd to control the driver using a rc transmitter , if not… How do i control the same motor driver with my transmitter ( motor drivers with rc control options are out of stock in my region)

Daniel Jundt
2 years ago

It won’t compile, says the LCD_KEY.h library is missing. I have been unable to find anywhere on the internet including github

1 year ago

LCD_Key library can be found here :

1) Get the code in ZIP format
2) Unzip it somewhere
3) The library LCD_Key is a subdirectory of the repository => go in “attsys” folder
4) Zip the LCD_Key folder only
5) Import your newly created zip file in Arduino IDE

1 year ago

tried to edit a mispelling and could not figure it out ? all I could is resave?

1 year ago

For those of you who have the Sainsmart top hat, some of them are misprinted? I found on mine that I couldn’t make it work. The direction button turned it off and so on. The fix is to leave the program as it is and move pins 2 and 3 up one pin. Now mine works fine. Also, programed the select button to stop the motor and the left button to jam 132 in to the speed up because my motor took too long to turn on.j 132 is almost a squar wave. So, then you can raise and lower… Read more »

Stephen Arbogast
1 year ago

This is very cool! I have an old American Flyer model railroad Baldwin switcher engine that I am converting to a dc motor. The old ac motor has burned out. You have been very helpful! Thank you.

5 months ago

Do you have any recommendations on brand for a 24V motor that is roughly the same size and specs as the one Gobilda sells? Gobilda only has 12V motors

Last edited 5 months ago by Stew
14 days ago

How can I download the post as pdf?