Library for the VNH5019 Motor Driver, with a helper class for the Pololu Dual VNH5019 Dual Motor Driver Shield http://www.pololu.com/product/2502
Dependents: VNH5019_second VNH5019_second1
VNH5019.cpp@4:3802325cf6e1, 2014-07-29 (annotated)
- Committer:
- ianmcc
- Date:
- Tue Jul 29 14:25:40 2014 +0000
- Revision:
- 4:3802325cf6e1
- Parent:
- 3:2b139675f60d
- Child:
- 5:b5f360a16354
Set PWM to zero if we set the speed to zero
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ianmcc | 1:5e8d9ed18f0f | 1 | #include "VNH5019.h" |
ianmcc | 0:5d3ab0ea7f27 | 2 | |
ianmcc | 1:5e8d9ed18f0f | 3 | VNH5019::VNH5019(PinName INA_, PinName INB_, PinName ENDIAG_, PinName CS_, PinName PWM_) |
ianmcc | 1:5e8d9ed18f0f | 4 | : INA(INA_), |
ianmcc | 1:5e8d9ed18f0f | 5 | INB(INB_), |
ianmcc | 1:5e8d9ed18f0f | 6 | ENDIAG(ENDIAG_), |
ianmcc | 1:5e8d9ed18f0f | 7 | CS(CS_), |
ianmcc | 1:5e8d9ed18f0f | 8 | PWM(PWM_) |
ianmcc | 0:5d3ab0ea7f27 | 9 | { |
ianmcc | 0:5d3ab0ea7f27 | 10 | this->init(); |
ianmcc | 0:5d3ab0ea7f27 | 11 | } |
ianmcc | 0:5d3ab0ea7f27 | 12 | |
ianmcc | 1:5e8d9ed18f0f | 13 | void VNH5019::init() |
ianmcc | 0:5d3ab0ea7f27 | 14 | { |
ianmcc | 1:5e8d9ed18f0f | 15 | ENDIAG.input(); |
ianmcc | 1:5e8d9ed18f0f | 16 | ENDIAG.mode(PullUp); |
ianmcc | 1:5e8d9ed18f0f | 17 | PWM.period(0.00025); // 4 kHz (valid 0 - 20 kHz) |
ianmcc | 1:5e8d9ed18f0f | 18 | PWM.write(0); |
ianmcc | 1:5e8d9ed18f0f | 19 | INA = 0; |
ianmcc | 1:5e8d9ed18f0f | 20 | INB = 0; |
ianmcc | 0:5d3ab0ea7f27 | 21 | } |
ianmcc | 0:5d3ab0ea7f27 | 22 | |
ianmcc | 1:5e8d9ed18f0f | 23 | void VNH5019::speed(float Speed) |
ianmcc | 0:5d3ab0ea7f27 | 24 | { |
ianmcc | 0:5d3ab0ea7f27 | 25 | bool Reverse = 0; |
ianmcc | 0:5d3ab0ea7f27 | 26 | |
ianmcc | 0:5d3ab0ea7f27 | 27 | if (Speed < 0) |
ianmcc | 0:5d3ab0ea7f27 | 28 | { |
ianmcc | 0:5d3ab0ea7f27 | 29 | Speed = -Speed; // Make speed a positive quantity |
ianmcc | 0:5d3ab0ea7f27 | 30 | Reverse = 1; // Preserve the direction |
ianmcc | 0:5d3ab0ea7f27 | 31 | } |
ianmcc | 0:5d3ab0ea7f27 | 32 | |
ianmcc | 0:5d3ab0ea7f27 | 33 | // clamp the speed at maximum |
ianmcc | 0:5d3ab0ea7f27 | 34 | if (Speed > 1.0) |
ianmcc | 0:5d3ab0ea7f27 | 35 | Speed = 1.0; |
ianmcc | 0:5d3ab0ea7f27 | 36 | |
ianmcc | 0:5d3ab0ea7f27 | 37 | if (Speed == 0.0) |
ianmcc | 0:5d3ab0ea7f27 | 38 | { |
ianmcc | 1:5e8d9ed18f0f | 39 | INA = 0; |
ianmcc | 1:5e8d9ed18f0f | 40 | INB = 0; |
ianmcc | 4:3802325cf6e1 | 41 | PWM = 0; |
ianmcc | 0:5d3ab0ea7f27 | 42 | } |
ianmcc | 0:5d3ab0ea7f27 | 43 | else |
ianmcc | 0:5d3ab0ea7f27 | 44 | { |
ianmcc | 1:5e8d9ed18f0f | 45 | INA = !Reverse; |
ianmcc | 1:5e8d9ed18f0f | 46 | INB = Reverse; |
ianmcc | 1:5e8d9ed18f0f | 47 | PWM = Speed; |
ianmcc | 0:5d3ab0ea7f27 | 48 | } |
ianmcc | 0:5d3ab0ea7f27 | 49 | } |
ianmcc | 0:5d3ab0ea7f27 | 50 | |
ianmcc | 3:2b139675f60d | 51 | void VNH5019::stop() |
ianmcc | 3:2b139675f60d | 52 | { |
ianmcc | 3:2b139675f60d | 53 | INA = 0; |
ianmcc | 3:2b139675f60d | 54 | INB = 0; |
ianmcc | 3:2b139675f60d | 55 | PWM = 0.0; |
ianmcc | 3:2b139675f60d | 56 | } |
ianmcc | 3:2b139675f60d | 57 | |
ianmcc | 1:5e8d9ed18f0f | 58 | void VNH5019::brake(float Brake) |
ianmcc | 0:5d3ab0ea7f27 | 59 | { |
ianmcc | 0:5d3ab0ea7f27 | 60 | // normalize Brake to 0..1 |
ianmcc | 0:5d3ab0ea7f27 | 61 | if (Brake < 0) |
ianmcc | 1:5e8d9ed18f0f | 62 | Brake = -Brake; |
ianmcc | 0:5d3ab0ea7f27 | 63 | if (Brake > 1.0) |
ianmcc | 0:5d3ab0ea7f27 | 64 | Brake = 1.0; |
ianmcc | 0:5d3ab0ea7f27 | 65 | |
ianmcc | 1:5e8d9ed18f0f | 66 | INA = 0; |
ianmcc | 1:5e8d9ed18f0f | 67 | INB = 0; |
ianmcc | 1:5e8d9ed18f0f | 68 | PWM = Brake; |
ianmcc | 0:5d3ab0ea7f27 | 69 | } |
ianmcc | 0:5d3ab0ea7f27 | 70 | |
ianmcc | 1:5e8d9ed18f0f | 71 | float VNH5019::get_current_mA() |
ianmcc | 0:5d3ab0ea7f27 | 72 | { |
ianmcc | 0:5d3ab0ea7f27 | 73 | // Scale is 144mV per A |
ianmcc | 0:5d3ab0ea7f27 | 74 | // Scale factor is 3.3 / 0.144 = 22.916667 |
ianmcc | 1:5e8d9ed18f0f | 75 | return CS.read() * 22.916667; |
ianmcc | 0:5d3ab0ea7f27 | 76 | } |
ianmcc | 0:5d3ab0ea7f27 | 77 | |
ianmcc | 1:5e8d9ed18f0f | 78 | bool VNH5019::is_fault() |
ianmcc | 0:5d3ab0ea7f27 | 79 | { |
ianmcc | 1:5e8d9ed18f0f | 80 | return !ENDIAG; |
ianmcc | 0:5d3ab0ea7f27 | 81 | } |
ianmcc | 0:5d3ab0ea7f27 | 82 | |
ianmcc | 1:5e8d9ed18f0f | 83 | void VNH5019::clear_fault() |
ianmcc | 0:5d3ab0ea7f27 | 84 | { |
ianmcc | 0:5d3ab0ea7f27 | 85 | // if ENDIAG is high, then there is no fault |
ianmcc | 1:5e8d9ed18f0f | 86 | if (ENDIAG.read()) |
ianmcc | 0:5d3ab0ea7f27 | 87 | return; |
ianmcc | 0:5d3ab0ea7f27 | 88 | |
ianmcc | 0:5d3ab0ea7f27 | 89 | // toggle the inputs |
ianmcc | 1:5e8d9ed18f0f | 90 | INA = 0; |
ianmcc | 1:5e8d9ed18f0f | 91 | INB = 0; |
ianmcc | 0:5d3ab0ea7f27 | 92 | wait_us(250); |
ianmcc | 1:5e8d9ed18f0f | 93 | INA = 1; |
ianmcc | 1:5e8d9ed18f0f | 94 | INB = 1; |
ianmcc | 0:5d3ab0ea7f27 | 95 | wait_us(250); |
ianmcc | 0:5d3ab0ea7f27 | 96 | |
ianmcc | 0:5d3ab0ea7f27 | 97 | // pull low all inputs and wait 1600us for t_DEL |
ianmcc | 1:5e8d9ed18f0f | 98 | INA = 0; |
ianmcc | 1:5e8d9ed18f0f | 99 | INB = 0; |
ianmcc | 1:5e8d9ed18f0f | 100 | PWM = 0; |
ianmcc | 1:5e8d9ed18f0f | 101 | ENDIAG.output(); |
ianmcc | 1:5e8d9ed18f0f | 102 | ENDIAG = 0; |
ianmcc | 0:5d3ab0ea7f27 | 103 | wait_us(1600); |
ianmcc | 0:5d3ab0ea7f27 | 104 | |
ianmcc | 0:5d3ab0ea7f27 | 105 | // and finally re-enable the motor |
ianmcc | 1:5e8d9ed18f0f | 106 | ENDIAG.input(); |
ianmcc | 0:5d3ab0ea7f27 | 107 | } |
ianmcc | 1:5e8d9ed18f0f | 108 | |
ianmcc | 1:5e8d9ed18f0f | 109 | void VNH5019::disable() |
ianmcc | 0:5d3ab0ea7f27 | 110 | { |
ianmcc | 1:5e8d9ed18f0f | 111 | ENDIAG.output(); |
ianmcc | 1:5e8d9ed18f0f | 112 | ENDIAG.write(0); |
ianmcc | 0:5d3ab0ea7f27 | 113 | } |
ianmcc | 0:5d3ab0ea7f27 | 114 | |
ianmcc | 1:5e8d9ed18f0f | 115 | void VNH5019::enable() |
ianmcc | 0:5d3ab0ea7f27 | 116 | { |
ianmcc | 1:5e8d9ed18f0f | 117 | ENDIAG.input(); |
ianmcc | 0:5d3ab0ea7f27 | 118 | } |
ianmcc | 0:5d3ab0ea7f27 | 119 | |
ianmcc | 1:5e8d9ed18f0f | 120 | DualVNH5019MotorShield::DualVNH5019MotorShield() |
ianmcc | 1:5e8d9ed18f0f | 121 | : m1(PTD4, PTA4, PTC8, PTB0, PTD5), |
ianmcc | 1:5e8d9ed18f0f | 122 | m2(PTC9, PTA13, PTD3, PTB1, PTD0) |
ianmcc | 0:5d3ab0ea7f27 | 123 | { |
ianmcc | 0:5d3ab0ea7f27 | 124 | } |
ianmcc | 0:5d3ab0ea7f27 | 125 | |
ianmcc | 1:5e8d9ed18f0f | 126 | DualVNH5019MotorShield::DualVNH5019MotorShield(PinName INA1_, PinName INB1_, PinName ENDIAG1_, PinName CS1_, PinName PWM1_, |
ianmcc | 1:5e8d9ed18f0f | 127 | PinName INA2_, PinName INB2_, PinName ENDIAG2_, PinName CS2_, PinName PWM2_) |
ianmcc | 1:5e8d9ed18f0f | 128 | : m1(INA1_, INB1_, ENDIAG1_, CS1_, PWM1_), |
ianmcc | 1:5e8d9ed18f0f | 129 | m2(INA2_, INB2_, ENDIAG2_, CS2_, PWM2_) |
ianmcc | 0:5d3ab0ea7f27 | 130 | { |
ianmcc | 0:5d3ab0ea7f27 | 131 | } |
ianmcc | 1:5e8d9ed18f0f | 132 | |
ianmcc | 1:5e8d9ed18f0f | 133 | VNH5019& |
ianmcc | 1:5e8d9ed18f0f | 134 | DualVNH5019MotorShield::operator()(int m) |
ianmcc | 1:5e8d9ed18f0f | 135 | { |
ianmcc | 1:5e8d9ed18f0f | 136 | return m == 1 ? m1 : m2; |
ianmcc | 1:5e8d9ed18f0f | 137 | } |