Brushless motor control library with TB6612FNG
Dependents: brushless_TB6612FNG gimbalController_brushless_IMU
brushlessController_TB6612FNG.cpp@0:fcf00057b1a3, 2015-07-17 (annotated)
- Committer:
- BaserK
- Date:
- Fri Jul 17 11:29:51 2015 +0000
- Revision:
- 0:fcf00057b1a3
- Child:
- 1:b52603b6a822
first working commit of brushless motor control library with TB6612FNG
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
BaserK | 0:fcf00057b1a3 | 1 | /* Brushless motor control library with TB6612FNG |
BaserK | 0:fcf00057b1a3 | 2 | * |
BaserK | 0:fcf00057b1a3 | 3 | * @author: Baser Kandehir |
BaserK | 0:fcf00057b1a3 | 4 | * @date: July 17, 2015 |
BaserK | 0:fcf00057b1a3 | 5 | * @license: Use this code however you'd like |
BaserK | 0:fcf00057b1a3 | 6 | * |
BaserK | 0:fcf00057b1a3 | 7 | * @brief: |
BaserK | 0:fcf00057b1a3 | 8 | * |
BaserK | 0:fcf00057b1a3 | 9 | * This a brushless motor control library. Generally brushless motors can be controlled |
BaserK | 0:fcf00057b1a3 | 10 | * using ESC s and motor drivers like L6234,L6235 etc. I previously control a brushless motor |
BaserK | 0:fcf00057b1a3 | 11 | * with 2x L293D. Motor was a little bit shaking and its movement was not precise. The reason for that |
BaserK | 0:fcf00057b1a3 | 12 | * was my way of driving the motor was a little bit wrong and max pwm freq. for L293D was restricted to |
BaserK | 0:fcf00057b1a3 | 13 | * 5 kHz. Now I am using 2x TB6612FNG which has fast response and supports max switching freq. up to 100 kHz. |
BaserK | 0:fcf00057b1a3 | 14 | * The movement is really precise and results are remarkable. What makes this movement so precise is the way |
BaserK | 0:fcf00057b1a3 | 15 | * we control pwm outputs. Before then I was just using digital outputs and it didnt give perfect results. |
BaserK | 0:fcf00057b1a3 | 16 | * Now I am using the pwm method which creates sin wave like shapes at the outputs with 120 deg phase shift. |
BaserK | 0:fcf00057b1a3 | 17 | * I learned the method from this website, check out the website for more information: |
BaserK | 0:fcf00057b1a3 | 18 | * |
BaserK | 0:fcf00057b1a3 | 19 | * http://www.berryjam.eu/2015/04/driving-bldc-gimbals-at-super-slow-speeds-with-arduino/ |
BaserK | 0:fcf00057b1a3 | 20 | * |
BaserK | 0:fcf00057b1a3 | 21 | */ |
BaserK | 0:fcf00057b1a3 | 22 | |
BaserK | 0:fcf00057b1a3 | 23 | #include "brushlessController_TB6612FNG.h" |
BaserK | 0:fcf00057b1a3 | 24 | |
BaserK | 0:fcf00057b1a3 | 25 | PwmOut pwm[] = {(p21),(p22),(p24)}; // PWM outputs to drive brushless motor |
BaserK | 0:fcf00057b1a3 | 26 | |
BaserK | 0:fcf00057b1a3 | 27 | int step[3]; // Current steps of three pwm outputs |
BaserK | 0:fcf00057b1a3 | 28 | int sinArraySize; // Size of pwmSin array |
BaserK | 0:fcf00057b1a3 | 29 | int phaseShift; // Phase shift between outputs |
BaserK | 0:fcf00057b1a3 | 30 | bool firstTime = 1; |
BaserK | 0:fcf00057b1a3 | 31 | |
BaserK | 0:fcf00057b1a3 | 32 | /* Magical data array to drive the brushless motor */ |
BaserK | 0:fcf00057b1a3 | 33 | const int pwmSin[] = { // pwmSin data array consists of 360 samples |
BaserK | 0:fcf00057b1a3 | 34 | 128, 132, 136, 140, 143, 147, 151, 155, 159, 162, 166, 170, 174, 178, 181, 185, 189, 192, 196, 200, |
BaserK | 0:fcf00057b1a3 | 35 | 203, 207, 211, 214, 218, 221, 225, 228, 232, 235, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, |
BaserK | 0:fcf00057b1a3 | 36 | 248, 248, 249, 250, 250, 251, 252, 252, 253, 253, 253, 254, 254, 254, 255, 255, 255, 255, 255, 255, |
BaserK | 0:fcf00057b1a3 | 37 | 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 253, 253, 253, 252, 252, 251, 250, 250, 249, 248, |
BaserK | 0:fcf00057b1a3 | 38 | 248, 247, 246, 245, 244, 243, 242, 241, 240, 239, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, |
BaserK | 0:fcf00057b1a3 | 39 | 248, 248, 249, 250, 250, 251, 252, 252, 253, 253, 253, 254, 254, 254, 255, 255, 255, 255, 255, 255, |
BaserK | 0:fcf00057b1a3 | 40 | 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 253, 253, 253, 252, 252, 251, 250, 250, 249, 248, |
BaserK | 0:fcf00057b1a3 | 41 | 248, 247, 246, 245, 244, 243, 242, 241, 240, 239, 238, 235, 232, 228, 225, 221, 218, 214, 211, 207, |
BaserK | 0:fcf00057b1a3 | 42 | 203, 200, 196, 192, 189, 185, 181, 178, 174, 170, 166, 162, 159, 155, 151, 147, 143, 140, 136, 132, |
BaserK | 0:fcf00057b1a3 | 43 | 128, 124, 120, 116, 113, 109, 105, 101, 97, 94, 90, 86, 82, 78, 75, 71, 67, 64, 60, 56, |
BaserK | 0:fcf00057b1a3 | 44 | 53, 49, 45, 42, 38, 35, 31, 28, 24, 21, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, |
BaserK | 0:fcf00057b1a3 | 45 | 8, 8, 7, 6, 6, 5, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, |
BaserK | 0:fcf00057b1a3 | 46 | 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 6, 6, 7, 8, |
BaserK | 0:fcf00057b1a3 | 47 | 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, |
BaserK | 0:fcf00057b1a3 | 48 | 8, 8, 7, 6, 6, 5, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, |
BaserK | 0:fcf00057b1a3 | 49 | 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 6, 6, 7, 8, |
BaserK | 0:fcf00057b1a3 | 50 | 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 21, 24, 28, 31, 35, 38, 42, 45, 49, |
BaserK | 0:fcf00057b1a3 | 51 | 53, 56, 60, 64, 67, 71, 75, 78, 82, 86, 90, 94, 97, 101, 105, 109, 113, 116, 120, 124 |
BaserK | 0:fcf00057b1a3 | 52 | }; |
BaserK | 0:fcf00057b1a3 | 53 | |
BaserK | 0:fcf00057b1a3 | 54 | /* Brushless motor control function |
BaserK | 0:fcf00057b1a3 | 55 | * |
BaserK | 0:fcf00057b1a3 | 56 | * @brief: This function can control a brushless motor PRECISELY with TB6612FNG. |
BaserK | 0:fcf00057b1a3 | 57 | * It initializes the 3 pwm outputs with 20 kHz frequency. Function takes data |
BaserK | 0:fcf00057b1a3 | 58 | * from the pwmSin array and gives the data to the 3 pwm outputs with 120 deg |
BaserK | 0:fcf00057b1a3 | 59 | * phase shift. By doing so it can control a brushless motor precisely with |
BaserK | 0:fcf00057b1a3 | 60 | * simple DC motor drivers. |
BaserK | 0:fcf00057b1a3 | 61 | * |
BaserK | 0:fcf00057b1a3 | 62 | * @variables: |
BaserK | 0:fcf00057b1a3 | 63 | * dir: Direction of the motor |
BaserK | 0:fcf00057b1a3 | 64 | * delay_time: Time delay between steps |
BaserK | 0:fcf00057b1a3 | 65 | */ |
BaserK | 0:fcf00057b1a3 | 66 | void brushlessControl(bool dir, int delay_time) |
BaserK | 0:fcf00057b1a3 | 67 | { |
BaserK | 0:fcf00057b1a3 | 68 | if(firstTime == 1) // do it only once (initialization process) |
BaserK | 0:fcf00057b1a3 | 69 | { |
BaserK | 0:fcf00057b1a3 | 70 | for(int i=0; i<3; i++) |
BaserK | 0:fcf00057b1a3 | 71 | pwm[i].period(1/20000.0); // 20 kHz pwm frequency (inaudible) |
BaserK | 0:fcf00057b1a3 | 72 | |
BaserK | 0:fcf00057b1a3 | 73 | sinArraySize = sizeof(pwmSin) / sizeof(int); // 360 for this case |
BaserK | 0:fcf00057b1a3 | 74 | phaseShift = sinArraySize / 3 ; // 120 for the above case |
BaserK | 0:fcf00057b1a3 | 75 | |
BaserK | 0:fcf00057b1a3 | 76 | step[0] = 0; |
BaserK | 0:fcf00057b1a3 | 77 | step[1] = step[0] + phaseShift; |
BaserK | 0:fcf00057b1a3 | 78 | step[2] = step[1] + phaseShift; |
BaserK | 0:fcf00057b1a3 | 79 | |
BaserK | 0:fcf00057b1a3 | 80 | firstTime = 0; |
BaserK | 0:fcf00057b1a3 | 81 | } |
BaserK | 0:fcf00057b1a3 | 82 | |
BaserK | 0:fcf00057b1a3 | 83 | for(int k=0; k<3; k++) |
BaserK | 0:fcf00057b1a3 | 84 | { |
BaserK | 0:fcf00057b1a3 | 85 | /* PWM duty cycles are determined by the step numbers of the outputs, |
BaserK | 0:fcf00057b1a3 | 86 | corresponding data is taken from pwmSin array */ |
BaserK | 0:fcf00057b1a3 | 87 | pwm[k] = pwmSin[step[k]]/255.0; // Pwm takes values between 0 and 1.0 (float) |
BaserK | 0:fcf00057b1a3 | 88 | |
BaserK | 0:fcf00057b1a3 | 89 | (dir == 1)? (step[k]++):(step[k]--); // Motor direction control |
BaserK | 0:fcf00057b1a3 | 90 | |
BaserK | 0:fcf00057b1a3 | 91 | /* If array index exceeds the array size, start over */ |
BaserK | 0:fcf00057b1a3 | 92 | if(step[k] == sinArraySize - 1) step[k] = 0; |
BaserK | 0:fcf00057b1a3 | 93 | if(step[k] < 0) step[k] = sinArraySize - 1; |
BaserK | 0:fcf00057b1a3 | 94 | } |
BaserK | 0:fcf00057b1a3 | 95 | wait_ms(delay_time); |
BaserK | 0:fcf00057b1a3 | 96 | } |