Kenji Arai / DRV8830

Dependents:   NucleoF401_motor_test_simple Frequency_Counter_w_GPS_1PPS Nucleo_ACM1602_I2C_DC_Angle Frequency_Cntr_1PPS_F746ZG

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DRV8830.cpp Source File

DRV8830.cpp

00001 /*
00002  * mbed library program 
00003  *  Texas Instruments / DRV8830 H-Bridge Voltage-Controlled Motor Driver
00004  *      http://www.ti.com/product/drv8830
00005  *
00006  * Copyright (c) 2014,'17 Kenji Arai / JH1PJL
00007  *  http://www.page.sannet.ne.jp/kenjia/index.html
00008  *  http://mbed.org/users/kenjiArai/
00009  *      Created: August      6th, 2014
00010  *      Revised: August     23rd, 2017
00011  */
00012 
00013 #include    "mbed.h"
00014 #include    "DRV8830.h"
00015 
00016 //  motor status
00017 #define DRV8830_FREE            0x00
00018 #define DRV8830_CW              0x01
00019 #define DRV8830_CCW             0x02
00020 #define DRV8830_BREAK           0x03
00021 
00022 //  register address
00023 #define DRV8830_CONTROL         0x00
00024 #define DRV8830_FAULT           0x01
00025 
00026 //  voltage data
00027 #define DRV8830_V_R48           0x06
00028 #define DRV8830_V_R56           0x07
00029 #define DRV8830_V_R64           0x08
00030 #define DRV8830_V_R72           0x09
00031     // (no definition from 0.82V to 4.74V)
00032 #define DRV8830_V_4R82          0x3c
00033 #define DRV8830_V_4R90          0x3d
00034 #define DRV8830_V_4R98          0x3e
00035 #define DRV8830_V_5R06          0x3f
00036 
00037 #define DRV8830_V_MIN           0x06
00038 #define DRV8830_V_MAX           0x3f
00039 #define DRV8830_V_RANGE         (DRV8830_V_MAX - DRV8830_V_MIN)
00040 
00041 //  fault status
00042 #define DRV8830_F_CLEAR         0x80
00043 
00044 // Voltage Control
00045 #define DRV8830_FREE            0x00
00046 #define DRV8830_POSI            0x01
00047 #define DRV8830_NEGA            0x02
00048 #define DRV8830_BREAK           0x03
00049 
00050 // Voltage table
00051 #define TBL_OFFSET              0x06
00052 #define TBL_SIZE                58
00053 #define TBL_MAX_VALUE           (5.06f)
00054 #define TBL_MIN_VALUE           (0.48f)
00055 
00056 const float voltage_table [] = {
00057     0.48,    0.56,    0.64,    0.72,    0.80,    0.88,    0.96,    1.04,
00058     1.12,    1.20,    1.29,    1.37,    1.45,    1.53,    1.61,    1.69,
00059     1.77,    1.85,    1.93,    2.01,    2.09,    2.17,    2.25,    2.33,
00060     2.41,    2.49,    2.57,    2.65,    2.73,    2.81,    2.89,    2.97,
00061     3.05,    3.13,    3.21,    3.29,    3.37,    3.45,    3.53,    3.61,
00062     3.69,    3.77,    3.86,    3.94,    4.02,    4.10,    4.18,    4.26,
00063     4.34,    4.42,    4.50,    4.58,    4.66,    4.74,    4.82,    4.90,
00064     4.98,    5.06
00065 };
00066 
00067 DRV8830::DRV8830 (PinName p_sda, PinName p_scl, uint8_t addr)
00068  : _i2c_p(new I2C(p_sda, p_scl)), _i2c(*_i2c_p)
00069 {
00070     DRV8830_addr = (char)addr;
00071 }
00072 
00073 DRV8830::DRV8830 (I2C& p_i2c, uint8_t addr)
00074  : _i2c(p_i2c)
00075 { 
00076     DRV8830_addr = (char)addr;
00077 }
00078 
00079 void DRV8830::speed(float speed) {
00080 uint8_t direction = 0;
00081 uint8_t pwm_rate = 0;
00082 uint8_t dt[2];
00083 
00084     if (speed == 0.0f ){
00085         pwm_rate = DRV8830_V_MIN;
00086         direction = DRV8830_FREE;
00087     } else if (speed > 0.0f){
00088         pwm_rate = (uint8_t)(DRV8830_V_RANGE * speed) + DRV8830_V_MIN;
00089         direction = DRV8830_CW;
00090     } else if (speed < 0.0f){
00091         speed *= -1.0f;
00092         pwm_rate = (uint8_t)(DRV8830_V_RANGE * speed) + DRV8830_V_MIN;
00093         direction = DRV8830_CCW;
00094     }
00095     if (pwm_rate > DRV8830_V_MAX){
00096         pwm_rate = DRV8830_V_MAX;
00097     } else if (pwm_rate < DRV8830_V_MIN){
00098         pwm_rate = DRV8830_V_MIN;
00099     }
00100     dt[0] = DRV8830_CONTROL;
00101     dt[1] = (pwm_rate << 2) + direction;
00102     _i2c.write((int)DRV8830_addr, (char *)dt, 2);
00103 }
00104 
00105 void DRV8830::set_voltage(float volt) {
00106 uint8_t direction = 0;
00107 uint8_t pwm_rate = 0;
00108 uint8_t dt[2];
00109 
00110     if (volt < 0){
00111         direction = DRV8830_NEGA;
00112         volt *= -1;
00113     } else {
00114         direction = DRV8830_POSI; 
00115     }
00116     if (volt >= TBL_MAX_VALUE) {
00117         pwm_rate = TBL_SIZE + TBL_OFFSET - 1;
00118     } else {
00119         for (uint32_t i = 0; i < TBL_SIZE; i++){ 
00120             if (volt < voltage_table[i]) {
00121                 //printf("n=%d, voltage_table[i]=%f\r\n", i, voltage_table[i]);
00122                 if (i == 0){
00123                     pwm_rate = 0;
00124                     direction = DRV8830_FREE;
00125                 } else {
00126                     pwm_rate = i + TBL_OFFSET;
00127                 }
00128                 break;
00129             }
00130         } 
00131     }
00132     //printf("volt=%f, pwm=0x%x, dir=%d\r\n", volt, pwm_rate, direction);
00133     dt[0] = DRV8830_CONTROL;
00134     dt[1] = (pwm_rate << 2) + direction;
00135     _i2c.write((int)DRV8830_addr, (char *)dt, 2);
00136 }
00137 
00138 uint8_t DRV8830::status() {
00139 uint8_t dt[2];
00140 
00141     dt[0] = DRV8830_FAULT;
00142     _i2c.write((int)DRV8830_addr, (char *)dt, 1);  // write register address
00143     _i2c.read((int)DRV8830_addr, (char *)dt, 1);   // read register content
00144     return dt[0];
00145 }
00146 
00147 void DRV8830::reset() {
00148 uint8_t dt[2];
00149 
00150     dt[0] = DRV8830_FAULT;
00151     dt[1] = DRV8830_F_CLEAR;
00152     _i2c.write((int)DRV8830_addr, (char *)dt, 2);
00153 }
00154 
00155 
00156