INTRODUCTION
SmartDrive40 is a smart motor driver series with current capacity up to 80A peak and 40A continuously. It is equipped with a microcontroller unit to provide smart features such as multiple input modes, current limiting and thermal protection. In order to control SmartDrive40 using 3.3V microcontroller, you can consider to use either:
- RC MCU mode
- Serial Simplified mode
- Serial Packetized mode
In this tutorial, I will show you how to control SmartDrive40 using ESP32 board in Serial Simplified mode.
VIDEO
This video shows how to control SmartDrive40 using NodeMCU ESP32 in Serial Simplified mode.
HARDWARE PREPARATION
Below is the list of items used in the video

Wiring connection table.
NodeMCU ESP32 | SmartDrive40 | Rotary Encoder |
VIN | 5V | |
GND | GND | GND |
D13 | IN1 | |
D14 | IN2 | |
3.3V | VCC | |
D25 | CE | |
D26 | EA | |
D27 | EB |
Sample Code
This is the sample code used in the video. Please install ESP32 board in your Arduino IDE first.
#define RXD_DUMMY 12 | |
#define MDS40B_IN1 13 | |
#define MDS40B_IN2 14 | |
#define MDS40BSerial Serial1 | |
#define BBRS_CE 25 | |
#define BBRS_EA 26 | |
#define BBRS_EB 27 | |
int motorSpeed = 127; | |
boolean motorDirection = false; | |
volatile int lastEncoded = 0; | |
volatile long encoderValue = 0; | |
long lastencoderValue = 0; | |
int lastMSB = 0; | |
int lastLSB = 0; | |
boolean printEncoder = false; | |
void updateEncoder() | |
{ | |
int MSB = digitalRead(BBRS_EA); //MSB = most significant bit | |
int LSB = digitalRead(BBRS_EB); //LSB = least significant bit | |
int encoded = (MSB << 1) | LSB; //converting the 2 pin value to single number | |
int sum = (lastEncoded << 2) | encoded; //adding it to the previous encoded value | |
if (sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) { | |
encoderValue ++; | |
} | |
if (sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) { | |
encoderValue --; | |
} | |
lastEncoded = encoded; //store this value for next time | |
encoderValue = constrain(encoderValue, 0, 100); | |
printEncoder = true; | |
} | |
void setup() | |
{ | |
pinMode(BBRS_CE, INPUT); | |
pinMode(BBRS_EA, INPUT); | |
pinMode(BBRS_EB, INPUT); | |
pinMode(MDS40B_IN2, OUTPUT); | |
digitalWrite(MDS40B_IN2, HIGH); | |
Serial.begin(115200); | |
MDS40BSerial.begin(9600, SERIAL_8N1, RXD_DUMMY, MDS40B_IN1); | |
MDS40BSerial.write(motorSpeed); | |
delay(1000); | |
attachInterrupt(digitalPinToInterrupt(BBRS_EA), updateEncoder, CHANGE); | |
attachInterrupt(digitalPinToInterrupt(BBRS_EB), updateEncoder, CHANGE); | |
Serial.println(); | |
Serial.println(); | |
Serial.println("Controlling SmartDrive-40 Using ESP32 Controller"); | |
Serial.println(); | |
Serial.print("Enc:\tSpeed:"); | |
} | |
void loop() | |
{ | |
if (printEncoder == true) { | |
printEncoder = false; | |
if (motorDirection == false) { | |
motorSpeed = map(encoderValue, 0, 100, 127, 255); | |
} | |
else if (motorDirection == true) { | |
motorSpeed = map(encoderValue, 0, 100, 127, 0); | |
} | |
Serial.print(encoderValue); | |
Serial.print("\t"); | |
Serial.println(motorSpeed); | |
MDS40BSerial.write(motorSpeed); | |
} | |
if (digitalRead(BBRS_CE) == LOW) { | |
motorDirection = !motorDirection; | |
encoderValue = 0; | |
motorSpeed = 127; | |
MDS40BSerial.write(motorSpeed); | |
Serial.println(); | |
Serial.println("Change Direction!"); | |
Serial.println(); | |
Serial.print("Enc:\tSpeed:"); | |
while (digitalRead(BBRS_CE) == LOW); | |
delay(100); | |
} | |
} |
Thank You
References:
Thanks for reading this tutorial. If you have any technical inquiry, please post at Cytron Technical Forum.