engineer2you
Published © GPL3+

DC Motor Position Control

This instruction will show how to control motor position via Local web network.

IntermediateFull instructions provided3,992
DC Motor Position Control

Things used in this project

Story

Read more

Schematics

12_circuit_1_Qufw6p0DGe.png

Code

code arduino

C/C++
  #include <Arduino.h>
  #include <ESP8266WiFi.h>
  #include <Hash.h>
  #include <ESPAsyncTCP.h>
  #include <ESPAsyncWebServer.h>
  #include "FS.h"

// Replace with your network credentials
const char* ssid = "NguyenTuong";
const char* password = "064897435";

#define LED 16

int rotation_value; //value of rotation from local web
//-----------------------position control
const byte pin_a = 4;   //for encoder pulse A
const byte pin_b = 5;   //for encoder pulse B
const byte pin_fwd = 12; //for H-bridge: run motor forward
const byte pin_bwd = 13; //for H-bridge: run motor backward
const byte pin_pwm = 14; //for H-bridge: motor speed
int encoder_r = 0;
int encoder_f = 0;
int position_pv = 0;
int position_sv = 0;
int m_direction = 0;

// Create AsyncWebServer object on port 80
AsyncWebServer server(80);

const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
  <script src="jquery.min.js"></script>
  <script src="knob.js"></script>
        
  <meta name="viewport" content="width=device-width, initial-scale=1">
  
</head>

<body>
  <center>
  <h2>Motor position control</h2>
  <input type="text" class="dial" value="1" data-displayPrevious=true data-fgColor="#00A8A9" data-thickness=.6>
  </center>

  <script>
    $(".dial").knob({
        'change' : function (v) { console.log(Math.round(v,0));    
    $.ajax({url: "/setLOCATION?rotation="+Math.round(v,0), success: function(result){
            $("#div1").html(result);
        }});
  }
    });
  </script>

</body>
</html>)rawliteral";


void setup(){
  //---------declaration for position control
  pinMode(pin_a,INPUT_PULLUP);
  pinMode(pin_b,INPUT_PULLUP);
  pinMode(pin_fwd,OUTPUT);
  pinMode(pin_bwd,OUTPUT);
  pinMode(pin_pwm,OUTPUT);
  attachInterrupt(digitalPinToInterrupt(pin_a), detect_a_r, RISING);

  digitalWrite(pin_fwd,0);  //stop motor
  digitalWrite(pin_bwd,0);  //stop motor
  
  // Serial port for debugging purposes
  Serial.begin(115200);
  
  // Connect to Wi-Fi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }
  if(!SPIFFS.begin()){
        Serial.println("An Error has occurred while mounting SPIFFS");
        return;
  }

  // Print ESP32 Local IP Address
  Serial.println(WiFi.localIP());

  // Route for root / web page

  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html);
  });
  server.on("/jquery.min.js", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(SPIFFS, "/jquery.min.js", "text/javascript");
  });
  server.on("/knob.js", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(SPIFFS, "/knob.js", "text/javascript");
  });
  server.on("/setLOCATION",HTTP_GET, [](AsyncWebServerRequest *request){
    String ROTATION = request->getParam("rotation")->value();
    rotation_value = 1024 - (ROTATION.toInt())*10;
    Serial.print("rotation_value ");
    Serial.println(rotation_value);
    analogWrite(LED,rotation_value);  //adjust LED light on NodeMCU
    request->send(200, "text/plane","");
    
  });
  // Start server
  server.begin();
}
 
void loop(){
  analogWrite(pin_pwm,650); //set motor speed = 650/1024
  position_sv = (1024 - rotation_value)/10; //unit: % (e.g. 0% ~ 0dg; 100% ~ 360dg)
  position_pv = ((encoder_r+encoder_f)/2); //unit: %; encoder pulse per revolution: 200ppr
  if(position_pv-position_sv < 0){
      digitalWrite(pin_fwd,1);
      digitalWrite(pin_bwd,0);
    }
    else{
      if(position_pv-position_sv > 0){
        digitalWrite(pin_fwd,0);
        digitalWrite(pin_bwd,1);
      }
      else{
        //stop motor if position between +0 ~ -0
        digitalWrite(pin_fwd,0);  //stop motor
        digitalWrite(pin_bwd,0);  //stop motor
      }
    }
}

void detect_a_r() {
  m_direction = digitalRead(pin_b); //read direction of motor
  if(!m_direction){
    encoder_r += 1;   //increasing encoder at forward run
  }
  else{
    encoder_r += -1;  //decreasing encoder at backward run
  }
  attachInterrupt(digitalPinToInterrupt(pin_a), detect_a_f, FALLING); //change interrupt to Falling edge
}
void detect_a_f() {
  m_direction = digitalRead(pin_b); //read direction of motor
  if(m_direction){
    encoder_f += 1; //increasing encoder at forward run
  }
  else{
    encoder_f += -1; //decreasing encoder at backward run
  }
  attachInterrupt(digitalPinToInterrupt(pin_a), detect_a_r, RISING);  //change interrupt to Rising edge
}

Credits

engineer2you

engineer2you

21 projects • 53 followers
i'm mechatronics engineer who loves making funny project and sharing for you. See me at: https://www.youtube.com/c/engineer2you

Comments