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

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?

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