Introduction: Controlling Servo Using MPU6050 Between Arduino and ESP8266 With HC-12

About: I am pursuing CSE engineering and have enthusiasm in Arduino DIY projects and ROBOTICS.

In this project, we are controlling the position of a servo motor using the mpu6050 and HC-12 for communication between Arduino UNO and ESP8266 NodeMCU.


It is another IoT project based on HC-12 RF-module. Here, the imu(mpu6050) data from arduino is used to control the servo motor (connected with Nodemcu). Here, the data visualization is also performed at arduino side where the mpu6050 pitch data(rotation about x-axis) is visualize with a processing sketch(discussed later). Basically this project is just a little warm up for remembering different aspects of Imu & Servo control with Arduino and ESP8266 nodemcu.


The objective of this pretty clear, We are controlling the position of Servo motor using the pitch value of IMU. And all together this pitch and synchronized motor position is visualized with Processing.

Step 2: Hardware Required

  • NodeMCU ESP8266 12E Wifi module
  • Solderless breadboard
  • Jumper wire
  • MPU6050 accelo+gyro
  • HC-12 RF modules (pair)
  • SG90 Servo motor

Step 3: Circuit & Connections

Connections are straight forward. You can power the servo with 3.3V of your Nodemcu. You can also use Vin to power the servo if your nodemcu has that much voltage on that pin. But most Lolin boards don't have 5V at Vin(depends on the manufacturer).

These circuit diagrams are made using EasyADA.


As soon as the arduino sketch started, it will send the pitch angle (which ranges from -45 to 45) to the hc12 receiver of Nodemcu that get mapped with 0 to 180 degree Servo position. Here we used the pitch angle from -45 to +45 degree so that we can easily map that to the Servo position.

Now, you are thinking why can we simply use the map method as follows:-

int pos = map(val,-45,45,0,180);

Because the negative angle sent by the hc12 transmitter is received as:

1st half : (T)0 to 45 => 0 to 45(R)

2nd half : (T)-45 to -1 => 255 to 210(R)

So you have to map it to 0 to 180 as

if(val>=0 && val<=45)      
      pos = (val*2)+90;
      pos = (val-210)*2;</p>

I am avoiding the map method due to some irrelevant error. You can try that and comment it works with you

if(val>=0 && val<=45)
	pos = map(val,0,45,90,180);
	pos = map(val,255,210,0,90);            // 4th argument can be 2 (you can check)

MPU6050 Pitch Angle Calculation

I'm using MPU6050_tockn library which is based on giving out raw data from the IMU.

int pitchAngle = mpu6050.getAngleX()

This will get us the angle of rotation about the x-axis. As you seen in the figure, my imu is vertically placed on the breadboard so don't confuse with pitch and roll. Actually you should always see the axis's printed on the breakout board.

Through this library, you don't have to bother about the internal electronics of reading specific registers for specific operation. you only specify the job and you are done!

Btw if you want to calculate the angle by yourself. You can easily do it as follows:

#include <Wire.h>
const int MPU6050_addr=0x68;
int16_t AcX,AcY,AcZ,Temp,GyroX,GyroY,GyroZ;
void setup(){  
void loop(){  
int xAng = map(AcX,minVal,maxVal,-90,90);   
int yAng = map(AcY,minVal,maxVal,-90,90);
    int zAng = map(AcZ,minVal,maxVal,-90,90);
    x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI);
    y= RAD_TO_DEG * (atan2(-xAng, -zAng)+PI);
    z= RAD_TO_DEG * (atan2(-yAng, -xAng)+PI);
     Serial.print("AngleX= ");                         // Pitch
     Serial.print("AngleY= ");                         //Roll
     Serial.print("AngleZ= ");                         //Yaw


But, it is not necessary that you will write this much code to get the angle. You should know the facts behind the scene but using library of other people is very effective in many projects. You can read about this imu and other approches to get more filtred data from the following link: Explore-mpu6050 .

My arduino code at the transmitting end has only 30 lines with the help of MPU6050_tockn library so using a library is good unless you don't need some core changes to the functionality of IMU. A library named I2Cdev by Jeff Rowberg is very helpful if you want some filtered data using the DMP(Digital motion processor) of the IMU.

Integration with Processing

Here Processing is used for visualizing the rotational data about the x-axis of IMU as calculated by the raw data coming from MPU6050. We receive the incoming raw data in SerialEvent in the following manner:

void serialEvent(Serial myPort) {
inString = myPort.readString();
  try {
    // Parse the data
    String[] dataStrings = split(inString, ':');
    if (dataStrings.length == 2) {
     if (dataStrings[0].equals("RAW")) {
        for (int i = 0; i < dataStrings.length - 1; i++) {
          raw[i] = float(dataStrings[i+1]);
      } else {
  } catch (Exception e) {
    println("Caught Exception");

Here you can see visualization in the image attached in this step. The position data received at the nodemcu end is also seen on the serial monitor as shown in the image.

Step 5: CODE

I have attached the github repository. You can clone & fork it to use in your projects.


The repo includes 2 arduino sketch for transmitter(arduino+IMU) & receiver (Nodemcu+Servo).

And one processing sketch. Star the repo if this helps in your project.

In this instructable,

R- Receiver & T- Transmitter


I will attach the video tomorrow. Follow me to get notified.

Thank you all!