Default mbed pwm doesn't have enough resolution at high frequencies, thats why I implemented VNH5019 Motor carrier with FastPWM.
Fork of VNH5019 by
VNH5019.h@5:b5f360a16354, 2014-08-07 (annotated)
- Committer:
- ianmcc
- Date:
- Thu Aug 07 12:23:30 2014 +0000
- Revision:
- 5:b5f360a16354
- Parent:
- 2:d670a4b999ab
- Child:
- 6:c8343fa0f3b4
Added VNH5019Accel for a drop-in replacement for the VNH5019 but has a built-in acceleration limiter. Default maximum acceleration will result in ramping up to maximum speed in 1/4 second.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ianmcc | 0:5d3ab0ea7f27 | 1 | #ifndef DualVNH5019MotorShield_h |
ianmcc | 0:5d3ab0ea7f27 | 2 | #define DualVNH5019MotorShield_h |
ianmcc | 0:5d3ab0ea7f27 | 3 | |
ianmcc | 0:5d3ab0ea7f27 | 4 | #include <mbed.h> |
ianmcc | 0:5d3ab0ea7f27 | 5 | |
ianmcc | 1:5e8d9ed18f0f | 6 | class VNH5019 |
ianmcc | 1:5e8d9ed18f0f | 7 | { |
ianmcc | 1:5e8d9ed18f0f | 8 | public: |
ianmcc | 1:5e8d9ed18f0f | 9 | VNH5019(PinName INA_, PinName INB_, PinName ENDIAG_, PinName CS_, PinName PWM_); |
ianmcc | 1:5e8d9ed18f0f | 10 | |
ianmcc | 1:5e8d9ed18f0f | 11 | // set motor speed from -1.0 to +1.0 |
ianmcc | 1:5e8d9ed18f0f | 12 | void speed(float Speed); |
ianmcc | 1:5e8d9ed18f0f | 13 | |
ianmcc | 1:5e8d9ed18f0f | 14 | // stop (no current to the motors) |
ianmcc | 1:5e8d9ed18f0f | 15 | void stop(); |
ianmcc | 1:5e8d9ed18f0f | 16 | |
ianmcc | 1:5e8d9ed18f0f | 17 | // Brake, with strength 0..1 |
ianmcc | 1:5e8d9ed18f0f | 18 | void brake(float Brake); |
ianmcc | 1:5e8d9ed18f0f | 19 | |
ianmcc | 1:5e8d9ed18f0f | 20 | // returns the current through the motor, in mA |
ianmcc | 1:5e8d9ed18f0f | 21 | float get_current_mA(); |
ianmcc | 1:5e8d9ed18f0f | 22 | |
ianmcc | 1:5e8d9ed18f0f | 23 | // returns true if there has been a fault |
ianmcc | 1:5e8d9ed18f0f | 24 | bool is_fault(); |
ianmcc | 1:5e8d9ed18f0f | 25 | |
ianmcc | 1:5e8d9ed18f0f | 26 | // Clears the fault condition |
ianmcc | 1:5e8d9ed18f0f | 27 | // PRECONDITION: is_fault() |
ianmcc | 1:5e8d9ed18f0f | 28 | void clear_fault(); |
ianmcc | 1:5e8d9ed18f0f | 29 | |
ianmcc | 1:5e8d9ed18f0f | 30 | // disable the motor, and set outputs to zero. This is a low power mode. |
ianmcc | 1:5e8d9ed18f0f | 31 | void disable(); |
ianmcc | 1:5e8d9ed18f0f | 32 | |
ianmcc | 1:5e8d9ed18f0f | 33 | // enable the motor. |
ianmcc | 1:5e8d9ed18f0f | 34 | void enable(); |
ianmcc | 2:d670a4b999ab | 35 | |
ianmcc | 2:d670a4b999ab | 36 | // set the PWM period of oscillation in seconds |
ianmcc | 2:d670a4b999ab | 37 | void set_pwm_period(float p) |
ianmcc | 2:d670a4b999ab | 38 | { PWM.period(p); } |
ianmcc | 1:5e8d9ed18f0f | 39 | |
ianmcc | 1:5e8d9ed18f0f | 40 | private: |
ianmcc | 2:d670a4b999ab | 41 | void init(); |
ianmcc | 1:5e8d9ed18f0f | 42 | |
ianmcc | 1:5e8d9ed18f0f | 43 | DigitalOut INA; |
ianmcc | 1:5e8d9ed18f0f | 44 | DigitalOut INB; |
ianmcc | 1:5e8d9ed18f0f | 45 | DigitalInOut ENDIAG; |
ianmcc | 1:5e8d9ed18f0f | 46 | AnalogIn CS; |
ianmcc | 1:5e8d9ed18f0f | 47 | PwmOut PWM; |
ianmcc | 1:5e8d9ed18f0f | 48 | }; |
ianmcc | 1:5e8d9ed18f0f | 49 | |
ianmcc | 1:5e8d9ed18f0f | 50 | // Helper class for the Pololu dual VNH5019 motor shield. |
ianmcc | 1:5e8d9ed18f0f | 51 | // The default constructor uses the default arduino pins. |
ianmcc | 1:5e8d9ed18f0f | 52 | // The motors can be accessed either by .m1 or .m2, or by operator()(i) where i is 1 or 2. |
ianmcc | 0:5d3ab0ea7f27 | 53 | class DualVNH5019MotorShield |
ianmcc | 0:5d3ab0ea7f27 | 54 | { |
ianmcc | 0:5d3ab0ea7f27 | 55 | public: |
ianmcc | 0:5d3ab0ea7f27 | 56 | // default pin selection |
ianmcc | 0:5d3ab0ea7f27 | 57 | DualVNH5019MotorShield(); // Default pin selection. |
ianmcc | 0:5d3ab0ea7f27 | 58 | |
ianmcc | 0:5d3ab0ea7f27 | 59 | // User-defined pin selection. |
ianmcc | 0:5d3ab0ea7f27 | 60 | DualVNH5019MotorShield(PinName INA1_, PinName INB1_, PinName ENDIAG1_, PinName CS1_, PinName PWM1_, |
ianmcc | 0:5d3ab0ea7f27 | 61 | PinName INA2_, PinName INB2_, PinName ENDIAG2_, PinName CS2_, PinName PWM2_); |
ianmcc | 0:5d3ab0ea7f27 | 62 | |
ianmcc | 1:5e8d9ed18f0f | 63 | // returns the given motor object, 1 or 2. |
ianmcc | 1:5e8d9ed18f0f | 64 | VNH5019& operator()(int m); |
ianmcc | 0:5d3ab0ea7f27 | 65 | |
ianmcc | 1:5e8d9ed18f0f | 66 | VNH5019 m1; |
ianmcc | 1:5e8d9ed18f0f | 67 | VNH5019 m2; |
ianmcc | 0:5d3ab0ea7f27 | 68 | }; |
ianmcc | 0:5d3ab0ea7f27 | 69 | |
ianmcc | 5:b5f360a16354 | 70 | inline |
ianmcc | 5:b5f360a16354 | 71 | void VNH5019::stop() |
ianmcc | 5:b5f360a16354 | 72 | { |
ianmcc | 5:b5f360a16354 | 73 | INA = 0; |
ianmcc | 5:b5f360a16354 | 74 | INB = 0; |
ianmcc | 5:b5f360a16354 | 75 | PWM = 0.0; |
ianmcc | 5:b5f360a16354 | 76 | } |
ianmcc | 5:b5f360a16354 | 77 | |
ianmcc | 5:b5f360a16354 | 78 | inline |
ianmcc | 5:b5f360a16354 | 79 | void VNH5019::brake(float Brake) |
ianmcc | 5:b5f360a16354 | 80 | { |
ianmcc | 5:b5f360a16354 | 81 | // normalize Brake to 0..1 |
ianmcc | 5:b5f360a16354 | 82 | if (Brake < 0) |
ianmcc | 5:b5f360a16354 | 83 | Brake = -Brake; |
ianmcc | 5:b5f360a16354 | 84 | if (Brake > 1.0) |
ianmcc | 5:b5f360a16354 | 85 | Brake = 1.0; |
ianmcc | 5:b5f360a16354 | 86 | |
ianmcc | 5:b5f360a16354 | 87 | INA = 0; |
ianmcc | 5:b5f360a16354 | 88 | INB = 0; |
ianmcc | 5:b5f360a16354 | 89 | PWM = Brake; |
ianmcc | 5:b5f360a16354 | 90 | } |
ianmcc | 5:b5f360a16354 | 91 | |
ianmcc | 5:b5f360a16354 | 92 | inline |
ianmcc | 5:b5f360a16354 | 93 | float VNH5019::get_current_mA() |
ianmcc | 5:b5f360a16354 | 94 | { |
ianmcc | 5:b5f360a16354 | 95 | // Scale is 144mV per A |
ianmcc | 5:b5f360a16354 | 96 | // Scale factor is 3.3 / 0.144 = 22.916667 |
ianmcc | 5:b5f360a16354 | 97 | return CS.read() * 22.916667; |
ianmcc | 5:b5f360a16354 | 98 | } |
ianmcc | 5:b5f360a16354 | 99 | |
ianmcc | 5:b5f360a16354 | 100 | inline |
ianmcc | 5:b5f360a16354 | 101 | bool VNH5019::is_fault() |
ianmcc | 5:b5f360a16354 | 102 | { |
ianmcc | 5:b5f360a16354 | 103 | return !ENDIAG; |
ianmcc | 5:b5f360a16354 | 104 | } |
ianmcc | 5:b5f360a16354 | 105 | |
ianmcc | 5:b5f360a16354 | 106 | inline |
ianmcc | 5:b5f360a16354 | 107 | void VNH5019::disable() |
ianmcc | 5:b5f360a16354 | 108 | { |
ianmcc | 5:b5f360a16354 | 109 | ENDIAG.output(); |
ianmcc | 5:b5f360a16354 | 110 | ENDIAG.write(0); |
ianmcc | 5:b5f360a16354 | 111 | } |
ianmcc | 5:b5f360a16354 | 112 | |
ianmcc | 5:b5f360a16354 | 113 | inline |
ianmcc | 5:b5f360a16354 | 114 | void VNH5019::enable() |
ianmcc | 5:b5f360a16354 | 115 | { |
ianmcc | 5:b5f360a16354 | 116 | ENDIAG.input(); |
ianmcc | 5:b5f360a16354 | 117 | } |
ianmcc | 5:b5f360a16354 | 118 | |
ianmcc | 5:b5f360a16354 | 119 | inline |
ianmcc | 5:b5f360a16354 | 120 | DualVNH5019MotorShield::DualVNH5019MotorShield() |
ianmcc | 5:b5f360a16354 | 121 | : m1(PTD4, PTA4, PTC8, PTB0, PTD5), |
ianmcc | 5:b5f360a16354 | 122 | m2(PTC9, PTA13, PTD3, PTB1, PTD0) |
ianmcc | 5:b5f360a16354 | 123 | { |
ianmcc | 5:b5f360a16354 | 124 | } |
ianmcc | 5:b5f360a16354 | 125 | |
ianmcc | 5:b5f360a16354 | 126 | inline |
ianmcc | 5:b5f360a16354 | 127 | DualVNH5019MotorShield::DualVNH5019MotorShield(PinName INA1_, PinName INB1_, PinName ENDIAG1_, PinName CS1_, PinName PWM1_, |
ianmcc | 5:b5f360a16354 | 128 | PinName INA2_, PinName INB2_, PinName ENDIAG2_, PinName CS2_, PinName PWM2_) |
ianmcc | 5:b5f360a16354 | 129 | : m1(INA1_, INB1_, ENDIAG1_, CS1_, PWM1_), |
ianmcc | 5:b5f360a16354 | 130 | m2(INA2_, INB2_, ENDIAG2_, CS2_, PWM2_) |
ianmcc | 5:b5f360a16354 | 131 | { |
ianmcc | 5:b5f360a16354 | 132 | } |
ianmcc | 5:b5f360a16354 | 133 | |
ianmcc | 5:b5f360a16354 | 134 | inline |
ianmcc | 5:b5f360a16354 | 135 | VNH5019& |
ianmcc | 5:b5f360a16354 | 136 | DualVNH5019MotorShield::operator()(int m) |
ianmcc | 5:b5f360a16354 | 137 | { |
ianmcc | 5:b5f360a16354 | 138 | return m == 1 ? m1 : m2; |
ianmcc | 5:b5f360a16354 | 139 | } |
ianmcc | 5:b5f360a16354 | 140 | |
ianmcc | 5:b5f360a16354 | 141 | |
ianmcc | 0:5d3ab0ea7f27 | 142 | #endif |