Introduction: Motorize IoT With ESP8266

Picture of Motorize IoT With ESP8266

IoT is the big buzz these days and it can mean just about anything. For me IoT means that cheap off-the shelf components can enable me to affordably make, monitor and control just about anythything I can imagine.

Despite IoT in the heading, this is not about how to connect the ESP8266 to the internet. There are plenty of other tutorials about that and I will share my own example in the second instructable in this series. This instructable is about how to use the ESP8266 based NodeMCU prototype board with a motor control board to control two types of motors. This is the first instructable in a series of two. This first one will focus on how to get the motors spinning. See it as a technology demo rather than a finished project. The second one will be an example of an actual project that you can do. ESPs can also contol RC servos but there is no particular reason to use this board combo for that. You can hook servos up to any ESP board so long as you don't power the servo from the board.

Covered in this instructable:

  • DC motor control. The motor board supports the use of two DC motors with individual speed and direction control. Speed is controlled through pulse width modulation (PWM) and direction is controlled pulling a powered pin high or low, effectively reversing the PWM polarity.
  • Stepper motor control. The board supports one stepper motor. ESP8266 boards can control steppers with other boards that sometimes ship in bundles with the motors. However, with those boards you have a lot more loose wires. Personally I prefer this shield since everything is in one piece.

Why not use Arduino?

Arduino's have a lot of advantages in that they come in a limited number of pinouts thus allowing manufacturers to make all kinds of snap-on shields and addons for everything under the sun. The ESP boards have less addons and are not as robust but they have other features which make them very powerful for IoT projects. Among other things, the ESP-boards feature itegrated WiFi, more memory (than most Ardu's) and a more powerful CPU.

Update: Please read part two which includes a practical example

Step 1: Items Used

For this instructable I used the following items from Gearbest:

A word of warning. Make sure you get NodeMCU 1.0. Gearbest also sell NodeMCU 0.9 (aka v1). It won't fit in the motor shield (I have first hand experience).

Step 2: The Motor Shield

Picture of The Motor Shield

The featured motor shield is manufactured by Shenzhen Doctors of Intelligence & Technology (I like the name). Whilst the board is pretty solid and well though out I find that that the documentation is lacking. The board is often sold bundled in a WiFi robo car kit for which software is available. That software is what I used instead of documentation. However, I couldn't find anything about using the driver with with stepper motors. Hopefully this instructable will shed some light on the matter.

Motor Shield documentation

WiFi Robo Car source

In essence, the motor shield features:

  1. Four powered outputs controlled by NodeMCU IO 1, 2, 3 and 4
  2. Optional dual voltage for motors and NodeMCU
  3. Convenience breakout for all relevant pins

The motor power pins are labeled as A-, A+, B- and B+. The nodemcu and Arduino GPIO is not mapped the same. If you try to use the D1 pin as io-pin 1 in Arduino IDE it will not work. In Arduino You will have to use D1 (which is an alias to 5 or just 5. The pins are mapped like this:

Board pin |NodeMCU GPIO |Arduino IDE
A-15 or D1
A+30 or D3
B-24 or D2
B+42 or D4

Step 3: The ESP-12E (NodeMCU)

Picture of The ESP-12E (NodeMCU)

The NodeMCU 1.0 (aka v2) is a very nice board to work with. Other ESP8266 boards that I have worked with require 3.3v and also need special wiring for flashing. The NodeMCU has an on-board 3.3v voltage regulator so it can be powered from the same microusb-cable that is used to program it. It also has on-board buttons for flash-mode and reset.

NodeMCU boards can be delivered with different firmwares. For this Instructable I choose to use the NodeMCU Lua firmware. You can achieve the same thing with the Arduino IDE. It could be useful to know that even though the Lua firmware was developed for the NodeMCU board it can be used with any ESP board. Lua is a scripting language and is powerful and featurefull. The NodeMCU Lua environment also features a file system. There are plenty of modules in the firmware but you may situations when you have to resort to the Arduino IDE just to take advantage of some specific Library.

Let's assume you got a board without Lua firmware:

  1. Download ESP8266flasher here
  2. Download Lua firmware here. Alternatively you can cook you own here.
  3. Unpack the binary and flash the fimware with ESP8266flasher. Hold the flash button then reset to put the device in flash mode. If you run into trouble, more info can be found on the previous links.
  4. Download and install NodeMCU Lua IDE ESPlorer from here

Firmware and modules documentation is found here.

General Lua language documentation is found on

Step 4: Driving DC Motors

Picture of Driving DC Motors

The A+ pin (D1) controls the PWM out for the first DC motor and the A- (D3) pin controls direction. The PWM-out drives the motor and allow fors speed control. For instance, a 50% duty cycle in effect creates a lower out voltage. It has nothing to do with pulse count. The A- direction control simply goes low or high, effectively reversing voltage and as such the spin direction of the motor. Please note that you can drive the motors with separate power (usually higher voltage) by connecting motor power to VM and NodeMCU power to VIN. Important note: If you use two power sources, remove the jumper which connects VM and VIN.

To try it, do this:

  1. Connect the (-) (usually black) lead from the motor to A-
  2. Connect the (+) (usually red) lead from the motor to A+
  3. Attach motor B in the same way
  4. Using ESPlorer, upload init.lua (below)

After the upload, reset and watch the motors turn, reverse and stop. To repeat, press reset again. Obviusly this particular behaviour is not very useful other than for demo purposes. The motors should be controlled over wifi but that is for part two of this instructable. After loading/running the file you can control the motors from the ESPlorer command linte with calls to the motor functions, e. g.

> motor_a(FWD, 100)

--motordrive: init.lua
pin_a_speed = 1
pin_a_dir = 3
pin_b_speed = 2
pin_b_dir = 4
FWD = gpio.HIGH
REV = gpio.LOW
duty = 1023
--initiate motor A
pwm.setup(pin_a_speed,1000,duty) --PWM 1KHz, Duty 1023
--initiate motor B
pwm.setup(pin_b_speed,1000,duty) --PWM 1KHz, Duty 1023
-- speed is 0 - 100
function motor(pin_speed, pin_dir, dir, speed)
    pwm.setduty(pin_speed, (speed * duty) / 100)
function motor_a(dir, speed)
    motor(pin_a_speed, pin_a_dir, dir, speed)
function motor_b(dir, speed)
    motor(pin_b_speed, pin_b_dir, dir, speed)
--start motors 100% speed forward
motor_a(FWD, 100)
motor_b(FWD, 100)
--reverse motors after 4s
tmr.register(0, 4000, tmr.ALARM_SINGLE, function() 
    motor_a(REV, 100)
    motor_b(REV, 100)
--turn motors off after 8s
tmr.register(1, 8000, tmr.ALARM_SINGLE, function() 
    motor_a(FWD, 0)
    motor_b(FWD, 0)

Step 5: Driving Stepper Motors

Picture of Driving Stepper Motors

For the this demo, I have used a standard unipolar (5 wires) 28BYJ-48 geared stepper motor. Read more about steppers here.

  1. Attach the wires
    1. Blue -> A-
    2. Pink -> A+
    3. Yellow -> B-
    4. Orange -> B+
    5. Red -> VM
  2. Using ESPlorer, upload init.lua and stepper.lua

After the upload, reset and watch the motor turn half a revolution (2048 steps), reverse and stop. To repeat, press reset again. As for the DC motors the stepper motor should be controlled over wifi for most projects. You can run the stepper from the command line with the step_move function.


ROTATION_FULL=4096 --One revolution, 28BYJ-48 geared stepper motor
tmr.register(0, 5000, tmr.ALARM_SINGLE, function() 

stepper.lua (credits to: wakenils

-- stepper.lua<br>-- code from:
-- simple stepper driver for controlling a stepper motor with a
-- l293d driver
-- nodemcu pins:  0  5  6  7
stepper_pins = {1,3,2,4} -- (A-)blue, (A+)pink, (B-)yellow, (B+)orange
-- half or full stepping
step_states4 = {
step_states8 = {
step_states = step_states8 -- choose stepping mode
step_numstates = 8 -- change to match number of rows in step_states
step_delay = 20 -- choose speed
step_state = 0 -- updated by step_take-function
step_direction = 1 -- choose step direction -1, 1
step_stepsleft = 0 -- number of steps to move, will de decremented
step_timerid = 4 -- which timer to use for the steps
-- setup pins
for i = 1, 4, 1 do
-- turn off all pins to let motor rest
function step_stopstate() 
  for i = 1, 4, 1 do
    gpio.write(stepper_pins[i], 0)
-- make stepper take one step
function step_take()
  -- jump to the next state in the direction, wrap
  step_state = step_state + step_direction
  if step_state > step_numstates then
    step_state = 1;
  elseif step_state < 1 then
    step_state = step_numstates
  -- write the current state to the pins
  for i = 1, 4, 1 do
    gpio.write(stepper_pins[i], step_states[step_state][i])
  -- might take another step after step_delay
  step_stepsleft = step_stepsleft-1
  if step_stepsleft > 0 then
    tmr.alarm(step_timerid, step_delay, 0, step_take )
-- public method to start moving number of 'int steps' in 'int direction'
function step_move(steps, direction, delay)
  step_stepsleft = steps
  step_direction = direction
  step_delay = delay
-- public method to cancel moving
function step_stop()
  step_stepsleft = 0

Step 6: Conclusions

It took some time to figure out how to use the motor drive board with the NodeMCU. The documentation is really bad. However, now that I know how to use the combo I will definitely use it for more project. Hopefully the information shared in this instructable will help others to get started too. I really like the Arduino-like plug-in shield combo. I hope more manufacturers start making shields for NodeMCU.


Attila_FIN made it! (author)2017-03-17

I wonder if that board really works for someone. Quality can be already seen from the typos on the silk-screen (e.g. VART instead of UART, D3 instead of DB)
Some months ago I bought two pieces from Aliexpress, today I thought I would try it with a bipolar 35P048S stepper motor. First without luck.

Code looked good, GPIO pin signals looked good on scope, but nothing came from L293DD output pins. Then I checked the PWM(enable) pin link to the ESP8266 board and turned out that the signal is connected to GND through a 100Ω resistor, while receiving the signal through a 1KΩ resistor! No idea why someone did that, but I just simply removed the two 100Ω resistor, and everything started to work fine.

JörgW (author)Attila_FIN2017-10-19

My shield came with the information that d1 and d2 are the level, and d3, d4 are the direction for the motors. To use it with a stepper motor, this requires no hardware change, but simply slightly different step_states from the code above.

x = 0; -- here direction doesn´t matter, coil ist not powered anyway.
step_states8bi = {

step_states4bib = {

-- Note that with this 4 state stepper, both coils are always powered, just the direction changes.

JohnMcHD (author)2017-07-27

The ESP8266 NODEMCU .9 is that the one that does not fit on the MB102 breadboard, it plugs in, but there is no where left to plug in pins to it

If i'm correct the 1.0 is smaller in width than the .9 is that correct ? thanks for your help - John

hebertialmeida made it! (author)2017-05-19

Nice, I made that using Arduino IDE, spent a lot of time to figure out why it was not working, thanks to Attila_FIN to point to the right solution of removing the two 100Ω resistor.

rudi48 (author)2017-01-09

Hello ehsmaes,

I have tried to use the ESP-12 motor shield with a bipolar stepper motor, as you described.

To my surprise I found out, that the motor drive signals are routes in a way, that it is impossible to drive a bipolar stepper motor. My signal measurements:

Mapping NodeMCU to ESP-12 motor shield and driver IC
NodeMCU J2 m.-shield L293DD pin
pin2 D1 GPIO5 PWMA Enable1 1
pin3 D2 GPIO4 PWMB Enable2 11
pin4 D3 GPIO0 DA Input1 2 Direction A
pin5 D4 GPIO2 DB Input3 12 Direction B

I have not found any possibility to control Input-2 and Input-4.

In your program "stepper.lua" there is the definition:

-- nodemcu pins: 0 5 6 7

Are that the Dx or GPIOx numbers?

Could you please tell, if you have an other ESP-12 motor shield,

or did you make some rewiring, or I am totally confused?

Regards, rudi48

ehsmaes (author)rudi482017-01-10

Hi rudi48, I'm sorry it is not working for you. It certainly works for me with a 28BYJ directly connected to the shield. I haven't modified the circuit or put anything in between. Looking now at the comment (0 5 6 7) it doesn't make sense. I think that must have been left in the code by mistake. The pins used are D1 (GPIO5), D2 (GPIO4), D3 (GPIO0) and D4 (GPIO2) and they are adressed in the gpio module as 1 - 4 (D-numbers). I still use the stepper.lua file and works very well. However, there are a couple of things you could try. Increase the stepper delay from 1 to 2. If you are powering the motor from USB, the motor will probably not get enough juice to rotate at 1ms steps. 2ms steps should be just fine though. Also, take care with the power jumper, power switch if you connect USB and external power at the same time. Lastly, make sure you don't hook anything else up to the GPIO breakout-pins 1-4.

rudi48 (author)ehsmaes2017-01-11

Hello ehsmaes, thank you very much for your detailed answer. To me it looks like, that we have different shield versions. I am feeding the motor supply voltage with an external power supply.

In the meanwhile I have ordered a motor shield for Arduino from Adafruit. That works fine, and has good software support.

Grifter2 (author)rudi482017-03-04

So i ran into the same problem... New motor control boards are wired differently.

input 2 and input 4 on the H Bridge are not wired to pins D1 and D2 on the NodeMCU, also Enable pin 2 on the H Bridge is wired to D2 on the nodeMCU via a resister. Enable pin 1 on the H Bridge is pulled low via a resister that is hardwired.

So to be clear it looks like stepper motors cannot be run off of this board without unsoldering the resistor, jumping the inputs and jumping the enable pin on the H Bridge.

Grifter2 (author)Grifter22017-03-04

That was easier then i though (for the stepper motor control, or two enable the second motor to work in the other configuration)

H Drive schematic is here

To fix solder pin 1 to 20 and 11 (This will enable both motor drivers)

Solder pin 9 to D1 (its marked 1 on the motor controller board)

Solder pin 19 to D2 (its marked 2 on the motor controller board)

Remove the 2nd and 5th resistor from the motor controller board (assumes the board is rotated so the blue headers are on your left)

Motor will now make its 50% rotations.

AgustinNunez (author)Grifter22017-03-16

Thanks Ehsmaes, Rudi48 & Grifter2 for your investigation, I lost 2 days testing different motors, ESP's and Shield configurations trying to drive a NEMA Stepper, finding weird signals at the Oscilloscope, thinking problems was me. My question is which resistors to remove. Rudi48 says 2nd and 5th, but starting from left or right? I guess are the ones with marking 102. I understand that one should also remove the 6pin little ic (marking =4v) that I couldn't find ist datasheet and was very suspictious to lower A+ / A- current. I don't know how to warn buyers that selling shops still advertise this Shield as capable of driving Steppers motors while is not (at least the version is being offered right now everywhere.

Grifter2 made it! (author)AgustinNunez2017-03-16

See attached photo

AgustinNunez made it! (author)Grifter22017-03-17

Done and working. Images worth more than words.

In 3 steps:

1st remove two 102 resistors and "=4v" ic.

2nd on L293DD bridge pin 1 with 20, and 10 with 11, as 10 and 20 are both connected to Vm.

3rd reuse the lower pads of removed resistors, as they are already connected to D1 and D2, wiring Pin 2(l293dd) with left resistor lower pad (D1) and Pin3(l293dd) with right resistor lower pad (D2).

With this patch in place, the mod is hidden below NodeMCU so the result is safe.

The final connections scheme is like attached table

gadu74 (author)AgustinNunez2017-03-17

I did exactly this, but now the ESP8266 is not responding when connected to the motorshield. When not connected to the shield the ESP works fine. Anything I'm missing?

Not as close nice looking solderjoints as you, but i checked and can't see any shorts.

gadu74 (author)gadu742017-03-18

Thanks AgustinNunez and Grifter2, got everything working! But i had to put red motorwire to positive on my 5V/2A powersupply for it work.

Grifter2 (author)gadu742017-03-17

its always possible you have the NodeMCU in backwards so check that first.

Next get a multimeter that has a continuity feature, remove the NodeMCU and check if any of the pins you soldered are shorted to any of the other pins beside them. Its possible a little strand of wire or solder is bridging two of the pads.

Its also possible that two of the leads from the stepper motor are shorted by a small strand of wire that may not have landed inside the screw terminals properly

Failing that i would check how many milliamps the 5 volt power supply your using is. If its not at least 750ma i would upgrade, currently i have mine hooked to a bench supply and at full sprint the whole unit draws about 700ma.

gadu74 (author)Grifter22017-03-18

Thanks Grifter2 and AgustinNunez, i will do some more measurements today. As I wrote in reply below I've used only computer USB as powersource, probably not enough.

AgustinNunez (author)gadu742017-03-17

Seems your patches are ok. How do you power the shield? Which is your stepper? When I did bridge Vs and Vss on L293dd (what actually connect Vmotor and Vin) to both Enable pins I assumed that power supply is sufficient to power both, ESP & stepper. Don't know in your case, but if ESP does not work when connected, seems a power issue. I supose you have double check that D1 & D2 are connected to IN2 and IN4 only.

gadu74 (author)AgustinNunez2017-03-18

I have to do some measurements to check for shorts and how D1/D2 is connected, but also try another powersource. Used only the USB from the computer, I read somewhere that its not enough for this setup.

Grifter2 (author)AgustinNunez2017-03-17

nicely done, I bought 18 boards, i have only fixed one so far. I am going to to steal your idea of connecting to the resistors pad for the next 17 boards, that looks very clean.

Grifter2 (author)Grifter22017-03-04

if you motor runs clockwise even when it should be in reverse then removing the small transistor looking device in between the resisters will fix the problem. It seems that it shorts the A- and A+ rails causing the coils to fire in the wrong sequence. I used 4 LED's hooked up in place of the stepper motor to diagnose my setup, that's what lead me to find this.

emilmash (author)2016-07-20

Hi, it's a really great and very useful tutorial. What about part two?

ehsmaes (author)emilmash2016-07-20

Temporary pause on part two :-) I'm on vacation for a couple of weeks. I will get back to it soon thereafter!

About This Instructable




Bio: IT-professional by day, DIY hobbyist (among other things) on my free time. I always have one or more projects going on. Usually something to do ... More »
More by ehsmaes:Motorized WiFi IKEA Roller BlindCheap 3D Delta Printer ImprovementsMotorize IoT with ESP8266
Add instructable to: