BLOG > Tutorial 5 for Arduino: Motors and Transistors

This tutorial was featured on the official Arduino blog on 3/9/2011

This week, we’ll finally be using the Arduino to control some motors!  First up, we’ll control a standard DC motor running off a 9V battery with the help of an NPN transistor and a PWM (Pulse Width Modulated) signal from the Arduino.  Next, it’s onto 180 degree servo motors, which we will power on an independent 5V rail using a voltage regulator.  We’ll control the servo using a PWM signal from the arduino, and I’ll show you how you can turn analog distance readings into precise angles for the servo to turn to!

I mention in the video that you can control DC motor direction using an H-Bridge.  If you want to wire that up, take a look through this Wikipedia article, and read through this tutorial.

If you want to learn more about analog input filtering in software, check out this example code.

The Arduino Contest has been extended!  So don’t forget to submit your project.


You can download the files associated with this episode here:

GNU GPL License Distributed under the GNU General Public (Open-Source) License.
Please Attribute and Share-Alike.


301 comments

  1. I made a small circuit with 4 motors and 2 servos and a high power battery.
    I used a NPN transistor with the motor as you showed in the video, but I didnt install a capacitor in the circuit, is it necessary for the circuit to work?
    At the moment without the capacitor the servos start vibrating and jerk as soon as I connect the battery to the circuit, I also used a voltage regulator to make a 5V line for the servos from the 9V battery.
    Thanks

      1. Is it possible to make the motor change direction (backwards or forwards) without the use of H bridge?

        1. Well you can you the L293D IC which has a H-bridge in it (easiest option) or you will have to find the means of changing the polarity of the motors for now I am not aware of any other way…but will surely let you know if i find anything.

  2. Hi Jermey, your tutorials are exceptionally educational.

    At time 2:55 in this video you show a diagram of the circuit, in it you’ve included a 1uF cap and a diode. I understand what the cap does, however I don’t understand why you put the diode in there. Why not elimintate the path the diode is creating all together?

    Thanks for your time

    1. It is important to consider issues caused by DC motors acting like inductors. (Inductors are electrical devices that store energy in their magnetic fields and resist changes in current.) As the DC motor spins, energy is built up and stored in the inductance of the motor coils. If power is instantaneously removed from the motor, the energy is dissipated in the form of an inverted voltage spike, which could prove harmful to the power supply. That’s where protection diodes come in. By putting the diode across the motor, you ensure that the current generated by the motor flows through the diode and that the reverse voltage cannot exceed the forward voltage of the diode (because diodes allow current to flow in one direction only). This will also absorb any current generated by you forcibly turning the motor.

      1. Hi Jeremy I’m Ali I need a help can you help me, I have a project to make a tower connected with an AC motor works and stops and change the rotation – go up and stop & go downd- , with ARDUINO. what I need to make it. please help me as soon as you can.
        NOTE: I’m a beginner. THANK YOU

  3. Hi Jeremy,

    Should the PWM with the transistor be able to regulate the voltage linearly? For example: if I have a 9v supply for my motor and I use the circuit described, will the motor only get 4.5v when I set the PWM to 128, and 2.8v when I set it to 80?

    I have a motor setup with an h-bridge chip and the voltage won’t go below about 7v, even when I put the PWM at 80 (I thought I would get about 3v). I measure without motors connected, but I don’t know if this matters. In your video you said the transistor allows different amounts of current flow to go across the transistor. I thought maybe I need to factor in the current somehow.

    I guess I want my h-bridge to act like a switching regulator because my motor is only rated for 3v, but as I said above the results are not what I expected.

    Thanks,
    William

    1. If your motor is only rated for 3V, then you should really step down the 9V to 3V with a regulator first. PWM is just changing the duty cycle, not the actual voltage.

    2. I would like to point out if you use a digital multimeter it will take the average voltage of the dc signal. So those readings are correct if you use a DMM because it will spend half the time at ~9V and the other at 0V giving you about 4.5V. Practice a little buy using different voltages.

      1. That’s what I expected would happen, but as I said the readings on my DMM are always higher than what the average voltage should be. Any idea what might cause this?

        1. RMS measurements will push a measured voltage for a PWM drive towards the full voltage.

          That RMS voltage represents the power equivalent as a DC voltage.

  4. Hi everybody i got a problem i have the same shematic like jeremy but when the Base input is 0=Low
    the morot doesn’t stop and when the input is raising to 5v the motor is spining faster
    also I tryed connecting the base input to ground and the motor is again spining …. any help?

  5. I wanted to control more that 16 servos on arduino mega 2560. I have read that the timer0 is utilized for delay. How do i utilize the existing arduino servo library to control the motors? Which pins i cannot use if I want to control more than 15 servos?

      1. Thanks, I have already seen the product. I just want to use the arduino directly without the use of any secondary controller.

  6. hi help me i m getting error

    int forwardPin = 7;
    int RoneaPin = 3;
    int RtwoaPin = 4;
    int RthreeaPin = 5;
    int RfouraPin = 8;
    int ir1eftPin = 6;
    int irrightPin = 12;
    int potPin = 0;
    int speedoPin=10;
    int speed=0;

    void setup()
    { pinMode(irleftPin,INPUT);
    pinMode(irightrPin,INPUT);
    pinMode(forwardPin,INPUT);
    pinMode(potPin,INPUT);
    pinMode(RoneaPin,OUTPUT);
    pinMode(RtwoaPin,OUTPUT);
    pinMode(RthreeaPin,OUTPUT);
    pinMode(RfouraPin,OUTPUT);
    pinMode(speedoPin,OUTPUT);
    }

    void loop()
    {int speed= analogRead(pot)/4;
    if (digitalRead(forwardPin==HIGH))
    {
    if((digitalRead(irleftPin==HIGH)) && (analogRead(pot)>0))
    {digitalWrite(RthreeaPin,LOW);
    digitalWrite(RfouraPin,HIGH);
    digitalWrite(RoneaPin,LOW);
    digitalWrite(RtwoaPin,LOW);
    analogWrite(speed0Pin,speed);
    }
    else if((digitalRead(irright==HIGH) && (analogRead(pot)>0))
    {digitalWrite(RoneaPin,LOW);
    digitalWrite(RtwoaPin,HIGH);
    digitalWrite(RthreeaPin,LOW);
    digitalWrite(RfouraPin,LOW);
    analogWrite(speed0Pin,speed);

    }
    else{
    digitalWrite(RthreeaPin,LOW);
    digitalWrite(RfouraPin,HIGH);
    digitalWrite(RoneaPin,LOW);
    digitalWrite(RtwoaPin,HIGH);
    analogWrite(speed0Pin,speed);
    }}

    else
    { digitalWrite(RthreeaPin,HIGH);
    digitalWrite(RfouraPin,LOW);
    digitalWrite(RoneaPin,HIGH);
    digitalWrite(RtwoaPin,LOW);
    analogWrite(speed0Pin,speed);
    }
    }
    delay(100);

    1. I suggest you have a look at L293D IC it will simplify your circuit. Connect the PWM pin to the enable pin of the IC.

  7. hi jermey,
    why is my H bridge gettin hot when i provide 12v,2A and running two motors simultaneously and using ARDUINO for controlling it

    1. Please check the amount of current required for the motor.Due to high current dissipation might take place.You could add a small heat sink to cool the IC.

      1. thanks jermey ,….but I am using l293d ic for h bridge to control 2 BO Motors please help me out …..:)

  8. Jeremy,

    Great content, thanks for helping hobbist’s on their feet. I’ve noticed alot of arduino projects power their arduino with a cord, and their motor/solenoid seperately, like in this instance.

    Is it difficult to power both the arduino and a motor from the same source? It seems like an issue that everyone avoids.

    I’ve googled power supply boards, but they only offer 5v/3v options.

    Thanks,

    Michael

  9. Hi Jeremy, why aren’t you using the 1k resistor between pin 9 and the yellow signal wire of the servo? You added the 1k resistor to the DC motor so you would not harm the Arduino. Are you not taking this precaution because the yellow wire would not harm the Arduino because it is just a signal wire (does not have current)?

  10. Hi Jeremy .Help needed please am new to electronics .I am trying to move an object along fixed rails from 0-180 degrees in small increments of about 20 degrees with stops of about 120 secs between each move using a arduino uno ,motor control shield type L293d and a RF300CA D/V motor with twin leads (no control) i have read your very informative tutorials and noticed you have a similar project using a 3 lead servo and just a arduino and a breadboard is this the only way to move a servo ? or can i get this motor do turn in small increments to drive a geared platform ?

    Would appreciate your help

    Regards Brian

    1. Yes, you can do it with no control or feedback but it will not be accurate. Since you say “about” 20degs of movement each time, you have to experiment to get what you want. You can use the PWM output. Set the PWM value to a small number at first, let’s say 20. Start with your loop time at a small number, let’s say 500mS and see how far your motor moves. Experiment.

      It will be repeatable to some degree but will vary with mechanical resistance, voltage and temperature.

      Check out this tutorial:
      You can learn about how to pulse the PWM to a motor.
      todbot.com/blog/wp-content/uploads/2006/10/arduino_spooky_projects_class3.pdf
      on page 31, “Moving a servo” he describes what you want to do.

      Don’t forget to set the direction pin on your H-bridge L293 shield.

  11. HAI JEREMY AND OTHERS .HOW TO MOVE MY BOT ACCORDING TO CORDINATES (X,Y) ALONG A PARTICULAR LINE O COLOR

  12. Hi Jeremy,
    I am using an Arduino uno and using a 9 volt external battery. I added a switch to it, so I can turn it on and off, but every time I turn it back on, I have to push the reset button on the Arduino so it start works again. Is there a way to fix that issue?

    1. If you’r also plugged in via, then the MCU will not turn off when you plug or unplug the battery. Run off the battery alone if you don’t want that to happen.

      1. I was using the via pin, but now I switched to the 5v pin. It still happens, every time I turn the Arduino power off, I have to push the reset button to the code starts working again. I would like that, when I turn the power switch from my circuit/Arduino, my motor would be ready to go. But I have to push this reset button first. Any additional input would work.

  13. Jeremy,
    You said that it is important that the ground from the Arduino and the ground from the external battery be connected together. That will make Arduino and the motor the run from the same ground level.

    Although, my external battery is a 22v battery powering a 29v motor. If I connect the ground wire from the Arduino to the 22v battery ground of the motor, wouldn’t that damage the Arduino?

  14. hello friend,
    i am making qudo copter using ardiuno. i need help from you . if you can help me……..?
    Thank you

  15. dear friend,
    I am making qudo copter using Ardiuno. i need some help from you. if you can help me…….
    Thank you

  16. Hi Jeremy

    I was trying to power a 12V motor with a scheme similar to your but it seems that when I put the 5V from Arduino Pin to BASE of TIP120 (equivalent) the EMITTER will also emit ONLY 5V. Enough to start moving the motor but not to work at full speed.

    I used DD647 (ISC 0645) as TIP120.

    Is there anything I do wrong?

  17. So you hooked up a 9V to your breadboard? How do I do this if my breadboard is just basic? Where do I hook up my 9V? My breadboard does not have the top terminals like yours.

    And can I use a 2N2222 transistor instead? Can I use any NPN?

      1. What do you mean another row? My 9V connector doesn’t have free wires – it instead has the jack that would go in the jack on the Arduino. Is that the same thing or not?

          1. I have the same issue that I have a basic breadboard ( I am new to electronics as well).
            It would help me if you post a picture of the connections for this on a basic bread board.
            Could not really grasp it from the video :( .

  18. Hello Jeremy
    I am new to electronics. I am trying to control more than 4 motors using arduino? Any suggestion?

  19. Hello Jeremy,

    Firstly, I would like to thank you for your videos on Youtube about Arduino micro-controllers, they were very helpful and easy to understand. I would like to know how many motors could be controlled independently using an Arduino Uno or Leonardo.

    Being specific, I would like to know if it was possible to control 4 motors independently (2 dc motors, 2 servo motors) using a single Arduino board (either uno or leonardo), using 4 potentiometers.

    Thanks

        1. Have you been able to control with the External Supply as Jeremy has shown, if yes, which Battery have you used ?

  20. Hi,

    How many connections to the arduino board on the motor circuit ? Is it Gnd and Pin 9 or do you connect to the 5v pin too? Also is it ok to use the BC548B transistor?

    thanks.

  21. Hi Jeremy Blum. I see you are a great ingeener and an intelligent man. I am seventeen and me and my friend ( a beautifull french too ) we must realize this project for the high school but we are more difficult :
    In first, we don’t have the materials and we need many thing of the list but it’s difficult for to have this.
    In second, we have more difficulties of inderstand the goal of this project number 5.

    We are sorry for the comprehension but we are french and we have a lot of difficult for to speak english :(
    we are not good for languages but for to work in the energy we are the best :D
    thank you for your website

  22. Hi, Jeremy any Idea how Easton Powered 5 Servo with the Arduino +5v only. He has not mentioned any where about the External Power Source ?

    Secondly, which battery can I use if I go with 4 X AA Battery Setup. Please send me the exact link of the Product. My Duracell Copper Top is making the Servo Going Crazy. As there is variation with Alkaline, Lithium, etc.

  23. how can i add a library to arduino, i dont get any temp change even when i heat up the sensor. i am using ds1820.
    {
    Serial.begin(9600);
    }
    void loop()
    {
    int reading = analogRead(sensorPin);
    float voltage = reading * (5.0 / 1024);
    float temperatureC = (voltage* 10)+23;
    Serial.print(temperatureC); Serial.print(” degrees C, “);
    Serial.print(voltage); Serial.println(” volts”);
    delay(1000);
    }

  24. Hey Jeremy. I’m trying to make an arduino powered device with your DC Motor circuit and your push switch circuit, on which the motor accelerates to full throttle when the momentary switch is pressed and slowly decelerates to zero when you release the switch. Can you tell me how I’d program that kind of device?

  25. Hi Jeremy, First of all a big thanks for such wonderful tutorials. Well I have a question w.r.t this tutorial.
    I followed the exact same circuit and didnot even change the code but my DC motor hardly rotates. I can hear a sound which means there is some movement within the motor but it looks like the dc motor needs more power. When I hook up the motor to the battery directly it goes with full power. Do you know what did I do wrong ? I tried changing the 1K to 220ohms but no big difference. Any of you here if you know pls help me.

  26. Yes, I am sure both the GND are connected. BTW the Arduino GND is the “GND” pin just below the “5V” pin. I think that is the right pin and not the “GND” pin above the “Vin” pin. Please correct me if I am wrong. Also, How much current should it flow through the motor ? I am seeing around 100mA on my multimeter.

  27. Hi jeremy, I want to drive a 12v 5 wire motor with 3 speed levels. Please help me with the parts required and the circuit diiagram. I am a beginner, please don’t ignore. Thank you

      1. I just found out that I did one thing different. My external battery supply is 5v and not 9v. would that be an issue ?

        1. You still haven’t said what kind of motor it is. That is important.

          IF YOU ARE USING A DC MOTOR:
          If you are putting it through a regulator, yes. The supply voltage needs to be greater than the output voltage plus the dropout voltage of the regulator. Just connect the battery directly to the power for the motor. Keep in mind, though, that as the battery discharges, the motor will move slower. That would not be the case if you used a 9V with a regulator.

  28. Can we use any servo motor for the tutorial? The one used by the instructor is SG-5010 standard servo. Is it necessary to use the same or any other will do?

  29. Hi Jeremy, i’m trying to control the speed of a coin vibration motor with a 2-3.6V operating range, i have a DC supply of 6V to the arduino uno board, so is it recommended to use the same power supply and step down to operate the motor? or should i use a different power supply of 3V?

  30. Hi Jeremy,
    After I watched your videos I built a electric longboard that uses an arduino UNO, wii nunchuck, and an esc. The motor is running now when I upload the code. Although, if the wii remote’s battery ends, the esc reads the last value that the remote was sending to the arduino. Result, my motor accelerates without stop. Do you know how to fix this issue?

    1. This is the code:

      #include // Library for reading data from Wii Nunchuck
      #include // Library for I2C communication
      #include // Library for controlling Servo or ESC

      WiiChuck chuck = WiiChuck();
      Servo myservo;

      int speed_val; // Speed value
      int speed_val_cur = 90; // Current speed value
      int y = 0; // Joystick value
      int time = 200; // Delay timer
      int speed_val_hold; // speed value for the throttle hold feature

      //led pin
      int ledPin = 13;

      //Lost connection variables
      int DuplicateCounter=0;
      int Previoussm=0;
      int DupplicateLimit=40;

      // Setup. This runs at startup, and initializes the nunchuck
      void setup() {

      //Serial.begin(115200); // Begin serial communication with baud rate at 115200. For debugging
      Serial.begin(9600); // Begin serial communication with baud rate at 115200. For debugging
      chuck.begin(); // Initialize nunchuck. This function is located in the WiiChuck.h library
      chuck.update(); // Read nunchuck. This function is located in the WiiChuck.h library
      myservo.attach(9); // ESC attached to 9 pin of Arduino

      //Set up LED
      pinMode(ledPin, OUTPUT);

      // Print to serial monitor. This tells us that the setup ran once. Again, for debugging
      //Serial.println();
      //Serial.print(“Initialization Sequence Complete”);
      //Serial.println();
      delay(1000);
      }

      // Main loop. This is what actually does stuff. The rest of the sketch is inside this
      void loop() {

      //int plusminus = 0;

      if (chuck.buttonC == 1)
      {
      digitalWrite(ledPin, HIGH);
      digitalWrite(ledPin, LOW);
      }

      //Check if Z or C button is pressed
      if ((chuck.buttonZ)||(chuck.buttonC)) {

      // If you hold down Z, the throttle hold is enabled and speed adjustments occur slowly (think cruise control buttons in a car)
      if (chuck.buttonZ) {
      Serial.println(“z”);
      time = 50;
      }

      /*
      // If you press C, something will happen — NOTE: This feature is not yet implimented, so nothing will really happen
      if (chuck.buttonC) {
      do stuff
      }
      */
      }

      // If no buttons are pressed, throttle response is set to maximum (think throttle/brake pedels in a car)
      else {
      time = 5;
      }

      // Delay for the time amount specified above. This determines how fast the throttle will react to input
      delay(time);

      // Request updated data from the nunchuck, and assign the Y axis position to variable y
      chuck.update();
      y = chuck.readJoyY();

      // Map the joystick value onto the speed value (joystick at 0 = speed at 90. This is neutral throttle)
      speed_val = map(y, -128, 125, 30, 150);

      // If the connection is lost, set all speeds to 90. Remember, speed = 90 is neutral. IE. the motor is stopped.
      if ((y > 125) || (y < -129)) {
      speed_val = 90;
      speed_val_cur = 90;
      speed_val_hold = 90;
      setup();
      }

      if (chuck.buttonZ) { // If Z is pressed (throttle hold on):

      if ((speed_val_hold 5)) {

      speed_val_hold++; // If hold button is pressed and throttle stick moved up – increase speed
      }
      if ((speed_val_hold > speed_val) // Check if we are trying to decellerate:
      && (y < -5)) {

      speed_val_hold–; // If hold button is pressed and throttle stick moved down – decrease speed
      }
      speed_val_cur = speed_val_hold;
      }

      else { // If Z is not pressed (throttle hold off):

      if (speed_val_cur speed_val) { // Check if we are trying to decellerate:
      speed_val_cur–; // If hold button is NOT pressed and throttle stick moved down – decrease speed
      }
      speed_val_hold = speed_val_cur;
      }

      // Write current speed value to the ESC
      myservo.write(speed_val_cur);

      //Print important variables to serial monitor. For debugging purposes.
      //Serial.println();

      //Serial.print(“Joy = “);
      //Serial.println(y, DEC);

      //Serial.print(” speed_val = “);
      //Serial.println(speed_val);

      //Serial.print(” speed_hold = “);
      //Serial.println(speed_val_hold);

      //Serial.print(” Speed = “);
      //Serial.println(chuck.buttonZ);
      Serial.println(speed_val_cur);

      /*
      //Handle loss of signal
      if (speed_val_cur == Previoussm && Previoussm !=90 && Previoussm !=150)
      {
      Serial.print(“Dupplicate value “);
      Serial.println(DuplicateCounter);

      DuplicateCounter++;
      if (DuplicateCounter > DupplicateLimit)
      {
      Serial.println(“Reducing Speed…”);
      //digitalWrite(resetPin, LOW);
      speed_val_cur = 100;
      while (speed_val_cur !=89)
      {
      Serial.println(speed_val_cur, DEC);
      Serial.print(‘ ‘);
      //Serial.print(Previoussm);
      myservo.write(speed_val_cur);
      delay(50);
      speed_val_cur–;
      }
      delay(8000);
      }

      }
      else
      {
      DuplicateCounter = 0;
      }
      */

      }

  31. You are the best…. Make it so simple that an old guy like me understand it 100% immediately.

    Thanks so much.

  32. Hi Jeremy,
    I am doing an Arduino project where am using a L293d driver for dc motor , IR sensor and switch. The working is , as soon as the switch is pressed the motor should start rotating and when it senses the sensor the motor should stop. But i dont understand what went wrong in my program code. Can you help me what”s wrong in my program.

    //
    void loop()
    {
    if(digitalRead(switch)==HIGH)
    {
    motorstart();
    if(analogRead(sense)==LOW)
    {
    motorstop();
    }
    }
    void motorstart()
    {
    digitalWrite(m1,HIGH);
    digitalWrite(m2,LOW);
    }
    void motorstop()
    {
    digitalWrite(m1,LOW);
    digitalWrite(m2,LOW);
    }

    1. if(analogRead(sense)==LOW)

      when u read an analog signal, values are stored as numbers and not 0’s and 1’s.

      may b u should use if (digitalRead(sense) == low).

      when ever u use a pushbutton. use debounce function for proper functioning.

      boolean debounce(boolean last)
      {
      boolean current = digitalRead(switchpin);
      if(last != current)
      {
      delay(5);
      current = digitalRead(switchpin);
      }
      return current;
      }

      void loop()
      {
      currentbutton = debounce(lastbutton); // variable to stored pushbutton values.
      }

  33. hii jer..i am trying to change the polarity of a 12v dc motor connected to the gripper of a robotic arm but its not changing.can u pls provide me a schematic ..it would be a great help.
    waiting..my projct submmsn is the day after tomorrow..rply asap plsss.

  34. Excellent tutorials! For more than a year I have watched them to broaden my understanding and knowledge in electronics. I am working toward my bachelors in electronics and I have developed a passion for micro-controllers and programming. My last creation was a science fiction “scanner” prop for Tech Fest at ITT. Next I am going to try and make something useful, a remote controlled robot with sensors and some automated interrupts. Would you recommend a geared motor dealer?

  35. while we are using PWM pin , how we can use command (analogwrite)?
    we have not connect it to analog pin for that.
    can i use (digitalWrite) insted of (analogWrite)??

  36. Hi Jeremy,

    I am new to Arduino and love your videos.

    One question, the SCH schematic file won’t open. Says it not valid. I do have PBExpress. Can you send me a new file or convert it to another format?

    Thanks
    Ralph

  37. wat happens at the two terminals of motor??? one terminal get 9v and how much volt does the other terminal get. the motor rotates only when there s a potential drop across it. so does the other terminal decreases its voltage to ground in order for speed control ??

    1. I am not Jeremy Blum but he will probably answer also.

      You have to use the following:

      #include

      //Creating servo objects
      ServoTimer2 servo1;
      ServoTimer2 servo2;

      I believe up 9 Servos

      If you need more info post question

    1. if u use two separate grounds then the polarity gets changed. ex if u use 5v and grd in arduino and external 12v and grd in separate then the 12v supply wil become -12v supply.

Leave a Reply to Matija Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Advertisement