Pololu VNH5019 Motor Driver Shield with Arduino

Hello,

I’m using the following code to power a 24V dc motor (via a pololu motor controller):

if(digitalRead(button1) == HIGH){
    for (int i = 0; i <= 400; i++)
    {
        md.setM1Speed(i);                   
        stopIfFault();              
    }
}

Later in my code i’m trying to say “if M1 speed, i.e. ‘i’, is not equal to zero, then do this…”

Therefore does anyone know a way to detect and save the motor speed as a variable?

Thanks

CBlewitt1:
Therefore does anyone know a way to detect and save the motor speed as a variable?

How can we without seeing the complete program?

...R

Robin2:
How can we without seeing the complete program?

…R

Apologies, i didn’t think it would be relevant.

Auto raise = motor turns on and remains on after button released
Manual raise = motor only turns on while button is held

Complete program so far as follows:

#include "DualVNH5019MotorShield.h"

DualVNH5019MotorShield md;

const int AutoRaise = 53;
const int Stop = 23;                      
const int ManualRaise = 50;                
int buttonTrigger = 0;

void setup(){
  Serial.begin(115200);
	pinMode(AutoRaise, INPUT);
	pinMode(Stop, INPUT);
	pinMode(ManualRaise, INPUT);
	md.init();
}

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

void loop(){

///////////////AUTO-RAISE///////////////////

	if(digitalRead(AutoRaise) == HIGH){     // if the auto raise button is pressed
    for (int i = 0; i <= 400; i++)
    {
    md.setM1Speed(i);                   // turn on the motor
    stopIfFault();              
	  buttonTrigger = 1;                    // set the button trigger variable to 1
	  }
	}
	
/////////////////STOP//////////////////////

	if(digitalRead(Stop) == HIGH){          // if the stop button is pressed
    md.setM1Speed(0);                     // turn off the motor
	  buttonTrigger = 2;                    // and set the button trigger variable to 2
}
	
////////////////MANUAL-RAISE////////////////

if(digitalRead(ManualRaise) == HIGH){         // if the manual raise button is pressed,
	if( motor is running ){                   // then check motor state. if already turning then do nothing
	}
	else{                                   // otherwise if motor is not on
		for (int i = 0; i >= 400; i++)
  {
    md.setM1Speed(i);                   // turn it on 
	}  
    buttonTrigger = 3;                  // and set the button Trigger to 3
 }

 else{                                    // if the manual raise button is now not pressed, i.e. released.
 if(buttonTrigger == 3){                 // but the motor was turned on by the manual raise button
		md.setM1Speed(0);                   // then turn off the motor.
	}
}
}

I hadn’t realised that “i” was a variable (arduino beginner!), therefore i’ve changed “i” to ManualSpeedVal which works to an extent, however the motor runs slower than it does when “auto raise” is pressed.

I have a feeling this is since “ManualSpeedVal” is declared twice?

(Code pasted as text to highlight relevant parts)

#include “DualVNH5019MotorShield.h”

DualVNH5019MotorShield md;

const int AutoRaise = 53;
const int Stop = 23;
const int ManualRaise = 50;
int buttonTrigger = 0;
int ManualSpeedVal = 0;

void setup(){
Serial.begin(115200);
pinMode(AutoRaise, INPUT);
pinMode(Stop, INPUT);
pinMode(ManualRaise, INPUT);
md.init();
}

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

void loop(){

///////////////AUTO-RAISE///////////////////

// if the auto raise button is pressed

if(digitalRead(AutoRaise) == HIGH){
for (int i = 0; i <= 400; i++)
{

// turn on the motor

md.setM1Speed(i);
stopIfFault();

// set the button trigger variable to 1

buttonTrigger = 1;
}
}

/////////////////STOP//////////////////////

// if the stop button is pressed

if(digitalRead(Stop) == HIGH){

// turn off the motor

md.setM1Speed(0);

// and set the button trigger variable to 2

buttonTrigger = 2;
}

////////////////MANUAL-RAISE////////////////

// if the manual raise button is pressed,

if(digitalRead(ManualRaise) == HIGH){

// then check motor state. if already turning then do nothing

if(ManualSpeedVal > 0){
}

// otherwise if motor is not on
else{
for (int ManualSpeedVal = 0; ManualSpeedVal <= 400; ManualSpeedVal++)
{

// turn it on

md.setM1Speed(ManualSpeedVal);
}

// and set the button Trigger to 3

buttonTrigger = 3;
}
}

// if the manual raise button is now not pressed, i.e. released.

else{

// but the motor was turned on by the manual raise button

if(buttonTrigger == 3){

// then turn off the motor.

md.setM1Speed(0);
}
}
}

You posted your program correctly using the code button </> in Reply #2. Please do the same for Reply #3 so I can copy it to my text editor to study it.

…R

Robin2:
You posted your program correctly using the code button </> in Reply #2. Please do the same for Reply #3 so I can copy it to my text editor to study it.

…R

Ok thanks, here’s the code:

#include "DualVNH5019MotorShield.h"

DualVNH5019MotorShield md;

const int AutoRaise = 53;
const int Stop = 23;                      
const int ManualRaise = 50;                
int buttonTrigger = 0;
int ManualSpeedVal = 0;

void setup(){
  Serial.begin(115200);
   pinMode(AutoRaise, INPUT);
   pinMode(Stop, INPUT);
   pinMode(ManualRaise, INPUT);
   md.init();
}

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

void loop(){

///////////////AUTO-RAISE///////////////////

// if the auto raise button is pressed

   if(digitalRead(AutoRaise) == HIGH){     
    for (int i = 0; i <= 400; i++)
    {

// turn on the motor

    md.setM1Speed(i);                   
    stopIfFault(); 

// set the button trigger variable to 1

     buttonTrigger = 1;                    
     }
   }
   
/////////////////STOP//////////////////////

 // if the stop button is pressed

   if(digitalRead(Stop) == HIGH){  

// turn off the motor

    md.setM1Speed(0);     

// and set the button trigger variable to 2

     buttonTrigger = 2;                    
}
   
   
////////////////MANUAL-RAISE////////////////

// if the manual raise button is pressed,

if(digitalRead(ManualRaise) == HIGH){ 

// then check motor state. if already turning then do nothing
  
   if(ManualSpeedVal > 0){                      
   }

// otherwise if motor is not on

   else{                                                
      for (int ManualSpeedVal = 0; ManualSpeedVal <= 400; ManualSpeedVal++)
  {

// turn it on

    md.setM1Speed(ManualSpeedVal);                    
   }  

// and set the button Trigger to 3

    buttonTrigger = 3;                  
 }
}

// if the manual raise button is now not pressed, i.e. released.

 else{                       

// but the motor was turned on by the manual raise button

 if(buttonTrigger == 3){ 

// then turn off the motor.

      md.setM1Speed(0);                   
   }
}
}

Thank you. You have a lot of unnecessary whitespace in your code and your indenting is not at all consistent so I have re-formatted it like this to make it easier to read. Use the AutoFormat tool in the Arduini IDE. I also prefer to indent the comments more than the code so I can read through the code and ignore the comments when I want to.

#include "DualVNH5019MotorShield.h"
DualVNH5019MotorShield md;
const int AutoRaise = 53;
const int Stop = 23;                      
const int ManualRaise = 50;                
int buttonTrigger = 0;
int ManualSpeedVal = 0;

void setup() {
    Serial.begin(115200);
    pinMode(AutoRaise, INPUT);
    pinMode(Stop, INPUT);
    pinMode(ManualRaise, INPUT);
    md.init();
}


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


void loop() {
    
        ///////////////AUTO-RAISE///////////////////
        // if the auto raise button is pressed
    if(digitalRead(AutoRaise) == HIGH) {    
        for (int i = 0; i <= 400; i++) {
                // turn on the motor
            md.setM1Speed(i);                  
            stopIfFault();
                // set the button trigger variable to 1
            buttonTrigger = 1;                    
         }
    }
    
        /////////////////STOP//////////////////////
         // if the stop button is pressed
    if(digitalRead(Stop) == HIGH) {  
            // turn off the motor
        md.setM1Speed(0);    
            // and set the button trigger variable to 2
        buttonTrigger = 2;                    
    }
    
        ////////////////MANUAL-RAISE////////////////
        // if the manual raise button is pressed,
    if(digitalRead(ManualRaise) == HIGH) {
            // then check motor state. if already turning then do nothing
        if(ManualSpeedVal > 0){                      
        }
            // otherwise if motor is not on
        else {                                                
            for (int ManualSpeedVal = 0; ManualSpeedVal <= 400; ManualSpeedVal++) {
                    // turn it on
                md.setM1Speed(ManualSpeedVal);                    
            }  
                // and set the button Trigger to 3
            buttonTrigger = 3;                  
        }
    }
        // if the manual raise button is now not pressed, i.e. released.
    else {                      
            // but the motor was turned on by the manual raise button
        if(buttonTrigger == 3) {
                // then turn off the motor.
            md.setM1Speed(0);                  
        }
    }
}

Having done all that I’m afraid I don’t understand your original question “a way to detect and save the motor speed as a variable”

It seems to me, for example, that line 62 (in my version) increments the speed from 0 to 400. Are you trying to save the value 400?

I note in line 62 that you have for (int ManualSpeedVal = 0. That will create a new variable called ManualSpeedVal that is local to the FOR loop. if you want to use the variable that you defined in line 8 then you should not have int on line 62 - just for (ManualSpeedVal = 0

…R

Thanks for the tips and taking the time to re-format! As you can tell i'm new to arduino so any help is appreciated.

It seems to me, for example, that line 62 (in my version) increments the speed from 0 to 400. Are you trying to save the value 400?

Yeah exactly, then use it to satisfy if(ManualSpeedVal > 0) i.e. the motor is turning. That way the if statements can check whether the manual raise button is held down, if it is and the motor is turning then carry on turning, else blah blah...

I had actually already tried for(ManualSpeedVal = 0) on line 62, which runs the motor at full speed, but only for one cycle of the code. As soon as the manual raise button is released, pressing it again has no effect.

CBlewitt1:
Yeah exactly, then use it to satisfy if(ManualSpeedVal > 0) i.e. the motor is turning.

Did you read what I wrote in the last paragraph in Reply #6?

I had actually already tried for(ManualSpeedVal = 0) on line 62, which runs the motor at full speed, but only for one cycle of the code. As soon as the manual raise button is released, pressing it again has no effect.

I don't understand. Can you try explaining it in more detail.

...R

Did you read what I wrote in the last paragraph in Reply #6?

Yes i read it?

I just needed some way of detecting whether the motor was turning or not. As i type this i'm thinking that checking whether the corresponding PWM pin is high (as per the motor shield pin mappings, pin 9 = motor 1 speed input)

I don't understand. Can you try explaining it in more detail.

I am able to operate manual raise, however it runs slower than auto raise for some reason.

When i remove "int" from line 62, leaving just "for(ManualSpeedVal = 0)", pressing and holding the manual raise button runs the motor at full speed (as i want it to), however if i release the button and press and hold it again, the motor does not turn at all. I'm not sure how else i can explain.

CBlewitt1:
I just needed some way of detecting whether the motor was turning or not.

When your program causes the motor to rotate just use a variable (let's call it motorRotating) and set it to true. When your code causes the motor to stop set the variable to false.

I am able to operate manual raise, however it runs slower than auto raise for some reason.

When i remove "int" from line 62, leaving just "for(ManualSpeedVal = 0)", pressing and holding the manual raise button runs the motor at full speed (as i want it to), however if i release the button and press and hold it again, the motor does not turn at all. I'm not sure how else i can explain.

Post the latest version of your program.

Your program mixes up the code for pressing buttons with the code for moving motors. If you separate them things will be easier to figure out. For example when a button is pressed it should change the state of a variable. The code to run the motor should only look at the state of that variable. Have a look at Planning and Implementing a Program

...R

I have packed up for the day now and won't get a chance to try out your suggestions until some point next week, however i had a quick glance through the link you posted which will be a massive help, great of you to put something like that together. I plan on working through it before going back to my project.

Thanks again for your time.

p.s. for the purposes of this discussion, the program hasn't changed from above.