Skip to content
This repository was archived by the owner on Aug 6, 2025. It is now read-only.

cakraawijaya/Motor-Speed-RPM-PID-Ziegler-Nichols-2-IoT

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Open Source Love License: MIT GitHub last commit Project Type

Motor-Speed-RPM-PID-Ziegler-Nichols-2-IoT

Undergraduate Thesis Project Documentation - Informatics UPN Veteran Jatim

In the industrial sector, DC conveyor motors are commonly used to move materials efficiently. Maintaining a stable speed is essential to ensure product quality and smooth production. Previous research faced issues with microcontroller selection and suboptimal PID implementation. Remote control was underutilized, and system integration was not fully synchronized. These shortcomings affected the flexibility and reliability of the conveyor. This project aims to improve speed control with IoT integration. The ESP32 microcontroller manages ON/OFF functions, rotation direction, and RPM setpoint. Ubidots serves as the remote monitoring and control platform. The Ziegler-Nichols PID method is applied to stabilize motor speed. The project was developed over one year and is expected to enhance the efficiency and reliability of small-scale industrial automation.



Project Requirements

Part Description
Development Board DOIT ESP32 DEVKIT V1
Code Editor Arduino IDE
Driver CP210X USB Driver
IoT Platform Ubidots
Communications Protocol • Inter Integrated Circuit (I2C)
• Message Queuing Telemetry Transport (MQTT)
IoT Architecture 3 Layer
Programming Language C/C++
Arduino Library • WiFi (default)
• PubSubClient
• LiquidCrystal_I2C
• ArduinoJson
• ESP32Encoder
Actuators Motor DC JGA25-370 (x1)
Sensor Encoder Sensor (x1)
Display LCD I2C (x1)
Other Components • USB type C - USB type A cable (x1)
• Jumper cable (1 set)
• Female DC power adapter (x1)
• Push button 12 x 12 mm (x2)
• Motor driver L298N (x1)
• Potentiometer (x1)
• Adaptor 12V 2A (x1)
• Adaptor 5V 2A (x1)
• Breadboard (x1)
• Plywood 50 x 50 cm (x2)
• Stainless Steel Concrete 30 cm (x1)
• 1/2 Inch Pipe 25 cm (x1)
• Oscar fabric 50 x 137 cm (x1)
• Spicer bolts (1 set)
• Bolts plus (1 set)
• Nuts (1 set)
• L Bracket (1 set)
• PVC Electrical insulation (1 set)
• Sandpaper G-180 1 m (x1)
• Smart Car Rims (x1)



Download & Install

  1. Arduino IDE

    https://www.arduino.cc/en/software
    

  2. CP210X USB Driver

    https://bit.ly/CP210X_USBdriver
    



Project Designs

Infrastructure
infrastructure
Block Diagram Pictorial Diagram
block-diagram pictorial-diagram
Prototype Design
prototype-design-1 prototype-design-2
Conveyor System Blueprint
blueprint-1 blueprint-2 blueprint-3
Wiring
wiring



CPR Calibration

// Library to read Magnetic/Optical Encoder with ESP32
#include <ESP32Encoder.h>

// Channel A of the encoder is connected to GPIO pin 34
#define encoderA 34

// Channel B of the encoder is connected to GPIO pin 35
#define encoderB 35

// Encoder object from the ESP32Encoder library
ESP32Encoder encoder;

// Encoder initial count (when starting calibration)
long startEncoderCount = 0;      

// Previous encoder count (to calculate delta)
long lastEncoderCount = 0;

// Difference between current and previous count
long deltaEncoderCount = 0;

// Count per Revolution (number of counts in one full revolution)
float CPR = 0;

// Pulse per Revolution (number of pulses of 1 channel in one revolution)
float PPR = 0;

// Gearbox ratio between motor and output shaft
float gearRatio = 0;

// PPR internal encoder (usually 11, depending on motor specifications)
const float encoderPPR_Internal = 11.0;

// Total estimated output shaft rotation
float totalOutputRotation = 0;

// Output shaft rotation target for calibration (default: 1 full rotation)
int outputRotationTarget = 1;

// Status of whether the calibration has been completed
bool calibrationDone = false;


// Function to display the guide on the Serial Monitor
void showInstructions() {
  Serial.println("================================================");
  Serial.println("                 CPR CALIBRATION                ");
  Serial.println("================================================");
  Serial.println("Steps:");
  Serial.println("1. Make sure the motor and encoder are connected.");
  Serial.println("2. Turn the OUTPUT shaft clockwise.");
  Serial.println("3. Rotate 1x full (360 degrees) steadily.");
  Serial.println("4. Wait for the calibration result to appear.");
  Serial.println("------------------------------------------------");
}


// The setup function will be executed once when the ESP32 board is powered on
void setup() {
  
  // Initialize Serial communication with baudrate 115200
  Serial.begin(115200);

  // Connect encoder with Full Quadrature method (4x resolution)
  encoder.attachFullQuad(encoderB, encoderA);

  // Reset encoder count to 0
  encoder.clearCount();

  // Save the initial count as a reference
  lastEncoderCount = encoder.getCount();

  // Also save as initial calibration value
  startEncoderCount = lastEncoderCount;

  while (!Serial) {
    ; // Wait for the Serial Monitor to be ready
  }

  // Delay to ensure Serial Monitor is completely ready
  delay(5000);
  
  // Display calibration instructions to user
  showInstructions();
}


// The loop function will be executed repeatedly (continuously)
void loop() {
  
  // If the calibration is complete, stop the loop (do nothing)
  if (calibrationDone) return;

  // Read the current encoder count value
  long currentCount = encoder.getCount();
  
  // Calculate the change from the last reading
  deltaEncoderCount = currentCount - lastEncoderCount;

  // Estimation of output rotation increment, based on encoder count change
  // Only if forward rotation occurs
  if (deltaEncoderCount > 0) {

    // Add to total output revolutions (500 is just an initial estimate)
    totalOutputRotation += deltaEncoderCount / 500.0;

    // If the total output rotation has reached the target (e.g. 1 full rotation)
    if (totalOutputRotation >= outputRotationTarget) {
      
      // Mark calibration complete
      calibrationDone = true;

      // Total encoder count for 1 revolution
      long totalCountsInOneRotation = currentCount - startEncoderCount;

      // Count Per Revolution
      CPR = (float)totalCountsInOneRotation;

      // Counts per pulse (due to Full Quad, divided by 4)
      PPR = CPR / 4.0;

      // Estimated gearbox ratio
      gearRatio = CPR / (encoderPPR_Internal * 4.0);

      // Round up results for easier reading
      int PPR_rounded = round(PPR);
      int CPR_rounded = round(CPR);
      int gearRatio_rounded = round(gearRatio);

      // Display calibration results
      Serial.println();
      Serial.println("================ CALIBRATION RESULT ===============");
      Serial.print("PPR (Pulse/Revolusi)   =  "); Serial.println(PPR_rounded);
      Serial.print("CPR (Count/Revolusi)   =  "); Serial.println(CPR_rounded);
      Serial.print("Gear Ratio (Motor:Out) =  1:"); Serial.println(gearRatio_rounded);
      Serial.println("================================================");
      Serial.println("✅ Calibration completed. Use the above values.");
    }
  }

  // Last encoder count update
  lastEncoderCount = currentCount;
}


Arduino IDE Setup

  1. Open the Arduino IDE first, then open the project by clicking File -> Open :

    Main.ino


  2. Fill in the Additional Board Manager URLs in Arduino IDE

    Click File -> Preferences -> enter the Boards Manager Url by copying the following link :

    https://dl.espressif.com/dl/package_esp32_index.json
    

  3. Board Setup in Arduino IDE

    How to setup the DOIT ESP32 DEVKIT V1 board

    • Click Tools -> Board -> Boards Manager -> Install esp32.

    • Then selecting a board by clicking: Tools -> Board -> ESP32 Arduino -> DOIT ESP32 DEVKIT V1.


  4. Change the Board Speed in Arduino IDE

    Click Tools -> Upload Speed -> 115200


  5. Install Library in Arduino IDE

    Download all the library zip files. Then paste it in the: C:\Users\Computer_Username\Documents\Arduino\libraries


  6. Port Setup in Arduino IDE

    Click Port -> Choose according to your device port (you can see in device manager)


  7. Change the WiFi Name, WiFi Password, and so on according to what you are currently using.

  8. Before uploading the program please click: Verify.

  9. If there is no error in the program code, then please click: Upload.

  10. Some things you need to do when using the ESP32 board :

    • If ESP32 board cannot process Source Code totally -> Press EN (RST) button -> Restart.

    • If ESP32 board cannot process Source Code automatically then :

    • When information: Uploading... has appeared -> immediately press and hold the BOOT button.

    • When information: Writing at .... (%) has appeared -> release the BOOT button.

    • If message: Done Uploading has appeared -> The previously entered program can already be operated.

    • Do not press the BOOT and EN buttons at the same time as this may switch to Upload Firmware mode.


  11. If there is still a problem when uploading the program, then try checking the driver / port / others section.



Ubidots Setup

  1. Getting started with Ubidots :

    • Please Log in to access the Ubidots service.

    • If you don't have a Ubidots account yet, please create one.


  2. Creating dashboards :

    • In the Data section -> select Dashboards menu.

    • Delete the Ubidots built-in demo dashboard before creating a new dashboard.

    • Click Add new Dashboard.

    Name, Tags, Default time range -> customize it to your needs.

    Dynamic Dashboard -> change it to Dynamic (Single Device).

    Default Device -> select the device you want to display.

    • Leave the other settings alone -> then click SAVE.


  3. Creating line chart widget :

    • Make sure you are in the Dashboards menu.

    • Click + Add new widget.

    • Select Line chart for data visualization.

    • Please set the variables that you want to use on the widget by clicking + ADD VARIABLE, then click ✅ Checklist to save.

    • If you want to change the content of the widget, please click the pencil symbol -> if so, then click ✅ Checklist to save.


  4. Creating switch widget :

    • Make sure you are in the Dashboards menu.

    • Click + Add new widget.

    • Select Switch for ON/OFF control and for DC motor rotation direction control.

    • Please set the variables that you want to use on the widget by clicking + ADD VARIABLE, then click ✅ Checklist to save.

    • If you want to change the content of the widget, please click the pencil symbol -> if so, then click ✅ Checklist to save.


  5. Creating indicator widget :

    • Make sure you are in the Dashboards menu.

    • Click + Add new widget.

    • Select Indicator to know the ON/OFF status and rotation direction status of the DC motor.

    • Please set the variables that you want to use on the widget by clicking + ADD VARIABLE, then click ✅ Checklist to save.

    • If you want to change the content of the widget, please click the pencil symbol -> if so, then click ✅ Checklist to save.


  6. Firmware configuration :

    • Click the User section in the bottom left corner -> then select API Credentials.

    • Copy the Default token -> paste it into the firmware code. An example is as follows:

    const String token = "BBUS-aRZvtYRMM7IWbrKFcICR30YYP7dh5Q"; // define ubidots token



Get Started

  1. Download and extract this repository.

  2. Make sure you have the necessary electronic components.

  3. Make sure your components are designed according to the diagram.

  4. Configure your device according to the settings above.

  5. Please enjoy [Done].



Highlights

Product
product-1 product-2
Wi-Fi Connectivity
wifi-connectivity-1 wifi-connectivity-2 wifi-connectivity-3
IoT Connectivity
iot-connectivity-1 iot-connectivity-2 iot-connectivity-3 iot-connectivity-4
Publish-Subscribe MQTT
pubsub-mqtt-1 pubsub-mqtt-2 pubsub-mqtt-3 pubsub-mqtt-4
LCD View
lcd-view-1 lcd-view-2 lcd-view-3 lcd-view-4 lcd-view-5
Serial Monitor Serial Plotter
serial-monitor serial-plotter
Ubidots Controls and Indicators Ubidots Line Chart
control-indicators line-chart



More information:

• Undergraduate Thesis : Access 1 or Access 2

• Journal : Click Here



Appreciation

If this work is useful to you, then support this work as a form of appreciation to the author by clicking the ⭐Star button at the top of the repository.



Disclaimer

This application is the result of the hard work of my colleague named Hawin, not the result of plagiarism from other people's research or work, except those related to third-party services which include: libraries, frameworks, and so on. In this project I only act as a supervisor. The publication of this work has obtained permission from the party concerned in accordance with what was agreed at the beginning, namely for the development of science.



LICENSE

MIT License - Copyright © 2025 - Moch Hawin Hamami & Devan C. M. Wijaya, S.Kom

Permission is hereby granted without charge to any person obtaining a copy of this software and the software-related documentation files to deal in them without restriction, including without limitation the right to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons receiving the Software to be furnished therewith on the following terms:

The above copyright notice and this permission notice must accompany all copies or substantial portions of the Software.

IN ANY EVENT, THE AUTHOR OR COPYRIGHT HOLDER HEREIN RETAINS FULL OWNERSHIP RIGHTS. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, THEREFORE IF ANY DAMAGE, LOSS, OR OTHERWISE ARISES FROM THE USE OR OTHER DEALINGS IN THE SOFTWARE, THE AUTHOR OR COPYRIGHT HOLDER SHALL NOT BE LIABLE, AS THE USE OF THE SOFTWARE IS NOT COMPELLED AT ALL, SO THE RISK IS YOUR OWN.