Remotely controlling a motor using Arduino, Python and PHP

IMG_6902In a previous article on this website, I taught you how to read a temperature measurement from your Arduino board, and how to display it on a server so it can be accessed remotely. In this article, I will show you the other way around: how to send commands to devices and control them remotely. And I will take a simple example: a DC motor. This is a very useful skill to acquire in the home automation world, as you want for example to automatically control curtains in your home, that are basically nothing but a larger DC motor to command. Of course, everything will be done using open-source components, and no proprietary libraries or services. Only Arduino, Python, and some HTML, PHP & JavaScript.

Hardware requirements

You need a few components in addition to an Arduino Uno board and a breadboard for this project. You first need a DC motor, with a nominal voltage close to 5V so it can be powered by the Arduino board alone. I just used a small motor that was left on my desk, and it worked just fine.

In this project, we possibly want to control the motor in both directions, because we want to control curtains up and down for example. For this reason, we cannot simply use a transistor to command the motor, as it will only allow to control the motor in one fixed direction. We will use a small integrated circuit, the L293D motor driver, and I will show you how to use it later in this article.

Software configuration

You first need the Arduino IDE to be installed on your computer. If you don’t have it already, you can find it here.

You will also need a working installation of Python on your computer, as well as the pyserial module. Finally, in terms of software, you will need a web server running on your computer. This will depend on your operating system, but I recommend MAMP for OS X, and EasyPHP for Windows. If you are using Linux, you probably don’t need my help to set up a web server on your computer :) Start the web server now, and make the localhost point to the directory of this project, we will need that later.

Hardware configuration

In this project, we need to configure to correctly wire the motor and the motor driver IC. You need to plug the L293D motor driver first, in the middle of your breadboard. You can start by connecting the power for this integrated circuit: connect pins 8 and 9 to the 5V of the Arduino board, and the pin 5 to the ground pin of the Arduino board.

Then, there are 3 inputs pin we need to connect, and 2 output pins. The output part is easy: you just need to connect the two output pins to the terminal of the DC motor. The output pins we want to use are pins 3 and 6. The first input pin to connect is pin number 1, which is called the Enable pin. This is the pin we will use to set the motor on and off, and to change the speed of the motor. Connect this pin to the pin number 6 of the Arduino board. Finally, we want to connect pins number 2 and 7 of the L293D to pins number 4 and 5 of the Arduino board. These pins will be used to change the direction of the motor.

This is the complete schematics:

dc_motor_l293_bb

Testing individual parts

We need to make sure that the L293D circuit is working correctly, before doing any remote command operation. To check that, we will do something quite simple, like making the motor accelerate and decelerate, and we will also make it changed direction. This is the sketch we will use:

The core of this sketch is the function setMotor, and we will also use it in the rest of this project, so let’s spend more time on it:

It takes two inputs, the direction and the speed. The first step consists in doing two digitalWrite() operations to set the direction of the motor: one pin of the L293D circuit will receive 5V, and the other one will be set at 0V. Finally, we use the analogWrite() command on the enable pin as we did in the last project, to change the motor speed using PWM. With this function, it is easy to command the motor in both directions. For example, to accelerate in reverse, we can just do:

Upload the sketch above to the Arduino board, and the motor should successively accelerate, decelerate, accelerate in the other direction, and decelerate in the other direction. If everything is going well at that point, you can move to the next part of this tutorial.

Putting it all together

At this point, you know how to control the DC motor from the Arduino. Let’s now put everything we know together and interface the system we designed in this part to the web. There are three different software parts we have to develop. First, we need to slightly modify the Arduino sketch so that it can receive data from the host computer. The second part will be written in Python, and will make the interface between the computer and the Arduino board, by reading and writing data using text files. Finally, we will use the HTML, PHP and Javascript languages together to have a nice web interface for the project. Do not worry; I will guide you step by step for all the new software components we are going to see.

Let’s start with the Arduino sketch. This is the sketch we will use in this part:

If you look at it, it is quite close to the sketch we used in the previous section: it also has the function setMotor() for example. However, the Serial part is new. Again, we use a serial protocol to receive messages. We will send messages to the Arduino board using the following notation:

We first check if a message is available:

If this is the case, we check if the received message starts with the header “H”:

Then, we decode the message by storing the values in an array, and assigning theses values to the correct variables of the motor:

Finally, the sketch applies the correct direction and speed to the motor:

This value will then be read by the Python script, and used by the web page. It is now time to design the second piece of this project: the Python file.

The role of this Python script will be to establish a communication with the Arduino, to send the content of a file to the Arduino with the right protocol (the file will be generated by the web interface). This is the final Python script:

Let’s walk through this script to understand it better. I already used the first part in many tutorials on this website, and it consists in creating an instance for the Arduino from the pyserial library:

The rest is new, and consists in reading from a file inside a loop that runs continuously. I will assume that we only want to drive the motor in one direction so it is easier to understand. The first part is to read the file motorCommand.txt that will contain the speed of the motor:

Then, the speed value is sent to the Arduino board, and we wait for some time so the Arduino has time to process the information:

The final part of this section consists in designing the web interface so you can remotely set the speed of the motor. This website is not about learning PHP or Javascript, but I will go through the basics. Of course, you can find all the files on the GitHub repository of this tutorial.

The HTML code creates two elements in the form: a text box where we can enter the speed, and a button to submit the form. The submit part is actually not included here, but is handled by the JavaScript part:

In the JavaScript part, the sendCommand() function links the button of the form, the value you entered in the text input, and sends it to the PHP script with the GET method.

Finally, here is the PHP part:

It is basically doing the opposite of the Python file: it gets the speed variable that you entered, and writes it to the motorCommand.txt file. Starts the remote_control.php file while having a PHP server running on your computer, and this is what you should see:

Screen Shot 2013-05-02 at 11.57.20 AM

You can just play it with by entering a speed between 0 and 255, and the motor should react accordingly. You can also play with your smartphone or tablet and connect directly to the IP of your computer, and you can then change the speed of the motor directly from your mobile device. This is a video where I explain most of the elements you’ve seen in this tutorial, and where I play with the project from my iPhone:

This is an important tutorial, because it is essential to learn how to control an actuator like a DC motor remotely. For this reason, it is really important to understand all the different parts of the tutorial and I really invite you to try it at your home with your own components. Again, you can find all the files on the GitHub repository of this project.

Finally, here is the list of the components that have been used in this tutorial:

- Arduino UNO R3 board
- Breadboard and jumper wires
- L293D motor driver
- 5V DC motor

Receive the latest news about home automation
Over 100 home automation enthusiasts already joined our list !

Do you want to receive the latest news about open-source hardware and home automation ? Then join our mailing list today by entering your name and email below. It is 100% free and you can unsubscribe at any time if you're not satisfied.

5 replies
  1. Jason
    Jason says:

    You mention that for the sake of simplicity the tutorial only has the motor going in one direction. Could you point me in the direction of how to make it reverse from the site as well?

    Reply
    • Marco Schwartz
      Marco Schwartz says:

      Hi Jason,

      To reverse the direction of the motor the easiest way would be to use a dedicated motor driver, like the L293D. You will then need to create two variables on the software side, one for speed, and one for direction.

      Reply
      • jason
        jason says:

        Yeah, I have a motor driver that can take care of that part. If I’m not mistaken, when I write arduino.write(‘H,1,’ + speed) the 1 tells the motor to go forward. Would 0 tell it to go backward? If so, I could just change it to arduino.write(‘H,’ + speed) and from the web form I could just enter 0,200 for forward at 200, and 1,200 for backward at 200.

        Reply
  2. jp²
    jp² says:

    Great stuff except there is an issue with for (int i = 100; i < 250; i++) and setMotor(true, i);
    name lookup of i changed for iso for scoping

    Reply

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">