askuric / Arduino-Closed-Loop-Motor-Control

Arduino Based Simple Closed Loop Motor Control library
MIT License
11 stars 4 forks source link

In velocity mode index_search failed #2

Closed Meekdai closed 4 years ago

Meekdai commented 4 years ago

Hi @askuric , I set up a simple test environment, I use arduino 2560 and my motor drive DRV8840. When I set the index pin:

Encoder encoder = Encoder(arduinoInt1, arduinoInt2, 128, A0);

Connect the A0 pin to the index of the encoder, The motor rotates, but it can never be completed.

DEBUG: Serial debugger enabled!  
DEBUG: Initilaise the motor pins.
DEBUG: Set high frequency PWM.   
DEBUG: Enabling motor.
DEBUG: Align the encoder and motor electrical 0 angle.
DEBUG: Search for the encoder index.

I tried not to use the index pin, set it to 0, I successfully entered

DEBUG: Serial debugger enabled!  
DEBUG: Initilaise the motor pins.
DEBUG: Set high frequency PWM.   
DEBUG: Enabling motor.
DEBUG: Align the encoder and motor electrical 0 angle.
DEBUG: Index not available!
Motor ready.
Input the new target velocity:

Through motor_monitor (); I can monitor my motor status very well. But when I input the velocity value between 0-450, the motor will jitter irregularly. After setting the velocity value greater than 500, the motor works well, but the speed will be maintained at around 460 even if I increase the velocity value.

I don't know if this is related to the parameters of PID.

the motor i used 483068

Meekdai commented 4 years ago

This is part of the data with velocity set to 10:

-0.15   10.00   21.23   20.48
-0.76   10.00   29.79   20.53
-0.16   10.00   13.34   20.57
-0.76   10.00   16.49   20.59
-0.17   10.00   8.49    20.62
0.11    10.00   8.49    20.62
0.38    10.00   8.49    20.62
0.66    10.00   8.49    20.62
0.93    10.00   8.49    20.62
1.50    10.00   1.33    20.63
0.92    10.00   8.98    20.65
0.33    10.00   22.20   20.71
-0.29   10.00   34.54   20.80
-0.91   10.00   29.27   20.87
-1.52   10.00   26.54   20.95
-0.92   10.00   16.44   20.98
-1.48   10.00   16.44   20.98
-0.88   10.00   -5.72   20.96
-0.28   10.00   -25.07  20.90
0.34    10.00   -35.06  20.81
0.97    10.00   -31.31  20.73
1.58    10.00   -27.10  20.65
2.20    10.00   -17.73  20.60

This is part of the data with velocity set to 500:

12.00   500.00  173.31  1041.56
12.00   500.00  179.83  1042.22
12.00   500.00  185.83  1042.91
12.00   500.00  190.66  1043.63
12.00   500.00  194.30  1044.38
12.00   500.00  201.62  1045.17
12.00   500.00  202.79  1045.99
12.00   500.00  216.05  1046.84
12.00   500.00  213.23  1047.72
12.00   500.00  226.79  1048.65
12.00   500.00  228.86  1049.62
12.00   500.00  233.40  1050.62
12.00   500.00  239.97  1051.65
12.00   500.00  250.69  1052.74
12.00   500.00  253.21  1053.87
12.00   500.00  253.74  1055.02
12.00   500.00  266.02  1056.23
12.00   500.00  265.82  1057.49
12.00   500.00  276.62  1058.78
12.00   500.00  277.45  1060.14
12.00   500.00  286.70  1061.54
12.00   500.00  293.30  1063.00
12.00   500.00  299.82  1064.51
12.00   500.00  307.53  1066.13
12.00   500.00  310.52  1067.74
12.00   500.00  316.88  1069.45
12.00   500.00  321.20  1071.22
12.00   500.00  328.87  1073.09
12.00   500.00  334.89  1075.00
12.00   500.00  340.64  1077.00
12.00   500.00  345.66  1079.10
12.00   500.00  354.47  1081.31
12.00   500.00  357.96  1083.62
12.00   500.00  363.11  1086.06
12.00   500.00  370.44  1088.59
12.00   500.00  378.02  1091.27
12.00   500.00  383.72  1094.05
12.00   500.00  389.09  1096.99
12.00   500.00  395.28  1100.12
12.00   500.00  403.06  1103.44
12.00   500.00  414.18  1106.99
12.00   500.00  421.34  1110.85
12.00   500.00  426.33  1114.96
12.00   500.00  435.71  1119.39
12.00   500.00  440.19  1124.15
12.00   500.00  450.09  1129.40
12.00   500.00  463.42  1135.28
12.00   500.00  467.22  1141.93
12.00   500.00  486.70  1149.71
12.00   500.00  498.21  1159.30
5.14    500.00  516.07  1172.21
-9.98   500.00  552.14  1199.88
-12.00  500.00  522.67  1225.12
-11.01  500.00  187.28  1225.83
-10.10  500.00  154.32  1226.39
-9.24   500.00  133.22  1226.84
-8.43   500.00  115.93  1227.20
-7.64   500.00  105.50  1227.52
-6.90   500.00  81.81   1227.75
-6.18   500.00  69.20   1227.95
-5.49   500.00  56.99   1228.11
-4.81   500.00  42.76   1228.22
-4.14   500.00  31.09   1228.30
-3.49   500.00  19.95   1228.35
-2.85   500.00  13.54   1228.39
-2.23   500.00  13.54   1228.39
askuric commented 4 years ago

Hey @Meekdai, thanks for the message. Both of the problems are the problems of the PI contorllers I think. Try to tune them a bit better, in the code they are set for a BLDC motor I have with me.

Basically try to set:

// index search velocity - default 1rad/s
  motor.index_search_velocity = 1;
  // index search PI contoller parameters
  // default K=0.5 Ti = 0.01
  motor.PI_velocity_index_search.K = 2;
  motor.PI_velocity_index_search.Ti = 10;
  // jerk control using voltage voltage ramp
  // default value is 100
  motor.PI_velocity_index_search.voltage_ramp = 1000;

and something similar to :

  // contoller configuration based on the controll type 
  // velocity PI controller parameters
  // default K=1.0 Ti = 0.003
  motor.PI_velocity.K = 2;
  motor.PI_velocity.Ti = 10;
  motor.PI_velocity.voltage_limit = 10;
  // jerk control using voltage voltage ramp
  // default value is 300 volts per sec  ~ 0.3V per millisecond
  motor.PI_velocity.voltage_ramp = 3000;

Also make sure if you dont need the pull-ups for your encoder.

You can use the Arduino ones if you need them at by setting:

  encoder.pullup = Pullup::INTERN;

By the look on the log, it seems that your motor cannot reach 500rad/s with 12 volts? To put 500 rad/s in context you can calculate it to rpm:

500[rad/s] / (2*PI) * 60 = 4774rpm (rotations per minute) 

I am not sure what your motor limit is but this might be close to it.

Meekdai commented 4 years ago

According to your suggestion, I tried some parameters and got better improvement.

  encoder.quadrature = Quadrature::ENABLE;
  encoder.pullup = Pullup::INTERN;
  encoder.init(doA, doB);
  motor.voltage_power_supply = 12;
  motor.index_search_velocity = 100;
  motor.PI_velocity_index_search.K = 0.5;
  motor.PI_velocity_index_search.Ti = 0.01;
  motor.PI_velocity_index_search.voltage_ramp = 20;
  motor.controller = ControlType::velocity;
  motor.PI_velocity.K = 0.5;
  motor.PI_velocity.Ti = 0.01;
  motor.PI_velocity.voltage_limit = 10;
  motor.PI_velocity.voltage_ramp = 20;

and the log:

0.61    200.00  192.80  13922.67
0.54    200.00  195.69  13923.45
0.48    200.00  201.40  13924.24
0.54    200.00  199.30  13925.05
0.47    200.00  203.42  13925.85
0.41    200.00  205.18  13926.67
0.34    200.00  205.84  13927.50
0.27    200.00  206.98  13928.33
0.34    200.00  204.10  13929.15
0.41    200.00  202.14  13929.97
0.34    200.00  206.28  13930.79
0.27    200.00  205.41  13931.60
0.34    200.00  201.93  13932.42
0.41    200.00  201.02  13933.23
0.34    200.00  203.42  13934.04
0.41    200.00  197.83  13934.85
0.34    200.00  203.86  13935.65
0.27    200.00  205.62  13936.49
0.34    200.00  199.94  13937.27
0.27    200.00  202.10  13938.07
0.20    200.00  202.32  13938.88
0.14    200.00  204.53  13939.66
0.20    200.00  195.69  13940.45
0.14    200.00  200.45  13941.21
0.20    200.00  191.95  13941.97
0.14    200.00  194.68  13942.73
0.20    200.00  189.17  13943.47
0.14    200.00  192.61  13944.19
0.20    200.00  191.53  13944.90
0.27    200.00  189.81  13945.62
0.33    200.00  186.78  13946.32
0.40    200.00  186.36  13947.01
0.46    200.00  181.49  13947.69
0.40    200.00  187.83  13948.40
0.46    200.00  190.66  13949.13
0.53    200.00  179.25  13949.81
0.50    200.00  185.11  13950.54
0.43    200.00  191.31  13951.25

But, the index pin still has no effect. I use an oscilloscope to measure the index pin signal and it looks normal when the motor is rotating.

Below are the parameters of my motor:

parameter value
Nominal voltage 18 V
No load speed 10400 rpm
No load current 50.6 mA
Nominal speed 9190 rpm
Nominal torque (max. continuous torque) 29.1 mNm
Nominal current (max. continuous current) 1.85 A
Stall torque 297 mNm
Stall current 18.4 A
Max. efficiency 86 %
askuric commented 4 years ago

Hey @Meekdai , perfect! Ok so your motor is rated to 10400rpm on 18V given that the range is linear at 12V you should be able to have:

12V/18V * 10400rpm = 6950rmp ~ 750rad/s

So 500rad/s should not be the limit yet.

Regarding the index pin, I don't really know why it doesn't work. Your motor never finds the index? The motor spins and then you get the message:

DEBUG: Error: Index not found!

or you don't get even that?

askuric commented 4 years ago

You can do one simple test to see what's going on:

ISR (PCINT1_vect) { 
   encoder.handleIndex(); 
   Serial.print("Index interrupt triggered");
}

Then you can disconnect the motor and spin it by hand to see if this code is ever going to be executed.

Meekdai commented 4 years ago

Thanks @askuric , Your library is really great, let me successfully control the DC motor. I also learned a lot from it. I don’t have a high requirement for speed, so I hope to try position control.

Meekdai commented 4 years ago

Hi @askuric , Use A0 pin, When I Rotating the motor I can not get the message "Index interrupt triggered", So I use int.2 to encoder index pin.

Encoder encoder = Encoder(arduinoInt1, arduinoInt2, 128, 21);

void index(){
  encoder.handleIndex(); 
  Serial.print("Index interrupt triggered");
}
void setup() {
  Serial.begin(115200);
  attachInterrupt(2, index, FALLING);
}

When I Rotating the motor, I can get the message "Index interrupt triggered", but the log block at:

DEBUG: Initilaise the motor pins.
DEBUG: Set high frequency PWM.
DEBUG: Enabling motor.
DEBUG: Align the encoder and motor electrical 0 angle.
DEBUG: Search for the encoder index.

I don't get DEBUG: Error: Index not found! never.

askuric commented 4 years ago

Hey @Meekdai, the reason may be because I have considered index of the encoder to be rising edge signal. I am not sure why this code doesn't work properly for you.

I have chnaged the code a bit and pushed it to the master branch.

Basically now you will create the handler funciton

void doIndex(){encoder.handleIndex();}

And if you have enough interrupts you can put it into the encoder.init():

  encoder.init(doA, doB, doIndex);

or if you have only two for A and B, you do as before with this approach:

ISR(PCINTx_vect){doIndex;}

I hope it helps

Meekdai commented 4 years ago

Hi, @askuric good news.

DEBUG: Serial debugger enabled!
DEBUG: Initilaise the motor pins.
DEBUG: Set high frequency PWM.
DEBUG: Enabling motor.
DEBUG: Align the encoder and motor electrical 0 angle.
DEBUG: Search for the encoder index.
DEBUG: Success: Index found!
Motor ready.
Input the new target velocity:
0.00    0.00    0.00    0.38
0.00    0.00    0.00    0.38

Now it can find the index correctly!thanks a lot.

askuric commented 4 years ago

Hey @Meekdai, perfect! I am still not sure why the previous approach did not work, I will have to look into it a bit deeper.

Also I will create a library from this repo in next few days with a bit more examples. For now you I will upload another minimal example of the position control so you can test it.

Antun

Meekdai commented 4 years ago

Very thankful @askuric I tried angle before use my code, and I found that the serial input is invalid. I will test your example code for the first time tomorrow.