Extracting Transfer Function of DC Motor
The Code and Data Acquisition
The complete code is available on my Github
Now because we need different sets of input and output data, we need to see the response of motor over various values of voltage. We do this by varying PWM and measure the corresponding voltage.
PWM
|
Voltage
(V)
|
255
|
10.4
|
100
|
7.56
|
75
|
6
|
50
|
3.68
|
The table above shows the corresponding values of voltage measured when different values of output were given. Using this data, a simple ratio formula is deduced to calculate the voltage at PWM which can be any value from 50-255.
As you can observe that its not linear, and hence the formula only tells us the approximate voltage and not the actual voltage
float volts(int num1) {
/* local variable declaration */
float result;
float num2;
num2=num1;
if(num2>=100){
result=(num2-100)*0.01806;
result=result+7.6;
}
else if(num2<100 && num2>75){
result=(num2-75)*0.06;
result=result+6;
}
else{
result=(num2-50)*0.0928;
result=result+3.68;
}
return result;
The function volts will allow us to calculate the corresponding value of voltage for the PWM,
As the motor uses quadrature encoder, there are 2 outputs from the motor that gives pulses. These pulses are counted and converted to revolutions/second and radians/second.
void EncoderInit()
{
Direction = true;//default -> Forward
pinMode(encoder0pinB,INPUT);
attachInterrupt(0, wheelSpeed, CHANGE);
}
void wheelSpeed()
{
int Lstate = digitalRead(encoder0pinA);
if((encoder0PinALast == LOW) && Lstate==HIGH)
{
int val = digitalRead(encoder0pinB);
if(val == LOW && Direction)
{
Direction = false; //Reverse
}
else if(val == HIGH && !Direction)
{
Direction = true; //Forward
}
}
encoder0PinALast = Lstate;
if(!Direction) duration++;
else duration--;
}
An interrupt service routine is called every time an impulse is received which allows us to measure impulses for the desired time.
long rpm1(unsigned long d){
long result1;
result1 = (duration/2)*600;
result1 = result1/1440;
return result1;
}
float rad(long a){
float result2;
result2 = a*0.1047;
return result2;
}
The above two functions converts impulses to rpm and rpm to rad/s.
The latest commit in the code gives steps of 2 volts. For other inputs refer to the commit history on github
for(int pwm=100; pwm<256;pwm++){
analogWrite(speedPinA, pwm);//Sets speed variable via PWM
delay(100);
time = millis();
}
for(int pwm=255; pwm >99;pwm--){
analogWrite(speedPinA, pwm);//Sets speed variable via PWM
delay(100);
time = millis();
}
Above two blocks, allow us to give ramp input and see the corresponding. All the different data sets I acquired are also uploaded on Github.
The figure above shows the data we have acquired. We can see how motor behaves to the step and ramp input.
Comments
Post a Comment