NodeMCU Motor Shield Review
I just received my NodeMCU Motor Shield to go with my NodeMCU v1 ESP12e development board and robot chassis.
So the board has a bunch of screw terminals on it – A+, A-, B+ and B- to connect two motors, and then VM/GND (up to 9v for the microcontroller) and VIN/GND (up to 36v for the motors). However the mostly undocumented feature is that if you jumper the VIN/VM pins near to the power switch, you can supply up to 9v to VIN/GND and it will feed that into the motors and also into the NodeMCU’s 3.3v regulator. I’ve used this configuration with two 18650 Li-Ion batteries that provide about 8v when fully charged (nominal 3.7v each).
Alternatively, but with some caution you can power the motors and the ESP12e via the NodeMCU’s micro USB port.
I had a poke around with a multimeter and found that if you put 8v into the VIN screw terminal and jumper the VIN/VM pins you get:
- 8v from the VM screw terminal;
- 8v from the VIN pin on the nodemcu itself;
- 8v from the two VIN pins on the motor shield;
- 3.3v from the three 3.3v pins on the modemcu;
- 3.3v from the 3.3v pin on the motor shield;
The motors seem to pull whatever they need – mine are 6v motors and they’re pulling about 6.25v when full on (1023 PWM) from the A+/B+ screw terminals.
If you power from USB the VIN pins run at about 4.4v and the motors run slower. The power button also does nothing. I think I’ll just use USB for programming rather than power, but you could use a USB power bank I guess, but at least it means you don’t have to unplug the NodeMCU from the motor shield to reprogram it, although it is a bit tight as the USB connector ends up only a few millimeters from the screw terminal blocks.
I initially wrote my own Arduino sketch which is a webserver that runs on the ESP12e and contains forward/backward/right/left/stop buttons.
// include libraries
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
// configure server
ESP8266WebServer server(80);
const char *form = "<center><form action='/'>"
"<button name='dir' type='submit' value='4'>Forward</button><br>"
"<button name='dir' type='submit' value='1'>Left</button> "
"<button name='dir' type='submit' value='2'>Right</button><br>"
"<button name='dir' type='submit' value='3'>Reverse</button><p>"
"<button name='dir' type='submit' value='5'>Stop</button>"
"</form></center>";
void stop(void)
{
analogWrite(5, 0);
analogWrite(4, 0);
}
void forward(void)
{
analogWrite(5, 1023);
analogWrite(4, 1023);
digitalWrite(0, HIGH);
digitalWrite(2, HIGH);
}
void backward(void)
{
analogWrite(5, 1023);
analogWrite(4, 1023);
digitalWrite(0, LOW);
digitalWrite(2, LOW);
}
void left(void)
{
analogWrite(5, 1023);
analogWrite(4, 1023);
digitalWrite(0, LOW);
digitalWrite(2, HIGH);
}
void right(void)
{
analogWrite(5, 1023);
analogWrite(4, 1023);
digitalWrite(0, HIGH);
digitalWrite(2, LOW);
}
void handle_form()
{
// only move if we submitted the form
if (server.arg("dir"))
{
// get the value of request argument "dir"
int direction = server.arg("dir").toInt();
// chose direction
switch (direction)
{
case 1:
left();
break;
case 2:
right();
break;
case 3:
backward();
break;
case 4:
forward();
break;
case 5:
stop();
break;
}
// move for 300ms, gives chip time to update wifi also
delay(300);
}
// in all cases send the response
server.send(200, "text/html", form);
}
void setup()
{
// connect to wifi network
WiFi.begin("essid", "passphrase");
// static ip, gateway, netmask
WiFi.config(IPAddress(192,168,1,2), IPAddress(192,168,1,1), IPAddress(255,255,255,0));
// connect
while (WiFi.status() != WL_CONNECTED)
{
delay(200);
}
// set up the callback for http server
server.on("/", handle_form);
// start the webserver
server.begin();
pinMode(5, OUTPUT); // 1,2EN aka D1 pwm left
pinMode(4, OUTPUT); // 3,4EN aka D2 pwm right
pinMode(0, OUTPUT); // 1A,2A aka D3
pinMode(2, OUTPUT); // 3A,4A aka D4
}
void loop()
{
// check for client connections
server.handleClient();
}
I also tried the Blynk joystick code with my Android phone. I’m still not happy with either solution though, as I need a way to move in more than one direction at once to give a smooth turning action – for example I can rotate left/right, but can’t drive forward at the same time, so I need to play with timings a bit more. Also I found that PWM at 512 seemed quite slow, so sticking with ultra-fast 1023 for full speed motors!
There’s a bunch of pins broken out on the motor shield – GPIO 0-8, UART, ADC, SPI etc. so you could add a servo or LED’s. Here is another useful post, and here is the pretty useless documentation.