Marcazzan_M
Published © GPL3+

Motor Speed Control with One Transistor

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

IntermediateFull instructions provided2 hours27,830
Motor Speed Control with One Transistor

Things used in this project

Hardware components

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

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

layout_motor_speed_control_tY0ycJvpYw.fzz

Schematic

Code

Motor_Control

Arduino
//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() {

  pot_value = analogRead(A0);

  //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
  button_state = digitalRead(3);

  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;

}

Credits

Marcazzan_M

Marcazzan_M

6 projects • 67 followers
I'm an Italian student, I'm studying electronic engineering. Sufficiently advanced technology is indistinguishable from magic.

Comments