featured

Remotely Controlling a Motor Using Arduino and PHP

In 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 Node.js & 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 to have Node.js installed on your computer, which we will use to build the interface for this project. You can download it from the official website:

http://nodejs.org

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 Node.js 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. To do so, we will use Node.js which allows to code server-side applications in Javascript. This website is not about learning Node.js or Javascript, but I will go through the basics. Of course, you can find all the files on the GitHub repository of this tutorial.

We basically need to code 3 files: the main Node.js file, the interface itself, and some Javascript to handle the clicks on the interface. Let’s start with the Node.js file. It starts by importing & configuring the Express module, which is a framework to easily create web servers with Node.js:

Then, we import the Node-aREST module, which will handle all the communications between our server & the Arduino board:

 

In this file, we also need to define on which Serial port the Arduino board is connected:

Of course, you need to change this value with your own Serial port, which you can find in your Arduino IDE under Tools>Port.

We will now look at the interface file, stored in dashboard.jade. Jade is basically a language that simplifies writing HTML code. The Jade file contains the description of the interface, which is then rendered by Node.js & Express. This is the Jade file for this project, which simply defines two buttons (for directions) & one slider (for the motor speed):

Finally, we need to add a Javascript client script to handle the clicks on the buttons & on the slider. This is the code for the ‘Forward’ button:

We can see that we set pin 4 to HIGH, and pin 5 to LOW. The other button does exactly the opposite, therefore making the motor going in the other direction.

To set the speed of the motor, we detect when the slider is released via a mouseup() event:

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 you downloaded all the interface files, and set your own Serial port in the main app.js file.

Go to this folder via a terminal, and type:

sudo npm install express jade arest

And then launch the app with:

node app.js

You can then go to your favorite web browser and type:

http://localhost:3000

You should see the interface being displayed:

interface

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 18/11/14: The tutorial has been updated to make use of the aREST framework, 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.

  • 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.