I finally got around to implementing a motor function that operates the motor properly in both forward and reverse. The original example code as posted only operates the motor in one direction. Also the original code uses the same pin for the PWM signal to control motor speed. Even if you do get this approach to work it will result in nonsymmetrical motor operation, since in one direction the motor will coast on the low portion of the PWM signal and in the other direction it will brake. The code below operates both directions symmetrically.
/* Tiny Motor Function
This program operates the TinyShield Motor Driver x 4 in a function. Board description is at:
http://tiny-circuits.com/shop/tinyshield-motorx4/
The motor can be operated in forward, reverse, braking, or coast mode. Speed can be controlled via PWM.
Operation is based upon the specs of the H-Bridge motor driver TI DRV8837. The commands use the Bridge Control table on page 6 at:
http://www.ti.com/lit/ds/symlink/drv8837.pdf
Unlike other H-Bridges where an Enable pin is operated in PWM mode and other pins control direction, the
TI DRV8837 has two Input pins. Proper operation requires that the PWM pin varies based upon direction of motor rotation
to ensure symmetric operation of the motor (otherwise the motor will brake in one direction in low PWM segments and coast in
the other direction).
Created 1 Aug 2013
by Nathan Delson
*/
// Define global motor variables
const int Forward = 5;
const int Reverse = 6;
const int Brake = 7;
const int Coast = 8;
int motorSleepPin = A3; // Motor sleep is analog pin 3
int LedPin = 13; // Arduino LED, which is used to flash if error occurs
void setup() {
digitalWrite(motorSleepPin, HIGH); // sets the Motor Driver sleep mode to be off
pinMode(LedPin, OUTPUT); // for flashing
// turn all 4 motors off (i.e. to coast)
for ( int i=0; i <= 4; i++){
MotorlControl(Coast,0,i);
}
}
void loop() {
int MotorNum; // Motor Number: 1, 2, 3, or 4
int MotorSpeed; // 0 to 255
int ControlMode; // Forward=5, Reverse=6, Brake=7, or Coast=8
MotorNum = 1;
// Ramp the motor speed up in Forward direction
MotorlControl(Forward,0,MotorNum);
delay(50);
MotorlControl(Forward,63,MotorNum);
delay(50);
MotorlControl(Forward,127,MotorNum);
delay(50);
MotorlControl(Forward,191,MotorNum);
delay(50);
MotorlControl(Forward,255,MotorNum);
delay(50);
// Ramp the motor speed down in Forward directoin
MotorlControl(Forward,191,MotorNum);
delay(50);
MotorlControl(Forward,127,MotorNum);
delay(50);
MotorlControl(Forward,63,MotorNum);
delay(50);
MotorlControl(Forward,0,MotorNum);
delay(50);
// Ramp the motor speed up in Reverse direction
MotorlControl(Reverse,0,MotorNum);
delay(50);
MotorlControl(Reverse,63,MotorNum);
delay(50);
MotorlControl(Reverse,127,MotorNum);
delay(50);
MotorlControl(Reverse,191,MotorNum);
delay(50);
MotorlControl(Reverse,255,MotorNum);
delay(50);
// Ramp the motor speed down in Reverse direction
MotorlControl(Reverse,191,MotorNum);
delay(50);
MotorlControl(Reverse,127,MotorNum);
delay(50);
MotorlControl(Reverse,63,MotorNum);
delay(50);
MotorlControl(Reverse,0,MotorNum);
delay(50);
}
void MotorlControl( int ControlMode, int MotorSpeed, int MotorNum) {
/* Definitions of Inputs
ControlMode - Forward=5, Reverse=6, Brake=7, or Coast=8
MotorSpeed - 0 to 255
MotorNum - Motor Number: 1, 2, 3, or 4
Flashes on Arduio LED will occur if inputs are outside valid ranges*/
int IN1Pin; // Pin on Tiny Duino that connects to Input 1 of motor driver
int IN2Pin; // Pin on Tiny Duino that connects to Input 2 of motor driver
// set IN1 and IN2 according to motor used (1-4)
switch (MotorNum) {
case 1:
IN1Pin = 2;
IN2Pin = 3;
break;
case 2:
IN1Pin = 4;
IN2Pin = 5;
break;
case 3:
IN1Pin = 6;
IN2Pin = 7;
break;
case 4:
IN1Pin = 8;
IN2Pin = 9;
break;
default:
// Invalid motor number flash
digitalWrite(LedPin, HIGH);
delay(50);
digitalWrite(LedPin, LOW);
delay(50);
}
pinMode(IN1Pin, OUTPUT); // sets the pin as output
pinMode(IN2Pin, OUTPUT); // sets the pin as output
// Check that MotorSpeed is between 0 and 255
if ( MotorSpeed < 0 || MotorSpeed > 255 ) {
// Invalid MotorSpeed flash
digitalWrite(LedPin, HIGH);
delay(100);
digitalWrite(LedPin, LOW);
delay(100);
}
// Operate H-Bridge according to the Bridge Control Table of the DRV8837
// In Forward and Reverse always set the low pin as fixed and the high pin to
// the PWM value. When the PWM pin is high the motor operates in the specfied direcion,
// and when the PWM is low the motor coasts.
switch (ControlMode) {
case Forward:
digitalWrite(IN2Pin, LOW); // sets the Mode
analogWrite(IN1Pin, MotorSpeed); // sets the speed with a PWM signal
break;
case Reverse:
digitalWrite(IN1Pin, LOW); // sets the Mode
analogWrite(IN2Pin, MotorSpeed); // sets the speed with a PWM signal
break;
case Coast:
digitalWrite(IN1Pin, LOW); // sets the Mode
digitalWrite(IN2Pin, LOW); // sets the Mode
break;
case Brake:
digitalWrite(IN1Pin, HIGH); // sets the Mode
digitalWrite(IN2Pin, HIGH); // sets the Mode
break;
default:
// Invalid ControlMode flash
digitalWrite(LedPin, HIGH);
delay(200);
digitalWrite(LedPin, LOW);
delay(200);
}
} // End of MotorlControl Function