Do my stepper motors provide enough torque to move a small cart?

I am trying to control the movement of a small car or cart (maximum weight ~5 kg total) its suppose to carry stuff from a position to another specific position. I initially decided to use DC motors with encoders but they were a bit of a headache for me since I am kind of a beginner to programming.

However, I decided NEMA 17 stepper motors instead for being much easier to handle for position control. I installed everything and tried running them but even though I am getting about 1.2 A to the motors they cannot move the cart. I checked them by lifting off the ground and the motors did move but they were weak. I do not think the load should be any problem since the motor can provide up to 48Ncm torque and the rolling resistance of the wheels should be on the order of 0.001 to 0.01 as far as I know.

Wheel radius: 6 cm
Cart radius: 25 cm (round part - see picture)
Stepper Motors: http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Robotics/42BYGHM809.PDF
Motor Driver: http://www.robotshop.com/media/files/pdf/datasheet-mot103b1m.pdf

Used a 6V battery and a 11V battery that can well provide over well above 2A

LiPo: http://lphonet.en.alibaba.com/product/738699122-218544641/2200mah_11_1v_14_8v_30C_rc_lipo_batteries.html
Acid: http://www.klb.com.tw/dbf/WP7-6.pdf

I am sure there is nothing wrong with the code cause the motors could definitely turn before I installed them. Moreover, if this motor/driver is not suitable for this type of application what can I change to get something that could actually carry this load?
What kind of power battery should I use?

This might not be the best explanatory picture but this is basically what the set up from below the cart , the other motor should be on the opposing side of the one in the pic (sorry its not there, its not with me at the moment). (attached picture)

I would appreciate any suggestions! Thank you.

Post your code.(using the "#" CODE TAGS tool button.)

The Society of Robots site has a calculator to help you estimate the torque needed to move a robot.
Main site: http://www.societyofrobots.com/
RMF calculator: How to Build a Robot Tutorials - Society of Robots

To explain my code, it has many other functions like a keypad and LCD display. But generally is that I input a number using the keypad and if the number is correct (corresponding to book's number). It should move exactly to where that book is located in a library-like setting (small scaled library) and from then on it picks the book up (but I haven't got there yet).

#include <Keypad.h>
#include <LiquidCrystal.h>
#include <Stepper.h>




// Stepper Constants Right
const int ENAR=38;
const int IN1R=42;
const int IN2R=40;
const int ENBR=48;
const int IN4R=46;
const int IN3R=44;

//Stepper Constants Left

const int ENAL= 53;
const int IN1L= 50;  
const int IN2L= 52;
const int ENBL= 49;
const int IN4L= 51;
const int IN3L= 47;


Stepper stepperR(400,IN1R,IN2R,IN3R,IN4R);
Stepper stepperL(400,IN1L,IN2L,IN3L,IN4L);

//LCD CONSTANTS
const int RS=4;
const int E=5;

const int D7=8;
const int D6=9;
const int D5=10;
const int D4=11;

LiquidCrystal lcd(RS,E,D4,D5,D6,D7);  //LCD display initialization

// counters and logicals

int n=0; //counter
boolean A; //checker for code array
char code[8];      //Code for Book retrieval

char book1[8]= {'1','2','3','4','5','6','7','8'}; //Book Database

//constants for keypad
const byte rows = 4;  
const byte cols = 4;

char keys[rows][cols] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

byte rowPins[rows] = {36,34,32,30};
byte colPins[cols] = {28,26,24,22};

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, rows, cols);




////////////////////////////////////////////////////////////////////////////////////////////
void setup() {


stepperR.setSpeed(50);        //Speed in RPM
stepperL.setSpeed(50);        //Speed in RPM
//Initialize H bridge Enables for stepper motor R
pinMode(ENAR,OUTPUT);      
pinMode(ENBR,OUTPUT);
digitalWrite(ENAR,HIGH);
digitalWrite(ENBR,HIGH);

//Initialize H bridge ENABLES for stepper motor L
pinMode(ENAL,OUTPUT);      
pinMode(ENBL,OUTPUT);
digitalWrite(ENAL,HIGH);
digitalWrite(ENBL,HIGH);



//LCD initializing and first message appearance + setting cursor to first column second row 
lcd.begin(16,2);

lcd.print("Enter Book Code:");


Serial.begin(115200);


lcd.setCursor(0,1);
}
///////////////////////////////////////////////////////////////////////////////////////////////

void loop() {

char key = keypad.getKey();
  if((int)key != 0 && n <8 && key != 'C' && key != 'A' && key != 'B' && key != 'D' && key != '*' && key != '#' ){      //Checks for the code which should be numbers and excludes symbols
    
    code[n]=key;
    n++;
    lcd.print(key);
    lcd.setCursor(n,1);
    
   
  }
if((int)key !=0  &&  key == 'C'){        //Clearing LCD INPUT by user
  lcd.setCursor(0,1);
  lcd.print("                ");
  lcd.setCursor(0,1);
  n=0;
}
if((int)key!=0 && key == 'B'){          //Backspacing LCD input by user
  n=n-1;
  lcd.setCursor(n,1);
  lcd.print(" ");
  lcd.setCursor(n,1);
  
}



if((int)key !=0 && key== 'A'){         //Enters code and checks for validity
  for(int i=0;i<8;i++){
  A=code[i]==book1[i];
  A=A*A;
  }
  if(A){                               //When code is correct
    clearlcd();                        
    lcd.setCursor(0,0);
    lcd.print("Book Found.");
    n=0;
    getBook();                        //set path to book by function getBook
    
  }
  else{                                //when code is wrong
    n=0;
    clearlcd();
    lcd.setCursor(0,0);
    lcd.print("Invalid Code");
    delay(5000);
    clearlcd();
    lcd.setCursor(0,0);
    lcd.print("Enter Book Code:");
    lcd.setCursor(0,1);
    
    
  

}
}
} //loop close bracket


void clearlcd(){              //Clears LCD Screen Completely
  lcd.setCursor(0,1);
  lcd.print("                ");
  lcd.setCursor(0,0);
  lcd.print("                ");
}


void getBook(){              //Function to get a book
  for(int i; i<3000;i++){
    stepperL.step(1);
    stepperR.step(1);
  }
}

I am sorry if this code is a mess, but basically the function getBook() is what runs the motors.
Used a sample book code as 12345678 and wanted to try to run the whole thing in a straight line for 3000 steps.

@jremington Thank you, I did try this calculator and I also tried doing it manually.
For example 5 kg load.
Normal force=5*9.81= 49 N.
Divided by 2 for each wheel ~25 N
assuming a rolling resistance coefficient of about 0.03 (which I think is conservative).
F_resistance= 0.75 N
with 6 cm arm (wheel radius). Torque required=4.5 Ncm
and each motor can provide way more than that.
I may be mistaken though and my assumptions could be wrong.

The L298 is not really suitable for driving stepper motors. You should look at, for example, the Pololu A4988 stepper motor driver board. It is much easier to use with the Arduino and because it can limit the current in the motor it can take a much higher voltage.

The A4988 is probably not quite capable of supplying the full current for your motor. You would be better with a driver with a higher current capability, but they may be considerably more expensive.

...R

PS the Pololu DRV8825 may be a bit better. ...R

I agree with Robin2 that the L298 is a problem. Most people can't even get 1 ampere per channel before they start to overheat and shut down. You should try the Pololu chopper drivers but even they will have a hard time with your motors (which are rated at 1.7 amps/winding) without extra cooling. Be sure to set the current limit to 1.5, or even 1.2 amperes.

For tests showing the poor performance of the L298 drivers, see: The Motor Driver Myth — Rugged CircuitsRugged Industrial Arduino Microcontrollers

Could there be any alternative to changing the drivers, I mean are stepper motors the best choice here? I'm ready to change anything as long as it could actually move to a specified position

A brushed or brushless (more expensive) DC motor can provide far more torque than a stepping motor of the same size. Few people use steppers for robot wheels or tracks.

Is there a way to get feedback other than quadrature encoders for DC motors? Or rather is there a way I could modify my code so it works with encoders (I had a headache with interrupts and encoders).

If you are just using the motors to propel your cart why do you need the precision of a stepper or an encoder on a DC motor?

What about having some external indicators (a line on the floor?) to determine position.

Have you considered using continuous rotation servos for your drive motors? They don't have positioning ability but their speed is easily controlled with the Servo library ad they are easy to install.

...R

I'm not sure how to do it with external indicators. It's because I need to make it move to discrete positions across a library like setting (see picture).

It would be hard to control its position by calculating speed and distances and setting the speed for an X amount of time such that it reaches that point and taking acceleration and deceleration into account would be a headache.

In the picture (basic d, I have a home position for my cart and each node on the map is where I want it to be able to get to. Then it should basically face the shelf and grab a book (very light weighted) and bring it back to home position.

My guess is that slippage at the wheels will lose a lot of the precision that stepper motors or encoders provide - especially when the cart turns.

...R

That would be really problematic, is there a different approach that could achieve this ?

azizsm:
That would be really problematic, is there a different approach that could achieve this ?

The cart would need to be able to correct / verify its position from external indicators. They could be active (such as a flashing LED that is only visible from a very narrow angle) or passive, such as marks on the floor or on the bookshelves.

If you had the computing power of a PC you might consider a vision system, but the Arduino can't do that.

...R

If you want to select objects from a fixed arrangement of shelves or slots, perhaps you could have a mechanism running in tracks attached to the shelves. That way a lightweight belt or chain could be used to drive the picking mechanism. If properly adjusted belts don't slip and can be used for very accurate positioning (to micrometers, in some cases).

jremington:
A brushed or brushless (more expensive) DC motor can provide far more torque than a stepping motor of the same size. Few people use steppers for robot wheels or tracks.

No, not true, steppers win out in my experience. I've a 200W BLDC and it gives 0.44Nm,
whereas a NEMA23 stepper motor of about the same size is about 3Nm.

However gearmotors are able to provide almost any amount of torque since you trade
speed for torque. But you can add gears to a stepper motor too...

azizsm:
I do not think the load should be any problem since the motor can provide up to 48Ncm torque and the rolling resistance of the wheels should be on the order of 0.001 to 0.01 as far as I know.

Rolling resistance depends on the vehicle weight, and is seldom negligible. You also
have dynamic loads due to accelerating the mass of the robot which have to be allowed
for.

With a 5kg load you have a lot of mass to accelerate so you need to set the programmed
acceleration to a low value to keep dynamic loads down I think.

Also with a stepper the pull-out torque at standstill is always a lot greater than
the pull-out torque under load, especially if there are vibrations and resonances
to deal with.

No, not true, steppers win out in my experience. I've a 200W BLDC and it gives 0.44Nm,
whereas a NEMA23 stepper motor of about the same size is about 3Nm.

That statement is very misleading, because it ignores the difference in typical motor shaft angular velocity at the point of maximum efficiency (which is where you would like to be using your motors). In such a situation a geared down brushed or brushless DC motor, turning at the same rate as a stepper, will win. Plus, the former are more efficient.

Rolling resistance depends on the vehicle weight, and is seldom negligible.

Rolling resistance depends most strongly on the type of wheels and tires you have, and the nature of the surface you are rolling on.

A railway vehicle has much lower rolling resistance than a car on a road, which has much less rolling resistance than a car on a beach.