HELP, Simple Motor running with DualVNH5019MotorShield and Uno3

HI Jon,

I’ve got the motor running and testing at present, I have used the standard
pololu driver code and cut it down for M1 only with the faults etc.

Below is the code I’m using but still need to start and stop the motor
every 60 mins approx, the delay (30000) at the end seems to delay the start
of the motor 30 seconds then it runs but doesn’t stop. I need to include a
stop parameter to stop it after running 60mins and delay for 60 mins and
start again.

I’m not having much luck with the code below, where am I going wrong please?

cheers Jason

#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++) //jon can i set motor speed to 50% here??//
  {
    md.setM1Speed(i);
    stopIfFault();
    if (i%200 == 100)
    {
      Serial.print("M1 current: ");
      Serial.println(md.getM1CurrentMilliamps());
    }
    delay(30000); //startup delay//
  }
}

Right now your modified version of our example code increases the short 2ms delay (delay(2)) to 30 seconds. This short delay is called each time the code iterates through the for loop, and is there so that the motor takes time to ramp up to the target duty cycle. By increasing it to 30 seconds, it will take 400*30 = 12000 seconds to ramp up to the target duty cycle, incrementally increasing the duty cycle by 1 every 30 seconds. This does not sound at all like what you want to do. So, as a first step you should change back the short delay to delay(2), and add delay(30000) outside of the for loop like:

void loop()
{
  for (int i = 0; i <= 200; i++) // I made the 400 a 200 so that this loop finishes with a duty cycle of 50% instead of 100%
  {
    md.setM1Speed(i);
    stopIfFault();
    if (i%200 == 100)
    {
      Serial.print("M1 current: ");
      Serial.println(md.getM1CurrentMilliamps());
    }
    delay(2); // this short delay exists so that the motor takes time to ramp up to the target duty cycle
  }
delay(30000);
}

That snippet of code ramps the motor up to the target duty cycle (I used a value of 200 so that the code ramps up to a 50% duty cycle instead of 100%, which is what a value of 400 does) and delays for 30 seconds. Now, since 30000 is pretty close to the maximum value you can delay for, to delay for any longer periods of time using that function, you could call it again by typing out the command again. For example:

void loop()
{
  for (int i = 0; i <= 200; i++) // I made the 400 a 200 so that this loop finishes with a duty cycle of 50% instead of 100%
  {
    md.setM1Speed(i);
    stopIfFault();
    if (i%200 == 100)
    {
      Serial.print("M1 current: ");
      Serial.println(md.getM1CurrentMilliamps());
    }
    delay(2); //  this short delay exists so that the motor takes time to ramp up to the target duty cycle
  }
delay(30000); // delay for 30 seconds
delay(30000); // delay for another 30 seconds
}

That snippet of code ramps the motor up to the target duty cycle and delays for 30 seconds twice for a total of 1 minute. You could call delay(30000) 120 times to delay for 60 minutes, but not is not really a good way to code. A more elegant method is to write a function to delay for a certain amount of time, and to make a for loop that calls that function as many times as you want. Here is what that would look like:

void loop()
{
  for (int i = 0; i <= 200; i++) // I made the 400 a 200 so that this loop finishes with a duty cycle of 50% instead of 100%
  {
    md.setM1Speed(i);
    stopIfFault();
    if (i%200 == 100)
    {
      Serial.print("M1 current: ");
      Serial.println(md.getM1CurrentMilliamps());
    }
    delay(2); //  this short delay exists so that the motor takes time to ramp up to the target duty cycle
  }
 customPause(60);
}

void customPause(int delayTimeInMinutes)
{
  int n = delayTimeInMinutes;
  for  (n; n >= 0; n--)
  { 
    delay(30000);
    delay(30000);
  }
}

-Jon

Thanks Jon,
This makes total sense. I’ll upload and test.
I’ll get back to you with results and post code

Best regards
Jason

HI Jon,
Just testing this now with 60mins set but
what tells the motor to turn OFF after a set time like 60mins?? What code would I use for this?

I presume the above delay code snippet

customPause(60);
}

void customPause(int delayTimeInMinutes)
{
  int n = delayTimeInMinutes;
  for  (n; n >= 0; n--)
  { 
    delay(30000);
    delay(30000);
  }
}

would then hold the motor off for 60mins then turn back on and repeat the loop over and over
cheers
jason

Once the motor is moving, there are a couple ways to get the motor to stop. You can send a value of 0 to setM1Speed(), which corresponds to full coast. That results in power being removed from the motor, and the output shaft should continue to rotate until friction slows it to a complete stop. If you want to stop the motor more quickly, you can use setM1Brake(), and the value you pass into that function will determine how quickly the motor will brake. You can learn more about those functions and their parameters under the Documentation section of the VNH5019 Arduino library’s GitHub page.

-Jon

HI Jon,

I changed to code to some I found on another forum to the below and changed they delays so that its 4mins on and 4 mins off and this works very well.

Is there a better way to delay this up to 60mins??
you suggested custompause(60); but would this still work in this prgram? and where?
cheers
jason

#include "DualVNH5019MotorShield.h"

DualVNH5019MotorShield md;

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

void loop()
{
  //motor startup//
  Serial.println("M1 Speed 100% Forward");
  md.setM1Speed(400);
  Serial.print("M1 current: ");
  Serial.println(md.getM1CurrentMilliamps());
  delay(120000);//MS delay to stop = 2mins//
  delay(120000);//MS delay to stop = 2mins//
  
  //motor shutdown//
  Serial.println("M1 Speed 0%");
  md.setM1Speed(0);
  Serial.print("M1 current: ");
  Serial.println(md.getM1CurrentMilliamps());
  delay(120000);//MS delay to start = 2mins//
  delay(120000);//MS delay to start = 2mins//
}

HI Jon,
2nd question
I have an LDR here and keen to control theVNH5019 with the LDR via a mapped pin into the VNH5019 input, what pin can I remap to turn ‘OFF’ the driver from the Arduino.

My code now looks like:

#include "DualVNH5019MotorShield.h"

DualVNH5019MotorShield md;

int sensorPin = A0;   // select the input pin for ldr, JON Need to find pin to turn off M1 motor Vcc//
int sensorValue = 0;  // variable to store the value coming from the sensor

void setup()
{
  Serial.begin(115200);
  Serial.println("Dual VNH5019 Motor Shield");
  md.init();
  pinMode(2, OUTPUT); //pin connected to the VNH5019//
}

void loop()
{
  // read the value from the sensor:
  sensorValue = analogRead(sensorPin);
  Serial.print("LDR light reading of ");    
  Serial.println(sensorValue); //prints the values coming from the sensor on the screen
  
  if(sensorValue < 300) //setting a threshold value
  digitalWrite(2,HIGH); //turn VNH5019 ON//
  
  else digitalWrite(2,LOW); //turn VNH5019 OFF//
  delay(100);
  
  //motor startup//
  Serial.println("M1 Speed 50% Forward");
  md.setM1Speed(200);
  Serial.print("M1 current: ");
  Serial.println(md.getM1CurrentMilliamps());
  delay(120000);//MS delay to stop = 2mins//
  delay(120000);//MS delay to stop = 2mins//

  // read the value from the sensor:
  sensorValue = analogRead(sensorPin);
  Serial.print("LDR light reading of ");    
  Serial.println(sensorValue); //prints the values coming from the sensor on the screen
  
  if(sensorValue < 300) //setting a threshold value
  digitalWrite(2,HIGH); //turn VNH5019 ON//
  
  else digitalWrite(2,LOW); //turn VNH5019 OFF//
  delay(100);
  
  //motor shutdown//
  Serial.println("M1 Speed 0%");
  md.setM1Speed(0);
  Serial.print("M1 current: ");
  Serial.println(md.getM1CurrentMilliamps());
  delay(120000);//MS delay to start = 2mins//
  delay(120000);//MS delay to start = 2mins//

}

So that,
The light values turn on the loop and then as light value drops turns off the loop

this is so that the sun light can control when the fan is on during the day only.

can you suggest code example.
cheers
jason

I think you should focus on getting the one-hour-on one-hour-off code working how you want it to before adding your light sensor. You should be able to implement the customPause() example function I wrote out with the new code you are working on. The way the delay() function is used in my reply with the customPause() example should look very similar to the code you are currently working on. So, the instructions and progression in that post should help you write your own long delay function. Can you read through that post again and try modifying your code from this post?

-Jon

HI Jon,

Got my motor working with some great code, I couldn’t get the customPause(60) to work and verify on the editor but got the following code to work very well and accurate for 1 hr on and 1hr off on the serial monitor.

const long oneSecond = 1000; // a second is a thousand milliseconds
const long oneMinute = oneSecond * 60;
const long oneHour = oneMinute * 60;
const long oneDay = oneHour * 24;

delay(oneHour);

Now that I have this working, Im keen to get the LDR working to only turn the VMH5019 on when there is more than 300 on the LDR,
So if below 300 then turn off as per the code below.

What pin do I need to control here to shut off signal to the VMH5019??

cheers
Jason

My code now looks like this:

#include "DualVNH5019MotorShield.h"

const long oneSecond = 1000;  // a second is a thousand milliseconds
const long oneMinute = oneSecond * 60;
const long oneHour   = oneMinute * 60;
const long oneDay    = oneHour * 24;

DualVNH5019MotorShield md;

int sensorPin = A0;   // select the input pin for ldr, JON Need to find pin to turn off M1 motor Vcc?? //
int sensorValue = 0;  // variable to store the value coming from the sensor


void setup()
{
  Serial.begin(115200);
  Serial.println("Dual VNH5019 Motor Shield");
  md.init();
  pinMode(2, OUTPUT); //pin connected to the VNH5019//
}

void loop()
{
  // read the value from the sensor:
  sensorValue = analogRead(sensorPin);
  Serial.print("LDR light reading of ");    
  Serial.println(sensorValue); //prints the values coming from the sensor on the screen
  
  if(sensorValue < 300) //setting a threshold value
  digitalWrite(2,HIGH); //turn VNH5019 ON//
  
  else digitalWrite(2,LOW); //turn VNH5019 OFF//
  delay(2);
  
  //motor startup//
  Serial.println("M1 Speed 50% Forward");// 400 is 100%//
  md.setM1Speed(200);
  Serial.print("M1 current: ");
  Serial.println(md.getM1CurrentMilliamps());
  Serial.print("Delay: ");
  Serial.println("delay for 1 hour");
  delay(oneHour);


  // read the value from the sensor:
  sensorValue = analogRead(sensorPin);
  Serial.print("LDR light reading of ");    
  Serial.println(sensorValue); //prints the values coming from the sensor on the screen
  
  if(sensorValue < 300) //setting a threshold value
  digitalWrite(2,HIGH); //turn VNH5019 ON//
  
  else digitalWrite(2,LOW); //turn VNH5019 OFF//
  delay(2);
  
  //motor shutdown//
  Serial.println("M1 Speed 0% stopped");
  md.setM1Speed(0);
  Serial.print("M1 current: ");
  Serial.println(md.getM1CurrentMilliamps());

  Serial.print("Delay: ");
  Serial.println("delay for 1 hour");
  delay(oneHour);
  

 }

Hi.

To disable the motors you would use M1EN and M2EN. You can see what pins on the Arduino the shield connects those to by default in the “Shield Connections” section of the Dual VNH5019 Motor Driver Shield User’s Guide.

By the way, you mentioned you want to disable the drivers if the light value is below 300, but the comments in your code show that it is set up to disable the driver if the light value is not below 300.

-Claire

Thanks Claire,

That’s what I needed to know as it’s not clear on the shield user guide as
to what pins disabled the motor shield, just the picture of all the digital
pins.

I’ll check my code and look at for function to turn off M1EN etc.

Best regards
Jason

HI Claire,

Well, I got the system working how i need now with the current code. So all works, the LDR turns off as needed and the motor runs M1 as needed,
but for the motor speed.

I have it set at 200 but seems to not make any difference if its 100 or 400 full speed. Im needing it to run at 50% or 200 forward direction.

I cant see anything wrong with the code and I checked the motor now and it is brushed.

I also tested the motor with the DEMO code for the shield but it also doesnt work, just runs motor at full speed forward only. I did notice the small green LED flicker a little, but no Flicker when running my code as below.

Can you advise me where Im going wrong??
cheers
Jason

My current code is:

#include "DualVNH5019MotorShield.h"

const long oneSecond = 1000;  // a second is a thousand milliseconds
const long oneMinute = oneSecond * 60;
const long oneHour   = oneMinute * 60;
const long oneDay    = oneHour * 24;

DualVNH5019MotorShield md;

int sensorPin = A0;   // select the input pin for ldr//
int sensorValue = 0;  // variable to store the value coming from the sensor 

void setup()
{
   Serial.begin(115200);
   Serial.println("Dual VNH5019 Motor Shield");
   md.init();
   pinMode(6, OUTPUT); //pin connected to the VNH5019 M1EN//
}

void loop()
{
  // read the value from the sensor:
  sensorValue = analogRead(sensorPin);
  Serial.print("LDR light reading of ");    
  Serial.println(sensorValue); //prints the values coming from the sensor on the screen
  
  if(sensorValue < 400) //setting LDR threshold value//
  digitalWrite(6,LOW); //turn VNH5019 off//
  
  else digitalWrite(6,HIGH); //turn VNH5019 ON//
  delay(2);
  
  //motor startup//
  Serial.println("M1 Speed 50% Forward");// 400 is 100%//
  md.setM1Speed(200);
  Serial.print("M1 current: ");
  Serial.println(md.getM1CurrentMilliamps());
  Serial.print("Delay: ");
  Serial.println("delay for 1 Hour");
  delay(oneHour);


  // read the value from the sensor:
  sensorValue = analogRead(sensorPin);
  Serial.print("LDR light reading of ");    
  Serial.println(sensorValue); //prints the values coming from the sensor on the screen
   
  if(sensorValue < 400) //setting LDR threshold value
  digitalWrite(6,LOW); //turn VNH5019 OFF//
  
  else digitalWrite(6,HIGH); //turn VNH5019 ON//
  delay(2);
  
  //motor shutdown//
  Serial.println("M1 Speed 0% stopped");
  md.setM1Speed(0);
  Serial.print("M1 current: ");
  Serial.println(md.getM1CurrentMilliamps());
  Serial.print("Delay: ");
  Serial.println("delay for 1 Hour");
  delay(oneHour);
   

 }

Can you remove your motor from your system and apply power to it directly to see if its speed changes with the voltage? If you have access to a benchtop power supply, try running your motor at a lower voltage (like 7V or 8V), then ramp up to a higher voltage (like 10V or 12V). How does the speed of the motor vary as the voltage changes?

If you do not have access to a benchtop power supply, you can try powering your motor with a couple different battery packs of differing voltages (e.g. start with a 2S LiPo or 7.2V NiMH battery pack, and then move up to a 3S LiPo or 8.4V NiMH battery pack) to perform a similar test.

-Jon

Thanks Jon,
I have the same motor and fan running on a solar panel directly on another
coastline. It does run at lower voltages as the 20w solar panel only
generates under 10v when low sun etc.
I have it directly connected to the solar panel.
So I know that this motor can achieve what we need.

Ive just tested it too now on a 7vdc charger here and yes the fan runs slow and low revs. It seems to run at low volts fine

I have identical motor to which this shield with drive on vmh5019 at home to test.

Now, the last item I need is the right code to tell the motor to run at 50% or 200. then Im done and all works well.

Best regards
Jason

There are several things I want to cover. First, the green LED should be lit whenever the VNH5019 is driving a motor. Second, I was able to make a setup similar to yours with a VNH5019 shield, micro metal gearmotor, and an Arduino Mega running your code, which works. I used a wire to connect the A0 pin to a steady voltage to simulate your LDR. The green LED lights whenever the motor is spinning and adjusting the speed parameter of setM1Speed() changes how fast the gearmotor rotates.

Next, I thought about it some more and want to point out that controlling a computer fan with a motor driver like the VNH5019 is not likely to work because the computer fan is not designed to accept a pulse-width modulated supply voltage like what the VNH5019 outputs. (I answered your questions in part because you already had a setup and code that needed troubleshooting.)

-Jon

Thanks Jon,

Sounds great, I have taken the computer fan off the test as was only using it in the early stages until the actual fan arrived that is the same as what I plan to use.

I have attached images of the actual fan the shield will drive and not sure if it will accept PWM but it is brushed and not like a computer fan, as it seems to run slower the less voltage is applied.

Is there some other C++ code I can use instead of md.setspeed ()???
Appreciate the help on this.
cheers
jas

The functions in that library are written specifically to work with this motor driver and should behave as described in the documentation. If the library is not working for you, then something is wrong in your setup or with your hardware, and using some other code will not be a way to solve the issue. (We do not have any other libraries or example code available for that motor driver, anyway.)

Do you have a datasheet for the motor you actually plan to use? If you do not, can you provide a link to the product page for it?

-Jon

Morning Jon,

The only link I can find for you is the Seaflow website but no datasheet.
http://www.seaflo.com/en-us/product/detail/663.html

Would one of these help on the output of the VNH5019?? I could cap it at 9v to fan?

If the pololu shield can’t control voltage then I can install and external one to do this, like a motor regulator control etc,
but would be nice to wrap this up in one neat package.

Can we not control motor voltage from the VNH5019??

I found this on Arduino.cc:
A call to analogWrite() is on a scale of 0 - 255, such that analogWrite(255) requests a 100% duty cycle (always on), and analogWrite(127) is a 50% duty cycle (on half the time) for example.
Is this something I need to add to my code?

cheers
jas

I do not understand why you are asking about using a regulator. The motor you posted looks like it could be a brushed DC motor (though I didn’t see that specifically called out on the page), so the PWM outputs of the VNH5019 should be able to control its speed. Have you tried using it with the driver and the last thing of code you posted?

It seems like you are really new to motors and motor control. I recommend reading through this page on H-Bridge basics to help you understand how a brushed DC motor driver works.

-Claire

Yes I’m new to motors.

The code all works well except for md.setspeed(), does not work to control
the motor speed.

If the shield can’t then I use external regulator.

Best regards
Jason