VNH5019 motor only runs at full speed for measuring velocity

Im trying to measure velocity of a DC motor equipped with an optical encoder while using the Dual VNH5019 motor shield and an Arduino Mega2560. The program reads the correct velocity when the motor is running at full speed but the motor wont run at any other speed. When the timer section is commented out the motor will run at any speed and still make the correct counts and angle measurements but not velocity since the timer is commented out. The code is shown below. Im using timer 2 with a 64 prescale and channel A from the encoder is sent to pin 3 and channel B from encoder is sent to pin 5.
Does the arduino and the motor shield have the capabilities to perform these functions alone or do I need a separate encoder shield?

[code]#include “DualVNH5019MotorShield.h”

DualVNH5019MotorShield md;

// for encoder 0
#define encoder0PinA 3
#define encoder0PinB 5
volatile long encoder0Count = 0;
volatile float angle0 = 0;
volatile float velocity0 = 0;
volatile float angle0_previous = 0;
volatile float angle0_post = 0;

// for Timer2
volatile int tcnt2 = 0;
volatile int t = 0;

void setup() {
// for encoder 0
pinMode(encoder0PinA, INPUT);
pinMode(encoder0PinB, INPUT);
//attachInterrupt(0, doEncoder0A, CHANGE);
attachInterrupt(1, doEncoder0B, CHANGE);

//setup for Timer2: interrupts every 1 ms
TIMSK2 &= ~(1<<TOIE2);
TCCR2A &= ~((1<<WGM21) | (1<<WGM20));
TCCR2B &= ~(1<<WGM22);
ASSR &= ~(1<<AS2);
//OCR2A = 249;// =(16000000/1000*64)-1 must be>256
TIMSK2 &= ~(1<<OCIE2A);
TCCR2B &= ~(1<<CS21) | (1<<CS20); //64 prescaler
TCCR2B |= (1<<CS22); //64 prescaler
TCNT2 = tcnt2;
TIMSK2 |= (1<<TOIE2);

Serial.begin (115200); // for debugging
}

void loop() {
md.setM2Speed(175);
// for encoder 0
Serial.print("cnt0: “);
Serial.print(encoder0Count, DEC);
Serial.print(”; ");
Serial.print("agl0: “);
Serial.print(angle0, 4);
Serial.print(”; ");
Serial.print("vel0: “);
Serial.print(velocity0, 4);
Serial.println(”. ");
//delay(500);

}
void doEncoder0B(){ // interrupt 1 function
if (digitalRead(encoder0PinB) == HIGH) { // look for a low-to-high on channel B
if (digitalRead(encoder0PinA) == HIGH) { // check channel A to see which way encoder is turning
encoder0Count = encoder0Count + 1;
}
else {
encoder0Count = encoder0Count - 1;
}
}
else { // must be a high-to-low edge on on channel B
if (digitalRead(encoder0PinA) == LOW) { // check channel B to see which way encoder is turning
encoder0Count = encoder0Count + 1;
}
else {
encoder0Count = encoder0Count - 1;
}
}
angle0 = 0.36*encoder0Count; // unit: degree
}

//--------------------
// estimate velocity
//--------------------
ISR(TIMER2_OVF_vect) {
TCNT1 = tcnt2; // reload the timer
t++;
if (t == 1){
angle0_previous = angle0;
}

else if (t == 20){
angle0_post = angle0;
}

else if (t == 21){
velocity0 = (angle0_post - angle0_previous)*8.333; // unit: rpm
t = 0;
}
}[/code]

Hello.

The PWM input pins on the VNH5019 shield are connected to Arduino pins 9 and 10, which use Timer 2 to generate the PWM signal. I suspect your code for reading the encoder using Timer 2 is interfering with those pins. You might try using a different timer; however, from a brief look at your code, it looks like you are only converting the encoder counts to RPM in the ISR, which could be done in the main loop instead.

- Jeremy

Thanks for the help but I have a few more questions.

Would it be best to use timer3 or timer5? I would use timer3 but I see that pin 2 is used by the shield. Does that still matter if I use pin 3 and 5 for channel A & B of the encoder and dont use pin2? I see there is a library for timer3 but I wasnt able to find a library for timer5 thats why Im leaning towards timer3.

Pin 2 should not be affected since the library does not depend on Timer 3 to drive the pin high or low, unlike pins 9 and 10, which depended on Timer 2 to generate the PWM signal. By the way, if the shield’s default Arduino pin mappings do not work for you application, you might consider remapping them. You can read more about this in the “Remapping the Arduino Connections” section of the VNH5019 motor driver shield user’s guide.

- Jeremy