Skip to content

Embedded C code to control a DC motor with high precision.

Notifications You must be signed in to change notification settings

Juhyung-L/motor_control

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 

Repository files navigation

motor_control

This code was written for a PIC32MX795F512L microprocessor on an Explorer 16/32 Board on the MPLAB X IDE. Because the code only works on the specified hardware, the focus of this repository is to show the method in which the DC motor was controlled, rather than the actual code itself.

The setup is shown below. image

There were 3 different types of motor controllers that were implemented

  1. Angle-Gap Controller
  2. Proportional controller
  3. Proportional-Integral controller

Angle-Gap Controller

This controller is the simplest method of controlling the motor. Essentially, the motor is set to turn right if its current angle exceeds the desired angle and turn left if it is below the desired angle.

motor_control/main.c

Lines 188 to 208 in 74b51d9

if (mode == angle_gap_mode) { // angle gap mode
// read from potentiometer and set the duty cycle of the motor
// higher potentiometer reading = higher duty cycle
unsigned int pot_data = 0;
int pot_pin = 2;
pot_data = adc_sample_convert(pot_pin); // reading from potentiometer
OC4RS = pot_data; // this changes the duty cycle
// set direction of motor
// set P88 and P87 until ref angle - current angle < 7.5
if((desired_angle - current_angle) > 7.5) { // desired angle is more positive -> increase count
setDirection(1);
}
else if((desired_angle - current_angle) < -7.5) { // current angle is more positive -> decrease count
setDirection(-1);
}
else { // stop the motor
setDirection(0);
}
LATAbits.LATA0 = 1;
IFS0bits.T2IF = 0;
}
if statement is placed in a timer interrupt service routine that is repeatedly called with a certain frequency. pot_data is the resistance reading from a potentiometer and its value is used to set the magnitude of motor velocity by setting the variable OC4RS, which controls the PWM signal duty cycle. So, the motor moves at a fixed speed and its direction is set to left or right if current_angle is not within 7.5 degrees of desired_angle.

Proportional Controller

The second controller is the proportional controller. The block diagram of the controller is shown below.

image

This controller works by taking the difference between the current_angle and desired_angle, multiplying the difference by a constant named kp, then setting that value to be the velocity of the motor.

motor_control/main.c

Lines 209 to 215 in 74b51d9

else if (mode == P_mode) { // proportional control mode
float e = desired_angle - current_angle; // get error
setDirection(kp * e); // set direction as gain * error (only the sign of gain * error matters)
setOC4(abs(kp * e)); // set pwm signal to magnitude of gain * error
LATAbits.LATA1 = 1;
IFS0bits.T2IF = 0;
}
The benefit of this controller compared to the angle-gap controller is that the velocity of the motor is high when current_angle is far away in value from desired_angle and low when the two angles are close in values.

Proportional-Integral Controller

The last controller is the most complicated controller out of the three (relatively).

image

This controller is an extension of the proportional controller. The added feature is that the velocity of the motor is not only defined by the difference in current_angle and desired_angle. but also the integral of the difference.

motor_control/main.c

Lines 216 to 223 in 74b51d9

else if (mode == PI_mode) { // proportional-integral control mode
float e = desired_angle - current_angle;
eint += e; // integrating error (summation in the discrete world)
setDirection(kp*e + ki*eint);
setOC4(abs(kp*e + ki*eint));
LATAbits.LATA2 = 1;
IFS0bits.T2IF = 0;
}
The integral is calculated by summing the difference in the angles. This method of calculating the integral is called the Euler approximation and it is a fairly good estimate of the integral because this block of code is called many times per second.

What makes this controller superior to the proportional controller is that the proportional controller cannot maintain a steady motor angle under constant force. Consider the following scenario: a constant force is applied to the wheel of the motor that shifts current_angle away from desired_angle. In this case, the proportional controller will start moving the motor only when the difference in the angles is non-zero. This means the motor will go back and forth between desired_angle and slightly less/more than desired_angle, causing and oscillatory motion. On the other hand, the proportional-integral controller will be able to maintain a steady angle even under constant force.

About

Embedded C code to control a DC motor with high precision.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages