Brushless motor control library with TB6612FNG

Dependents:   brushless_TB6612FNG gimbalController_brushless_IMU

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?

UserRevisionLine numberNew 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 }