Remotely Controlling a Motor Using Arduino and Node.js

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:


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:

// Define motor pins
int motorPinPlus = 4;
int motorPinMinus = 5;
int motorPinEnable = 6;

void setup()
{
   pinMode(motorPinPlus, OUTPUT);
   pinMode(motorPinMinus, OUTPUT);
   pinMode(motorPinEnable, OUTPUT);
   Serial.begin(9600);
}

void loop()
{
  
   // Define speed
   int motor_speed;

   // Accelerate forward
   for (motor_speed = 0; motor_speed < 250; motor_speed++)
   {
      setMotor(true, motor_speed);
      delay(10);
   }
}

// Function to control the motor
void setMotor(boolean forward, int motor_speed)
{
   digitalWrite(motorPinPlus, forward);
   digitalWrite(motorPinMinus, !forward);
   analogWrite(motorPinEnable, motor_speed);
}

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:

// Function to control the motor
void setMotor(boolean forward, int motor_speed){
   digitalWrite(motorPinPlus, forward);
   digitalWrite(motorPinMinus, !forward);
   analogWrite(motorPinEnable, motor_speed);
}

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:

// Accelerate forward
for (motor_speed = 0; motor_speed < 250; motor_speed++)
{
  setMotor(true, motor_speed);
  delay(10);
}

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:

// Libraries
#include 

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:

/analog/6/200

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:

// Module
var express = require('express');
var app = express();

// Define port
var port = 3000;

// View engine
app.set('view engine', 'jade');

// Set public folder
app.use(express.static(__dirname + '/public'));

// Serve interface
app.get('/', function(req, res){
  res.render('dashboard');
});

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

var rest = require("arest")(app);

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

rest.addDevice('serial','/dev/tty.usbmodem1a12121',115200);

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):

h1 Motor Control
.row.voffset
  .col-md-4
    button.btn.btn-block.btn-lg.btn-primary#1 Forward
  .col-md-4
    button.btn.btn-block.btn-lg.btn-danger#2 Reverse
  .col-md-4
    input(type='range',min='0',max='255',value='0',id='motorspeed')

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:

$("#1").click(function() {
  $.get('/motor_control/digital/4/1', function() {
    $.get('/motor_control/digital/5/0');
  });
});

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:

$("#motorspeed").mouseup(function(){

  // Get speed
  speed = $("#motorspeed").val(); 
    
  // Send command
  $.get("/motor_control/analog/6/" + speed);  

});

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:

And then launch the app with:

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

You should see the interface being displayed:


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.