Go Down

Topic: Dual VNH5019 Motor Shield (Read 811 times) previous topic - next topic

vleud101

Jun 05, 2013, 02:15 pm Last Edit: Jun 05, 2013, 03:06 pm by vleud101 Reason: 1
Dear members from the Arduino forum,

I just received this week my Dual VNH5019 Motor Shield (From polulu). The shield works perfectly with my Arduino Uno, but i have problems with my Arduino mega (2560). I get the error M1 fault. I read what the error means, shortcut etc.

I just wonder if more people has the same problem.. (i already did some research [google] but not much hits).

I just the next libarary file from the shield: https://github.com/pololu/Dual-VNH5019-Motor-Shield

Now i hope somebody can help me out.

Kind Regards,

Dave
____
The code:

Demo.pde

Code: [Select]
#include "DualVNH5019MotorShield.h"

DualVNH5019MotorShield md;

void stopIfFault()
{
 if (md.getM1Fault())
 {
   Serial.println("M1 fault");
   while(1);
 }
 if (md.getM2Fault())
 {
   Serial.println("M2 fault");
   while(1);
 }
}

void setup()
{
 Serial.begin(115200);
 Serial.println("Dual VNH5019 Motor Shield");
 md.init();
}

void loop()
{
 for (int i = 0; i <= 400; i++)
 {
   md.setM1Speed(i);
   stopIfFault();
   if (i%200 == 100)
   {
     Serial.print("M1 current: ");
     Serial.println(md.getM1CurrentMilliamps());
   }
   delay(2);
 }
 
 for (int i = 400; i >= -400; i--)
 {
   md.setM1Speed(i);
   stopIfFault();
   if (i%200 == 100)
   {
     Serial.print("M1 current: ");
     Serial.println(md.getM1CurrentMilliamps());
   }
   delay(2);
 }
 
 for (int i = -400; i <= 0; i++)
 {
   md.setM1Speed(i);
   stopIfFault();
   if (i%200 == 100)
   {
     Serial.print("M1 current: ");
     Serial.println(md.getM1CurrentMilliamps());
   }
   delay(2);
 }

 for (int i = 0; i <= 400; i++)
 {
   md.setM2Speed(i);
   stopIfFault();
   if (i%200 == 100)
   {
     Serial.print("M2 current: ");
     Serial.println(md.getM2CurrentMilliamps());
   }
   delay(2);
 }
 
 for (int i = 400; i >= -400; i--)
 {
   md.setM2Speed(i);
   stopIfFault();
   if (i%200 == 100)
   {
     Serial.print("M2 current: ");
     Serial.println(md.getM2CurrentMilliamps());
   }
   delay(2);
 }
 
 for (int i = -400; i <= 0; i++)
 {
   md.setM2Speed(i);
   stopIfFault();
   if (i%200 == 100)
   {
     Serial.print("M2 current: ");
     Serial.println(md.getM2CurrentMilliamps());
   }
   delay(2);
 }
}


DualVNH5019MotorShield.cpp
Code: [Select]

#include "DualVNH5019MotorShield.h"

// Constructors ////////////////////////////////////////////////////////////////

DualVNH5019MotorShield::DualVNH5019MotorShield()
{
 //Pin map
 _INA1 = 2;
 _INB1 = 4;
 _EN1DIAG1 = 6;
 _CS1 = A0;
 _INA2 = 7;
 _INB2 = 8;
 _EN2DIAG2 = 12;
 _CS2 = A1;
}

DualVNH5019MotorShield::DualVNH5019MotorShield(unsigned char INA1, unsigned char INB1, unsigned char EN1DIAG1, unsigned char CS1,
                                              unsigned char INA2, unsigned char INB2, unsigned char EN2DIAG2, unsigned char CS2)
{
 //Pin map
 //PWM1 and PWM2 cannot be remapped because the library assumes PWM is on timer1
 _INA1 = INA1;
 _INB1 = INB1;
 _EN1DIAG1 = EN1DIAG1;
 _CS1 = CS1;
 _INA2 = INA2;
 _INB2 = INB2;
 _EN2DIAG2 = EN2DIAG2;
 _CS2 = CS2;
}

// Public Methods //////////////////////////////////////////////////////////////
void DualVNH5019MotorShield::init()
{
// Define pinMode for the pins and set the frequency for timer1.

 pinMode(_INA1,OUTPUT);
 pinMode(_INB1,OUTPUT);
 pinMode(_PWM1,OUTPUT);
 pinMode(_EN1DIAG1,INPUT);
 pinMode(_CS1,INPUT);
 pinMode(_INA2,OUTPUT);
 pinMode(_INB2,OUTPUT);
 pinMode(_PWM2,OUTPUT);
 pinMode(_EN2DIAG2,INPUT);
 pinMode(_CS2,INPUT);
 #if defined(__AVR_ATmega168__)|| defined(__AVR_ATmega328P__)
 // Timer 1 configuration
 // prescaler: clockI/O / 1
 // outputs enabled
 // phase-correct PWM
 // top of 400
 //
 // PWM frequency calculation
 // 16MHz / 1 (prescaler) / 2 (phase-correct) / 400 (top) = 20kHz
 TCCR1A = 0b10100000;
 TCCR1B = 0b00010001;
 ICR1 = 400;
 #endif
}
// Set speed for motor 1, speed is a number betwenn -400 and 400
void DualVNH5019MotorShield::setM1Speed(int speed)
{
 unsigned char reverse = 0;
 
 if (speed < 0)
 {
   speed = -speed;  // Make speed a positive quantity
   reverse = 1;  // Preserve the direction
 }
 if (speed > 400)  // Max PWM dutycycle
   speed = 400;
 #if defined(__AVR_ATmega168__)|| defined(__AVR_ATmega328P__)
 OCR1A = speed;
 #else
 analogWrite(_PWM1,speed * 51 / 80); // default to using analogWrite, mapping 400 to 255
 #endif
 if (speed == 0)
 {
   digitalWrite(_INA1,LOW);   // Make the motor coast no
   digitalWrite(_INB1,LOW);   // matter which direction it is spinning.
 }
 else if (reverse)
 {
   digitalWrite(_INA1,LOW);
   digitalWrite(_INB1,HIGH);
 }
 else
 {
   digitalWrite(_INA1,HIGH);
   digitalWrite(_INB1,LOW);
 }
}

// Set speed for motor 2, speed is a number betwenn -400 and 400
void DualVNH5019MotorShield::setM2Speed(int speed)
{
 unsigned char reverse = 0;
 
 if (speed < 0)
 {
   speed = -speed;  // make speed a positive quantity
   reverse = 1;  // preserve the direction
 }
 if (speed > 400)  // Max
   speed = 400;
 #if defined(__AVR_ATmega168__)|| defined(__AVR_ATmega328P__)
 OCR1B = speed;
 #else
 analogWrite(_PWM2,speed * 51 / 80); // default to using analogWrite, mapping 400 to 255
 #endif
 if (speed == 0)
 {
   digitalWrite(_INA2,LOW);   // Make the motor coast no
   digitalWrite(_INB2,LOW);   // matter which direction it is spinning.
 }
 else if (reverse)
 {
   digitalWrite(_INA2,LOW);
   digitalWrite(_INB2,HIGH);
 }
 else
 {
   digitalWrite(_INA2,HIGH);
   digitalWrite(_INB2,LOW);
 }
}

// Set speed for motor 1 and 2
void DualVNH5019MotorShield::setSpeeds(int m1Speed, int m2Speed)
{
 setM1Speed(m1Speed);
 setM2Speed(m2Speed);
}

// Brake motor 1, brake is a number between 0 and 400
void DualVNH5019MotorShield::setM1Brake(int brake)
{
 // normalize brake
 if (brake < 0)
 {
   brake = -brake;
 }
 if (brake > 400)  // Max brake
   brake = 400;
 digitalWrite(_INA1, LOW);
 digitalWrite(_INB1, LOW);
 #if defined(__AVR_ATmega168__)|| defined(__AVR_ATmega328P__)
 OCR1A = brake;
 #else
 analogWrite(_PWM1,brake * 51 / 80); // default to using analogWrite, mapping 400 to 255
 #endif
}

// Brake motor 2, brake is a number between 0 and 400
void DualVNH5019MotorShield::setM2Brake(int brake)
{
 // normalize brake
 if (brake < 0)
 {
   brake = -brake;
 }
 if (brake > 400)  // Max brake
   brake = 400;
 digitalWrite(_INA2, LOW);
 digitalWrite(_INB2, LOW);
 #if defined(__AVR_ATmega168__)|| defined(__AVR_ATmega328P__)
 OCR1B = brake;
 #else
 analogWrite(_PWM2,brake * 51 / 80); // default to using analogWrite, mapping 400 to 255
 #endif
}

// Brake motor 1 and 2, brake is a number between 0 and 400
void DualVNH5019MotorShield::setBrakes(int m1Brake, int m2Brake)
{
 setM1Brake(m1Brake);
 setM2Brake(m2Brake);
}

// Return motor 1 current value in milliamps.
unsigned int DualVNH5019MotorShield::getM1CurrentMilliamps()
{
 // 5V / 1024 ADC counts / 144 mV per A = 34 mA per count
 return analogRead(_CS1) * 34;
}

// Return motor 2 current value in milliamps.
unsigned int DualVNH5019MotorShield::getM2CurrentMilliamps()
{
 // 5V / 1024 ADC counts / 144 mV per A = 34 mA per count
 return analogRead(_CS2) * 34;
}

// Return error status for motor 1
unsigned char DualVNH5019MotorShield::getM1Fault()
{
 return !digitalRead(_EN1DIAG1);
}

// Return error status for motor 2
unsigned char DualVNH5019MotorShield::getM2Fault()
{
 return !digitalRead(_EN2DIAG2);
}



DualVNH5019MotorShield.h
Code: [Select]
#ifndef DualVNH5019MotorShield_h
#define DualVNH5019MotorShield_h

#include <Arduino.h>

class DualVNH5019MotorShield
{
 public:  
   // CONSTRUCTORS
   DualVNH5019MotorShield(); // Default pin selection.
   DualVNH5019MotorShield(unsigned char INA1, unsigned char INB1, unsigned char EN1DIAG1, unsigned char CS1,
                          unsigned char INA2, unsigned char INB2, unsigned char EN2DIAG2, unsigned char CS2); // User-defined pin selection.
   
   // PUBLIC METHODS
   void init(); // Initialize TIMER 1, set the PWM to 20kHZ.
   void setM1Speed(int speed); // Set speed for M1.
   void setM2Speed(int speed); // Set speed for M2.
   void setSpeeds(int m1Speed, int m2Speed); // Set speed for both M1 and M2.
   void setM1Brake(int brake); // Brake M1.
   void setM2Brake(int brake); // Brake M2.
   void setBrakes(int m1Brake, int m2Brake); // Brake both M1 and M2.
   unsigned int getM1CurrentMilliamps(); // Get current reading for M1.
   unsigned int getM2CurrentMilliamps(); // Get current reading for M2.
   unsigned char getM1Fault(); // Get fault reading from M1.
   unsigned char getM2Fault(); // Get fault reading from M2.
   
 private:
   unsigned char _INA1;
   unsigned char _INB1;
   static const unsigned char _PWM1 = 9;
   unsigned char _EN1DIAG1;
   unsigned char _CS1;
   unsigned char _INA2;
   unsigned char _INB2;
   static const unsigned char _PWM2 = 10;
   unsigned char _EN2DIAG2;
   unsigned char _CS2;
   
};

#endif

codlink

M1 fault means that your power supply is not sufficient. 

http://forum.pololu.com/viewtopic.php?f=15&t=4830
//LiNK

vleud101

Hi, at first point thanks for replying and trying to help me out/

I already read that topic on pololu.

I have a power supply of 30 Ampere at 12V. I already try-ed to use a separated power supply at the Arduino and the driver without success.. same error.

I try to figure out what the pin difference is between the Mega and the Uno, i see some timers are different but if that is the problem.. i don't know.

Go Up