Project tutorial

# Motor Speed Control with One Transistor © GPL3+

I will show you how control a motor's speed with one transistor and a personal PWM signal.

• 145 views
• 5 respects

## Components and supplies

 Elegoo Starter Kit
×1
 Arduino UNO & Genuino UNO
×1
×1
 DC motor (generic)
×1
 General Purpose Transistor NPN
×1
 Rotary potentiometer (generic)
×1
 1N4007 – High Voltage, High Current Rated Diode
×1
 Resistor 1k ohm
×2
 Resistor 221 ohm
×2
 SparkFun Pushbutton switch 12mm
×1
 LED (generic)
×2
 Capacitor 100 µF
×1

## Apps and online services

 Arduino IDE

### BASICS:

If you need to control the speed of a DC motor the easiest way to do it is using a transistor.

This is possible thanks to the PWM.

The PWM (Pulse-Width Modulation ) is a signal with a variable duty cycle.

If we use this signal and a transistor we can control the speed of a motor.

Consider this schematic:

In this case the inductor represent the motor. Thanks to the PWM signal DC Motor doesn't feel 12V but the voltage that it feels is proportional to the PWM.

In particular the voltage depends on the duty cycle (δ).

The duty cycle is this:

So it is a number for 0 to 1. But it is often expressed as a per cent so it goes from 0% to 100%.

In the first it is from 0 to 1.

For example with a δ = 0.5 (50%) and Vmax = 12V we have 6V around the motor.

But if δ = 1 (100%) we have 12V around the motor, but δ = 1 means that the signal is always high so it is direct current and we have the maximum power.

### HOW DO IT!

• Hardware

The hardware doesn't need a lot of components. There are:

• 1 Transistor: For a better result it should be an high speed switch transistor (2n2222)
• 1 Diode (D1) in this case is necessary because we use a motor and it is a sort of inductor. In fact when we control an inductor with a square wave the inductor can create some high voltage spikes which can destroy the transistor. The diode removes these spikes.
• 1 Base resistor for the transistor. In this case I use 1KΩ but near values ​​are also good.
• SOFTWARE

In this case we can use the PWM signal of the Arduino but it has got a frequency around 1kHz, so it is better use an higher frequency.

I will use the Internal Timer to make my personal PWM signal.

If you want to know more about Timer watch my project: Internal Timer.

I create a 5kHz PWM from Arduino thank to TIMER0.

`````` TCCR0A = (1 << WGM01); //Set the CTC mode
OCR0A = 0x04;          //Value for ORC0A for 2us
TIMSK0 |= (1 << OCIE0A); //Set the interrupt request
sei(); //Enable interrupt
TCCR0B |= (1 << CS01); //Set the prescale 1/8 clock
TCCR0B |= (0 << CS00);  //Now timer is on
``````

After that I create an ISR ( Interrupt Request Service ) every 2μs.

``````ISR(TIMER0_COMPA_vect) {   //This is the interrupt request
timer++;    //+1 every 2 us
if (timer <= (percent * 2))    // The duty cycle depends on the value
// of "percent" which represent the per cent
// of duty cylce that we have requested
digitalWrite(13, HIGH);
else
digitalWrite(13, LOW);
if (timer >= 200) timer = 0;    //Every 200us reset the timer value
}
``````

There will be an external potentiometer which one we can control the value of the duty cycle.

After that we need also a push button to control the state.

In the Elegoo's kit I found a joystic with a push button and two potentiometer so I will use it.

### NOW THERE IS A PROBLEM!

Now the software must do the counts with the reality.

So there are two important restrictions:

• we can't use the complete range of PWM but from 100% to 30% because under 30% the motor will stop.(This depends on the type of motor)
• we must create a function which start the motor without the PWM. For example for 1s the motor run at the highest speed after that we can control it with PWM. That's because we can't think to start the motor with a PWM of 30%, for example.

For these reasons I take out the code from ISR and I control the PWM in the loop() function.

In the ISR I left only timer++.

Complete code below.

This is the final result.

## Code

##### Motor_ControlArduino
```//Control motor with PWM

#define MOTOR 13
#define LED_ON 5
#define LED_OFF 4

//Button variables
int button_state = 0;
int last_button_state = 1;

//State of motor
bool motor_state = false; //->0 Motor off -> 1 Motor ON
double cont = 0;

//frequency of PWM: 5kHz
int timer = 0;

//Other variables
int percent = 0;
int pot_value = 0;

//start variables
bool start = false;

void setup() {
pinMode(MOTOR, OUTPUT);
digitalWrite(MOTOR, LOW);
pinMode(LED_ON, OUTPUT);
pinMode(LED_OFF, OUTPUT);
pinMode(3, INPUT);

//**SET TIMER0**
TCCR0A=(1<<WGM01);        //Set the CTC mode
OCR0A = 0x04;             //Value for ORC0A for 2us

TIMSK0 |= (1 << OCIE0A);  //Set the interrupt request
TCCR0B |= (1 << CS01) | (0 << CS00);    //Set the prescale 1/8 clock
//Now timer is on

//**SET TIMER0**

digitalWrite(LED_OFF, HIGH);
digitalWrite(LED_ON, LOW);
}

void loop() {

//The value doesn't start from 0 to 100, but from 30 to 100 because with a duty cycle < 30% the motor can't turn
percent = map(pot_value, 0, 1024, 30, 100);

//**This routine controls if the state of the push button is changes

if (button_state == LOW && last_button_state == HIGH) {
motor_state = !motor_state;
}
last_button_state = button_state;
//**

if (motor_state == true ) {
//**PWM**
if (start == false)
{
//I must starting the engine once
digitalWrite(LED_ON, HIGH);
digitalWrite(LED_OFF, LOW);
digitalWrite(13, HIGH);
//cont is in the ISR() routine so it is like timer variable
if (cont > 40000) {
start = true;
cont = 0;
}

}
else {
//THIS CREATES A VARAIBLE PWM
if (timer <= (percent * 2))
digitalWrite(13, HIGH);
else
digitalWrite(13, LOW);
}
//**PWM**
}

//if motor_state==false motor is OFF so 13 must be LOW
else {
digitalWrite(13, LOW);
digitalWrite(LED_ON, LOW);
digitalWrite(LED_OFF, HIGH);
start = false;
}
}

//This routine control the pwm but the sum of high time and low time must be ALWAYS 200us -> 5kHz
ISR(TIMER0_COMPA_vect) {   //This is the interrupt request

timer++;
if (start == false && motor_state == true)cont++;

//After 200us ( timer == 200) -> timer = 0
if (timer >= 200) timer = 0;

}
```

## Schematics

layout_motor_speed_control_tY0ycJvpYw.fzz

• 6 projects
• 20 followers

December 8, 2018

#### Members who respect this project

and 2 others

See similar projects
you might like

#### Control Speed and Direction of Motor

Project in progress by ahmed soliman

• 14,359 views
• 20 respects

#### Control the Speed of Brushless DC Motor Using Bluetooth

Project tutorial by mohitmehlawat

• 3,487 views
• 13 respects

by Jasleen

• 7,832 views
• 10 respects

#### Servo Control Panel

Project tutorial by dancili

• 1,202 views
• 6 respects

#### Arduino - Motor PID Speed Control

Project tutorial by whitebank

• 37,432 views