Concerning Dual VNH5019 Motor Driver

HI,
I rand the “demo” example and am trying to figure out all the commands for the Dual VNH5019 Driver. Can someone help with the following:

  1. What is the command to actually stop, or disengage the motor? So far I have just set the speed to “0” so it does not turn. In reading the users guide, if I set arduino digital pin 6 for motor 1 to low, or digital pin 12 low, will this disable each motor?

  2. I am unable to find any other code examples to help in understanding how to operate the driver. Do you know where I can look at other examples?

  3. The speed goes from -400 to 400. Is this adjusting the PWM? What is this actually doing to change the speed of the motor?
    Thanks you very much
    Scott

Hello.

  1. Setting the motor speed to zero effectively disengages the motor (it turns off both low-side MOSFETs). Alternatively, you can drive the desired enable line low to turn off the outputs of the corresponding motor driver.

  2. I do not know of any other code examples, but the driver is not very complicated. Is there something you want to do that is not covered by the example we provide?

  3. Yes, the speed parameter affects the status of the direction controls and the duty cycle of the PWM.

- Ben

HI Ben, and and any others…
Thank you for responding! Yes, I do have a few more questions. I like this driver very much and hope to buy 3 more. I am just a beginner and want to really understand it more.

  1. You say I can stop a motor by driving the enable pin low. I have one motor hooked up, and tried to stop it this way but it did not work. I have left out some of the arduino code for ease of reading.

int offPin = 6;
pinMode(offPin, Input);
digitalWrite(offPin,Low);

  1. md.getM1CurrentMilliamps - I tried this on the one motor hooked up, no load. At first I got about 5 readings from over 1 amp, down to 0 amps, then all the rest zeros, reading on the screen. But on my power supply, it showed a similar start current then at a steady state was showing about 165 milliamps or so. But the computer screen showed 0 milliamps while the motor is still running… Any ideas why?

Two more questions… hang in there… almost done :slight_smile:

  1. the example code below: What is the While(1)? Does this mean stopiffault returns a 1, and it only prints if a 1 is returned? If not fault, nothing is printed?

void stopIfFault()
{
if (md.getM1Fault())
Serial.println(“M1 fault”)
while(1)
}

  1. the example code:

if (i%200 ==100)

I think the % means that if the remainder equals 100 then do the following? ie print… so the speed or i would have to get to be 20,000? I am probably way off on this one.

I think this covers it for now.
Thanks for any help!!!
Scott

While I can’t help you with your second and third questions right now (I’m on the wrong PC), your first code snippet appears to have a mistake in it. Also, even when posting short code snippets, it still helps if you stick it in [ code ] blocks, available above the post editor.

You are setting the pin to be an input,pinMode(offPin, INPUT); while I believe you need it to be an output.pinMode(offPin, OUTPUT); Since you also left out the capitalization, I guess this could be from you typing it in. When you can, always try to use copy and paste.

I will admit that I don’t quite understand the usage of modulo. However, it looks like that line will evaluate to true when i == 300, 500, 700, etc. Not quite correct, reference Ben’s next post.

Update:

The code you wrote for question 3 will not compile. I believe you are asking about this function in the demo program?:

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

It works similarly to how you described. “md.getMxFault()” will return a zero under normal conditions, and a 1 if there is a fault. The above function wont do anything unless there is a fault. If there a fault, it will print, then loop continuously.

Hi, Scott.

It looks like you might have inadvertently double-posted. I merged your new thread with this one and deleted your double post. If it wasn’t an accident, please keep discussions on the same topic to a single thread, and please don’t post the same thing in multiple places.

  1. Darth Maker has already answered your first question: the pin needs to be an output for it to drive the enable line low. When you do a digitalWrite(pin, LOW) on an input pin, the pin is floating, and the enable line’s internal pull-up keeps the enable line high.

  2. As the user’s guide says:

What this means is that the current sense output voltage will be 140 mV/A * 0.165 A = 23 mV when the motor current is 165 mA. Ultimately, it’s not easy to measure such small voltages, and the voltage might be even lower than this given that the current sense output is not very accurate at such low currents, so you should not be too surprised that you’re not getting a meaningful current sense output in this case.

  1. That function only does something if a fault is detected (i.e. if the getM1Fault() method returns 1). When that happens, it prints “M1 fault” and goes into an infinite loop. By the way, your rough summary of the example code isn’t as helpful if it is inaccurate. What you have written is fundamentally different from what is actually in the example (and contains syntax errors). As Darth Maker requested, please copy and paste the code you have questions about rather than trying to retype it from scratch.

  2. Interestingly, you happen to be both on target and way off on this. You are correct in your analysis that the if statement only evaluates to true when the remainder equals 100, but it seems like you aren’t clear what a remainder is. If you divide 20000 by 200, you get a quotient of 100 and a remainder of zero (200 divides into 20000 evenly). If you divide 100 by 200, you get a quotient of zero and a remainder of 100 (200 does not divide into 100 evenly, so there is a remainder). The effect of that check is that the motor current is printed whenever the motor speed is -300, -100, 100, or 300, which happens every 400 ms.

Please let me know if you have any other questions.

- Ben

HI Ben and Darth Maker,
Thanks so much for writing back. This is my first forum “ever” so every thing is new. Thanks for the tips on responding.

back to work… in regards to stopping M1. I tried your suggestions but it did not stop the motor. I am sure I am doing something wrong but can’t see my error. This is my first code insert and I used the “code” button. Hope it works. Here is the code I used:

#include "DualVNH5019MotorShield.h"
DualVNH5019MotorShield md;
int offPin = 6;
void setup()
{
  pinMode(offPin, OUTPUT);
  md.init();
}

void loop()
{
    md.setM1Speed(400);
    delay(2000);
    digitalWrite(offPin,HIGH);
    delay(2000);
}

I looked at the user’s guide section 4.b and it states the following for MxEN/DIAG Default HIGH

So I guess I need to get a logical LOW on the driver board via pin 6?

Help? and thanks. I’m learning step by step…
Scott

Yes, you need to drive the enable pin low to disable the motor driver outputs, which you would do with:

digitalWrite(offPin,LOW);

However, I think you should just set the motor speed to zero, which basically accomplishes the same thing. Is there a particular reason you want to use the enable pin?

- Ben

HI Ben,
Thanks for responding. I have no particular reason to use pin 6 to stop the motor. I am discovering many things and this was just one of them. It helps me understand working through problems. I tried your suggestion:

digitalWrite(offPin,LOW);

and it did not stop the motor. O’well. It’s not important. I will set the speed to 0. That works fine for my use. Thanks again! I am sure I’ll have more questions…
Scott

You should be able to get the enable pin working, and I think it’s still worth trying if for no other reason than to figure out what you might be doing wrong so the same problem doesn’t slow you down later on. Can you post your full program and tell me exactly how you have everything connected?

- Ben

HI Ben,
I am not sure what I did wrong. But something is amiss…

  1. I tried to stop the motor with using the 0, and tried to change directions, but nothing happens, and the motor keeps running.

  2. The code uploads to the arduino just fine, but I get what I think is an error code on the bottom of the arduino screen. I tried my simple code which worked before. I also tried the demo example. The motor just keeps running. It does not stop when uploading or reset. I will type what I think is an error code because I cannot copy it.

avrdude: stk500_getsync(): not in sync: resp=0x30

I have no control over the motor now. I am not sure what I did?
Can you help?
Thank you,
Scott

Hi Ben, I figured it out. I was uploading to COM port 3, but normally I upload to COM port 4. Now it works fine. Learned something for sure.
Thanks,
Scott

HI Ben,
Here is my code:

    #include "DualVNH5019MotorShield.h"
    DualVNH5019MotorShield md;
    int offPin = 6;
    void setup()
    {
      pinMode(offPin, OUTPUT);
      md.init();
    }

    void loop()
    {
        md.setM1Speed(400);
        delay(2000);
        digitalWrite(offPin,LOW);
        delay(2000);
    }

I have a small 12 volt dc motor at 15 rpm attached to M1A and M1B. I have my power supply attached to VIN and GND. I also (before I knew what I was doing) soldered all the pins on the motor shield as if I needed another microcontroller. The arduino uno is powered by my computer separate from the power supply.
So when I try to drive pin 6 low, nothing happens? Perhaps I need two motors attached?
by the way, I work as a mental health crisis counselor, so electronics is so awesome, but I am learning all the time. Sometimes I sit for 8 hours trying to figure stuff out.
Thank you,
Scott

If you could elaborate on what you mean by nothing happens, that would be great.

Looking at your code, I’m pretty sure it wont do what you think it should do. Always remember that microcontrollers will do exactly what you tell them to do, not necessarily what you want them to do.

Because the enable pin is also the fault pin, you don’t really want to drive it high. When the Arduino pin (connected to the enable pin) is set as an input (which it is in the init() function), there is a resistor pullup that enables the motor. To disable the motor, you set the pin to be an output, then drive it low. To re-enable the motor, you have to set the pin to be an input again.

Here is a little run down of what is and is not happening in your code:

    #include "DualVNH5019MotorShield.h"
    DualVNH5019MotorShield md;
    int offPin = 6;
    void setup()
    {
      pinMode(offPin, OUTPUT);    //Sets pin to an output, and probably defaults low,
                                   //which would disable the motor.
      md.init();    //This then sets the pin back to an input, which re-enables the motor.
    }

    void loop()
    {
        md.setM1Speed(400);    //The motor is set to run.
        delay(2000);
        digitalWrite(offPin,LOW);    //This actually turns off the Arduino's internal pullups.
                                  //(Which basically means it does nothing that affect the motor.)
                                  //It does not drive the pin low since the pin was set to an
                                  //input in the init(); function.
        delay(2000);
    }

This code will probably do what you expected from your program:

#include "DualVNH5019MotorShield.h"
DualVNH5019MotorShield md;
byte offPin = 6;    //Just using less memory space with a byte instead of an int.
void setup()
{
    md.init();    //Enables the motor
}

void loop()
{
    md.setM1Speed(400);
    delay(2000);
    pinMode(offPin, OUTPUT);    //This sets the pin to an output. and probably low but...
    digitalWrite(offPin, LOW);    //...This makes sure the pin is low to disable the motor.
    delay(2000);
    pinMode(offPin, INPUT);     //This re-enables the motor so it can run again.
}

Unfortunately, I can’t test this program until at least tomorrow (or later today, depending on how to look at it considering the time.)

Edited to fix a small mistake in my program. Also, I tested it today and it works.

HI Ben and Darth Maker,
Thank you for all the help. Yes… that solves the problem. The motor shuts off with this code. I went to the Arduino playground “constants” page:

if a pin is sinking current, like a battery being charged, current is flowing into it? Meaning electrons are flowing into the pin? and when a pin is sourcing current, electrons are flowing out of the pin. I have read to follow the electrons as they are the current. And not to follow the electron holes. I get confused with this as many drawings are using holes as electron flow.
Scott

Unfortunately, ever since Benjamen Franklin got it backwards (not really his fault), most terms in electronics would lead you to believe that current flows from positive to negative (conventional flow). Technically, the opposite is true. Electrons flow from the negative terminal to the positive terminal (electron flow).

If you want to think in terms of holes vs electrons, then holes are what flow from positive to negative. Generally, terms such as sink and source refer to positive as the source, and sinking to negative or ground.

A pin that is sinking current (in the LOW state) is connected to ground. If you connect positive power to a pin in such state, it will be a short circuit. Current flows into the pin by conventional flow (which sink and source refer to), and out of the pin by actual, literal electron flow.

I’m sorry if this sounded redundant. It can be a confusing topic, so I wanted to be as clear as possible. Really, it doesn’t matter which way you choose to think about it, as long as you’re consistent. However, you will need to remember that sink and source most often (in my experience of reading lots of datasheets) refer to conventional flow.

Thank you Darth Maker and Ben, for helping me understand sink and source. Well… I am off to work on my project. No more questions for now. You and Ben have been a great help. I have learned a lot for sure. Have a great and safe holiday!
Scott