Default mbed pwm doesn't have enough resolution at high frequencies, thats why I implemented VNH5019 Motor carrier with FastPWM.

Dependencies:   FastPWM

Fork of VNH5019 by IEEE RAS METU

Committer:
ianmcc
Date:
Thu Aug 07 12:23:30 2014 +0000
Revision:
5:b5f360a16354
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?

UserRevisionLine numberNew contents of line
ianmcc 5:b5f360a16354 1 // VNH5015 driver with acceleration control
ianmcc 5:b5f360a16354 2 // A drop-in replacement for the basic VNH5019
ianmcc 5:b5f360a16354 3
ianmcc 5:b5f360a16354 4 #if !defined(VNH5019ACCEL_H)
ianmcc 5:b5f360a16354 5 #define VNH5019ACCEL_H
ianmcc 5:b5f360a16354 6
ianmcc 5:b5f360a16354 7 #include "VNH5019.h"
ianmcc 5:b5f360a16354 8 #include <Ticker.h>
ianmcc 5:b5f360a16354 9
ianmcc 5:b5f360a16354 10 // The maximum acceleration, in fractions of full speed per second
ianmcc 5:b5f360a16354 11 float const VNH5019MaxAccel = 4;
ianmcc 5:b5f360a16354 12
ianmcc 5:b5f360a16354 13 // Tick period in microseconds for updating the speed
ianmcc 5:b5f360a16354 14 int const VNH5019Tick_us = 20000;
ianmcc 5:b5f360a16354 15
ianmcc 5:b5f360a16354 16 float const VNH5019ChangePerTick = VNH5019MaxAccel * VNH5019Tick_us / 1000000;
ianmcc 5:b5f360a16354 17
ianmcc 5:b5f360a16354 18 // allow braking to come on faster
ianmcc 5:b5f360a16354 19 float const VNH5019BrakeChangePerTick = VNH5019ChangePerTick*10;
ianmcc 5:b5f360a16354 20
ianmcc 5:b5f360a16354 21 class VNH5019Accel
ianmcc 5:b5f360a16354 22 {
ianmcc 5:b5f360a16354 23 public:
ianmcc 5:b5f360a16354 24 VNH5019Accel(PinName INA_, PinName INB_, PinName ENDIAG_, PinName CS_, PinName PWM_)
ianmcc 5:b5f360a16354 25 : Driver(INA_, INB_, ENDIAG_, CS_, PWM_),
ianmcc 5:b5f360a16354 26 CurrentSpeed(0.0),
ianmcc 5:b5f360a16354 27 CurrentBrake(0.0),
ianmcc 5:b5f360a16354 28 RequestedSpeed(0.0),
ianmcc 5:b5f360a16354 29 RequestedBrake(0.0)
ianmcc 5:b5f360a16354 30 {
ianmcc 5:b5f360a16354 31 timer.attach_us(this, &VNH5019Accel::Interrupt, VNH5019Tick_us);
ianmcc 5:b5f360a16354 32 }
ianmcc 5:b5f360a16354 33
ianmcc 5:b5f360a16354 34 // set motor speed from -1.0 to +1.0
ianmcc 5:b5f360a16354 35 void speed(float Speed)
ianmcc 5:b5f360a16354 36 {
ianmcc 5:b5f360a16354 37 if (Speed < -1.0)
ianmcc 5:b5f360a16354 38 Speed = 1.0;
ianmcc 5:b5f360a16354 39 else if (Speed > 1.0)
ianmcc 5:b5f360a16354 40 Speed = 1.0;
ianmcc 5:b5f360a16354 41 RequestedSpeed = Speed;
ianmcc 5:b5f360a16354 42 }
ianmcc 5:b5f360a16354 43
ianmcc 5:b5f360a16354 44 // stop (no current to the motors)
ianmcc 5:b5f360a16354 45 void stop()
ianmcc 5:b5f360a16354 46 {
ianmcc 5:b5f360a16354 47 RequestedSpeed = 0.0;
ianmcc 5:b5f360a16354 48 }
ianmcc 5:b5f360a16354 49
ianmcc 5:b5f360a16354 50 // Brake, with strength 0..1
ianmcc 5:b5f360a16354 51 void brake(float Brake)
ianmcc 5:b5f360a16354 52 {
ianmcc 5:b5f360a16354 53 if (Brake < 0.0)
ianmcc 5:b5f360a16354 54 Brake = 0;
ianmcc 5:b5f360a16354 55 else if (Brake > 1.0)
ianmcc 5:b5f360a16354 56 Brake = 1.0;
ianmcc 5:b5f360a16354 57 RequestedBrake = Brake;
ianmcc 5:b5f360a16354 58 RequestedSpeed = 0.0;
ianmcc 5:b5f360a16354 59 }
ianmcc 5:b5f360a16354 60
ianmcc 5:b5f360a16354 61 // returns the current through the motor, in mA
ianmcc 5:b5f360a16354 62 float get_current_mA()
ianmcc 5:b5f360a16354 63 {
ianmcc 5:b5f360a16354 64 return Driver.get_current_mA();
ianmcc 5:b5f360a16354 65 }
ianmcc 5:b5f360a16354 66
ianmcc 5:b5f360a16354 67 // returns true if there has been a fault
ianmcc 5:b5f360a16354 68 bool is_fault()
ianmcc 5:b5f360a16354 69 {
ianmcc 5:b5f360a16354 70 return Driver.is_fault();
ianmcc 5:b5f360a16354 71 }
ianmcc 5:b5f360a16354 72
ianmcc 5:b5f360a16354 73 // Clears the fault condition
ianmcc 5:b5f360a16354 74 // PRECONDITION: is_fault()
ianmcc 5:b5f360a16354 75 void clear_fault()
ianmcc 5:b5f360a16354 76 {
ianmcc 5:b5f360a16354 77 timer.detach();
ianmcc 5:b5f360a16354 78 Driver.clear_fault();
ianmcc 5:b5f360a16354 79 timer.attach_us(this, &VNH5019Accel::Interrupt, VNH5019Tick_us);
ianmcc 5:b5f360a16354 80 }
ianmcc 5:b5f360a16354 81
ianmcc 5:b5f360a16354 82 // disable the motor, and set outputs to zero. This is a low power mode.
ianmcc 5:b5f360a16354 83 void disable()
ianmcc 5:b5f360a16354 84 {
ianmcc 5:b5f360a16354 85 timer.detach();
ianmcc 5:b5f360a16354 86 Driver.disable();
ianmcc 5:b5f360a16354 87 }
ianmcc 5:b5f360a16354 88
ianmcc 5:b5f360a16354 89 // enable the motor.
ianmcc 5:b5f360a16354 90 void enable()
ianmcc 5:b5f360a16354 91 {
ianmcc 5:b5f360a16354 92 timer.detach();
ianmcc 5:b5f360a16354 93 Driver.enable();
ianmcc 5:b5f360a16354 94 timer.attach_us(this, &VNH5019Accel::Interrupt, VNH5019Tick_us);
ianmcc 5:b5f360a16354 95 }
ianmcc 5:b5f360a16354 96
ianmcc 5:b5f360a16354 97 // set the PWM period of oscillation in seconds
ianmcc 5:b5f360a16354 98 void set_pwm_period(float p)
ianmcc 5:b5f360a16354 99 {
ianmcc 5:b5f360a16354 100 Driver.set_pwm_period(p);
ianmcc 5:b5f360a16354 101 }
ianmcc 5:b5f360a16354 102
ianmcc 5:b5f360a16354 103 private:
ianmcc 5:b5f360a16354 104 VNH5019 Driver;
ianmcc 5:b5f360a16354 105 Ticker timer;
ianmcc 5:b5f360a16354 106 float CurrentSpeed; // this is only ever accessed from the ISR, so no need for volatile
ianmcc 5:b5f360a16354 107 float CurrentBrake;
ianmcc 5:b5f360a16354 108 volatile float RequestedSpeed;
ianmcc 5:b5f360a16354 109 volatile float RequestedBrake;
ianmcc 5:b5f360a16354 110 void Interrupt();
ianmcc 5:b5f360a16354 111 };
ianmcc 5:b5f360a16354 112
ianmcc 5:b5f360a16354 113 // Helper class for the Pololu dual VNH5019 motor shield.
ianmcc 5:b5f360a16354 114 // The default constructor uses the default arduino pins.
ianmcc 5:b5f360a16354 115 // The motors can be accessed either by .m1 or .m2, or by operator()(i) where i is 1 or 2.
ianmcc 5:b5f360a16354 116 class DualVNH5019AccelMotorShield
ianmcc 5:b5f360a16354 117 {
ianmcc 5:b5f360a16354 118 public:
ianmcc 5:b5f360a16354 119 // default pin selection
ianmcc 5:b5f360a16354 120 DualVNH5019AccelMotorShield(); // Default pin selection.
ianmcc 5:b5f360a16354 121
ianmcc 5:b5f360a16354 122 // User-defined pin selection.
ianmcc 5:b5f360a16354 123 DualVNH5019AccelMotorShield(PinName INA1_, PinName INB1_, PinName ENDIAG1_, PinName CS1_, PinName PWM1_,
ianmcc 5:b5f360a16354 124 PinName INA2_, PinName INB2_, PinName ENDIAG2_, PinName CS2_, PinName PWM2_)
ianmcc 5:b5f360a16354 125 : m1(INA1_, INB1_, ENDIAG1_, CS1_, PWM1_),
ianmcc 5:b5f360a16354 126 m2(INA2_, INB2_, ENDIAG2_, CS2_, PWM2_)
ianmcc 5:b5f360a16354 127 {
ianmcc 5:b5f360a16354 128 }
ianmcc 5:b5f360a16354 129
ianmcc 5:b5f360a16354 130 // returns the given motor object, 1 or 2.
ianmcc 5:b5f360a16354 131 VNH5019Accel& operator()(int m)
ianmcc 5:b5f360a16354 132 {
ianmcc 5:b5f360a16354 133 return m == 1 ? m1 : m2;
ianmcc 5:b5f360a16354 134 }
ianmcc 5:b5f360a16354 135
ianmcc 5:b5f360a16354 136 VNH5019Accel m1;
ianmcc 5:b5f360a16354 137 VNH5019Accel m2;
ianmcc 5:b5f360a16354 138 };
ianmcc 5:b5f360a16354 139
ianmcc 5:b5f360a16354 140 #endif