Remotely Controlling a Motor Using Arduino 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 well known technologies like Arduino and some HTML, PHP & JavaScript.

Hardware & Software 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. This is the list of all the required components:

On the software side, you first need the Arduino IDE to be installed on your computer. If you don’t have it already, you can find it here. To control the motor directly from a webpage like we are going to do at the end of the tutorial, you’ll also need the aREST library. To install a library, just download the required folder, and put it into your /Arduino/libraries/ folder. You will also 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 & start again continuously. 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, we can just do:

Upload the sketch above to the Arduino board, and the motor should successively accelerate and then start again from zero at some point. 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. Then, 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, you can see that is this quite different from the previous section: it has the same part to initialise the motor pins, but it relies on the aREST instance to receive commands. For example, to set a given motor speed, we will make a call from the computer like:

We will make similar calls from the computer interface to control the other motor pins, for example the direction. If you want to learn more about this REST API for Arduino, I invite you to read the corresponding article. 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 three elements in the form: two buttons to set the direction of the motor, and one slider to set the speed. This is done with this piece of HTML:

Note that I included some CSS to the project so the interface looks better. Now, the JavaScript. The goal here is to link the buttons to the two motor pins that control the direction of the motor. Remember, to set pin number 4 to 1 for example, we just need to send the command /digital/4/1. This is the JavaScript code for the buttons:

Then, to set the speed, we first get the value from the slider, and then send it to the Arduino board via an analogWrite command:

You can see that all these functions are calling a PHP file called serial.php, which is actually responsible of sending the commands to the board. We won’t see the details of this file, but you will just need to change the Serial port inside this file:

Note that you can find the value of your Serial port in the Arduino IDE. We can now test the project. Of course, you can find all the files on the GitHub repository of this tutorial. First upload the remote_motor sketch to the Arduino board. Then, make sure all the files are located on your web server, and access this folder by typing localhost in your web browser. Go to the folder, and open the interface.html file. This is what you should see:

Screen Shot 2014-05-06 at 07.09.51

You can just play it with by first setting a direction, and then using the slider to change the speed. 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.

Hot to Go Further

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. You can also modify the code to add more complex behaviour to your motor. For example, you can modify the interface to introduce a delay between the moment you change the motor direction and the moment the motor actually changes direction. Update 06/05/14: The tutorial has been updated to make use of the aREST library, which implements a REST API for Arduino. It greatly simplified the code to control the motor from the web page. For example, it completely removed the need of an intermediate language (Python) and the need to store data in text files.

Receive the latest news about home automation
Over 1000 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.

  • Jason

    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?

    • http://www.marcoschwartz.com Marco Schwartz

      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.

      • jason

        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.

  • jp²

    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

  • http://www.intorobotics.com/controlling-arduino-board-php-web-based-script-tutorials/ Ezu

    very good tutorials that help me to find what I need to build a web based application and control sensors from internet

  • calvin

    Great tutorial Marco,i have tried the project out and it works just fine,but i am finding it difficult to make adjustments on the code so that the motor could run in the forward direction for some specified amount of time after which it changes direction……also for some specified amount of time.So any form of help would be much appreciated,thank you in advance.

    • http://www.marcoschwartz.com Marco Schwartz

      Hello Calvin, to include time into the project you can use time functions inside PHP. For example look at: http://www.php.net//manual/fr/function.time.php

      • calvin

        Thank you Marco,i will do all the possible adjustments and keep you informed on how it all goes.

  • Akhil George

    Hi Marco,
    I was really in search of this kind of web based device control. Finally, I got it from here!
    Your explanations are really helping. KUDOS !

  • David Issac

    <Hi Marco,
    thanks for the great tutorial in advanced but when i'm trying to compile and upload the sketches shows those errors
    remote_motor:8: error: 'aREST' does not name a type
    remote_motor.ino: In function 'void setup()':
    remote_motor:24: error: 'rest' was not declared in this scope
    remote_motor.ino: In function 'void loop()':
    remote_motor:31: error: 'rest' was not declared in this scope

    i'm using and includes
    https://github.com/marcoschwartz/aREST.git & https://codeload.github.com/adafruit/Adafruit_CC3000_Library/zip/master

    • http://www.marcoschwartz.com Marco Schwartz

      Hello David, thanks for your comment. I just tested the code again and it seems to work fine. I also simplified it so you just need the aREST library and nothing else. Make sure to update the code & the aREST library to their latest version and it should work fine. Also make sure to place the aREST library in your /libraries folder & to restart the Arduino IDE.

  • arnaldo

    Hi Marco,
    Thanks for your tutorial.
    I have a problem…while the motor test works fine the web interface doesn’t work for me….
    It seems like the java scripts do not run….all the files are in the right place /var/www but the buttons on the interface.html file do not work at all…
    is it an Apache problem?
    can you please help?
    thanks a lot.
    best
    arnaldo

    • http://www.marcoschwartz.com Marco Schwartz

      It seems like an Apache problem indeed. Check that you modified the files with your serial port, and also make sure that you are opening the interface using the localhost path in your web browser.

  • Franco

    hi, Marco,
    .. and, if i would like to use a single slider (without botton) with a “0” on center and “foward” all right and “backward” all left?
    What can i do?

    thanks for your answer
    Franco

    • http://www.marcoschwartz.com Marco Schwartz

      Hello Franco, I think this is possible, it is basically a question of the design of the slider (you need to go from negative values to positive values). Then, you need to write a function that takes this value and converts to the corresponding motor command.