Wishing my Tamiya Motors Had More Drive

I built a rc car, but after completing it only does well on solid surfaces, not carpet. Further it will only go fwd/reverse and not left/right because it would be dragging the back wheels. This is a double gear box, so for left/right I have each wheel go in opposite direction. However it only seems like it would do it if I had 2 double gear boxes making it truly 4 wheel drive. Even without this bulky 6v lantern battery and using a 12v adapter cable I noticed my car is very weak. Unless I replace the Tamiya motors with something bigger might this work better. here's a pic. I control it via bluetooth commands. F= forward, B=reverse, L=left, R=right. what's your thoughts? I'm thinking success on proving I can control hardware via bluetooth, but failure in hardware's capability meant for a prototype car.

I would suggest verifying that you're getting as much amperage through your motors as you think you're getting (use an ammeter). Is the L298 getting hot?

Next step would be showing us how you have it wired up.

The program works with the wheels turning the way I expect them to. Here is my code:

/*
Evan Johnson
Description: test sending serial input to turn on 1 of 3 leds.
 
 */

char serInStr[30];  // array that will hold the serial input string
//int breakLed = 2;
//int reverseLed = 4;



void setup()
{
  //Setup led for something to monitor working status
  //pinMode(led, OUTPUT);
  
  //Setup Channel A
  pinMode(12, OUTPUT); //Initiates Motor Channel A pin
  pinMode(9, OUTPUT); //Initiates Brake Channel A pin

  //Setup Channel B
  pinMode(13, OUTPUT); //Initiates Motor Channel A pin
  pinMode(8, OUTPUT);  //Initiates Brake Channel A pin

  //Start the UART TX1/RX0 (D1/D0) communication at defined rate
  Serial.begin(115200);
  delay(1000);
  
  //Call menu function
  menu();
  delay(1000);
  /* 
  for(int i=0; i<4; i++)
  {
    digitalWrite(led, HIGH);
    delay(200);
    digitalWrite(led, LOW);
    delay(200);
  }
  */
}

void loop()
{
  //read the serial port and create a string out of what you read
  if(readSerialString())
  {
    Serial.println(serInStr);
    char cmd = serInStr[0];
    int num = atoi(serInStr+1);

    if( cmd == 'F' )
    {
      Serial.println("MADE IT IN F");
      
      //Motor A and Motor B engage breaks
      digitalWrite(9, HIGH); // ENGAGE BREAK ON CHANNEL A MOTOR
      digitalWrite(8, HIGH); // ENGAGE BREAK ON CHANNEL B MOTOR
      
      //Motor A forward @ half speed
      digitalWrite(12, HIGH); //Establish forward direction of channel A
      digitalWrite(9, LOW);   //Disengage the brake for channel A
      analogWrite(3, 255);   //Spins the motor on channel A at half speed
      
      //Motor B forward @ half speed
      digitalWrite(13, HIGH);  //Establishes forward direction of Channel B
      digitalWrite(8, LOW);   //Disengage the Brake for Channel B
      analogWrite(11, 255);    //Spins the motor on Channel B at half speed
    }
    else if( cmd == 'B' )
    {
      Serial.println("MADE IT IN B");
      
      //Motor A and Motor B engage breaks
      digitalWrite(9, HIGH); // ENGAGE BREAK ON CHANNEL A MOTOR
      digitalWrite(8, HIGH); // ENGAGE BREAK ON CHANNEL B MOTOR
      
      //Motor A background @ half speed
      digitalWrite(12, LOW); //Establish forward direction of channel A
      digitalWrite(9, LOW);   //Disengage the brake for channel A
      analogWrite(3, 255);   //Spins the motor on channel A at half speed
      
      //Motor B background @ half speed
      digitalWrite(13, LOW);  //Establishes forward direction of Channel B
      digitalWrite(8, LOW);   //Disengage the Brake for Channel B
      analogWrite(11, 255);    //Spins the motor on Channel B at half speed
    }
    else if( cmd == 'L' )
    {
      Serial.println("MADE IT IN L");
      
      //Motor A and Motor B engage breaks
      digitalWrite(9, HIGH); // ENGAGE BREAK ON CHANNEL A MOTOR
      digitalWrite(8, HIGH); // ENGAGE BREAK ON CHANNEL B MOTOR
      
      //Motor A backward @ half speed
      digitalWrite(12, LOW); //Establish backward direction of channel A
      digitalWrite(9, LOW);   //Disengage the brake for channel A
      analogWrite(3, 255);   //Spins the motor on channel A at half speed
      
      //Motor B forward @ half speed
      digitalWrite(13, HIGH);  //Establishes forward direction of Channel B
      digitalWrite(8, LOW);   //Disengage the Brake for Channel B
      analogWrite(11, 255);    //Spins the motor on Channel B at half speed
      
    }
    else if( cmd == 'R' ) 
    {
      Serial.println("MADE IT IN R");
      
      //Motor A and Motor B engage breaks
      digitalWrite(9, HIGH); // ENGAGE BREAK ON CHANNEL A MOTOR
      digitalWrite(8, HIGH); // ENGAGE BREAK ON CHANNEL B MOTOR
      
      //Motor A forward @ half speed
      digitalWrite(12, HIGH); //Establish forward direction of channel A
      digitalWrite(9, LOW);   //Disengage the brake for channel A
      analogWrite(3, 255);   //Spins the motor on channel A at half speed
      
      //Motor B backward @ half speed
      digitalWrite(13, LOW);  //Establishes backward direction of Channel B
      digitalWrite(8, LOW);   //Disengage the Brake for Channel B
      analogWrite(11, 255);    //Spins the motor on Channel B at half speed
      
    }
    else if( cmd == 'S' ) 
    {
      Serial.println("MADE IT IN S");
      
      //Motor A and Motor B engage breaks
      digitalWrite(9, HIGH); // ENGAGE BREAK ON CHANNEL A MOTOR
      digitalWrite(8, HIGH); // ENGAGE BREAK ON CHANNEL B MOTOR
      
      
    }
    else
    {
      Serial.println("Invalid Selection. Please try again!");
      return;
    }
  }
  delay(2);
}


//****************************************************
//1) Menu void/void function 
void menu()
{
  Serial.print("\r\nEvan's Double Gearbox Control!\n"
                  "'F' for forwards\n"
                  "'B' for backwards\n"
                  "'L' for left\n"
                  "'R' for right\n"
                  "'S' for stop\n"
                  "Please enter your command: ");
}


//2) Read a string from the serial and store it in an array
//you must supply the array variable
uint8_t readSerialString()
{
  if(!Serial.available())
  {
    return 0;
  }
  delay(10);  // wait a little for serial data
  int i = 0;
  while (Serial.available())
  {
    serInStr[i] = Serial.read();   // FIXME: doesn't check buffer overrun
    i++;
  }
  serInStr[i] = 0;  // indicate end of read string
  return i;  // return number of chars read
}

I only have a multimeter. Nothing is getting too hot. Once the wheels touch the ground it barely moves. You're right I'm probably not getting enough amperage. I hear an amp meter to test. How can I increase amperage?

You forgot to set pin 3 and 11 as output.

Is it really necessary? Will that change make a world of a difference in amperage? :slight_smile:

analogWrite () sets the pin as an OUTPUT, so that's not an issue (although its poor coding style).

We don't know which motors you are using, nor the current ratings of that battery - can you provide links to the
data for the motors and more information (such as manufacturer's datasheet) for the battery?

[ edit: a lattern battery is not a motor battery... Motors may require a lot of current (but how much
do yours need?) also which motor shield? ]

I was using a 12v adaptor cable before I tried the latern battery (6v) with a little better results. There are two FA-130 motors. Pololu - Tamiya 980112M Mabuchi FA-130 Motor

It is the Arduino Motor Shield. http://store.arduino.cc/ww/index.php?main_page=product_info&cPath=11&products_id=204

Rayovac latern battery. sorry the site does say how much continuous amperage. However this is a much heavier alcaline battery so I imagine it can handle these small motors.

http://hdsupplysolutions.com/shop/RecordSearch?catalogId=110076&storeId=10051&langId=-1&rstate=157540-1&parentCategoryId=

I don't know why the car is so weak? Could I be supplying too much voltage to these motors being that they run on 3v and I'm supplying the barrel jack on Arduino Uno R3 with 12v? :sweat_smile:

how do I supply 3v to these motors if the Arduino Motor shield works on 5v-12v. Do I need to upgrade the motors?

are you using rechargeable batteries? If you are not that its a 90% chance thats why. i have run motors on rechargeable batteries and non rechargeable batteries and found out that they had more torque on rechargeable batteries.

I believe that, but let's forget I'm even running on batteries right now. I'm using a 12v wallwart into the arduino uno r3, then it goes to the arduino motor r3, which also runs on 5-12v. So we are cool so far, but then the FA-130 motors run at 1.5amps to 3amps, then will stall out (according to pololu). I'm thinking I'm overpowering those motors. What's your opinion? :*

Those motor shields can probably have a significant voltage drop across them. If you have a multimeter you can measure the voltage drop while the motors are operating. also check the battery voltage while the motors are operating to see how low it goes. As the others say, go rechargable, even if just using rechatgable D cells. Saves $$$ and time.

I was figuring the lantern battery I bought would give me good lifespan and a decent amperage for $6. Plus I thought it was kind of funny to use this type of battery in a project. Ok understood, better amps and saves time. I have a couple lipo batteries now, but no way to charge them yet. I have the sparkfun recharge shield but need single male pins infront of jst port. I have 2 maxim 1811 500mA rechargeable ICs but didn't know it required a SOIC to DIP socket.

Back on subject, I'll measure these voltages. I believe my only choices are 1)get higher rated motors from Pololu to use with 5v. 2) Get a small breadboard or prototype PCB to connect 3.3v, but even still that's above the 3v being the max.

encryptor:
how do I supply 3v to these motors if the Arduino Motor shield works on 5v-12v. Do I need to upgrade the motors?

Well the motor shield will drop some volts so that it is probably a reasonable match at 5 or 6V motor supply, but
each motor can take a max of 2A or so - does your supply/battery handle that load? Those peaks will be needed to
get the thing moving from a standstill more easily.

I think those motors are rather small - some about twice the weight / size might do better (but you'll need to
make sure the supply is adequate).

The gearing is another thing to consider - a great reduction ratio would give more torque but lower theoretical
top speed. Reducing the weight by using a smaller battery (high current NiMH pack or LiPo 2S perhaps) might
make it easier to propel too...

It would be a huge help to get rid of the weight of that lantern battery and to have front wheels that can actually turn instead of dragging on a high friction surface.

Making a 4-wheel car turn by spinning one pair of wheels in opposite directions is not going to work.

You need to run the wheels in the same direction, with one a bit faster than the other.

I did come to realize spinning 2 wheels in opposite directions wasn't going to work. If it did, then a car's wheels would be able to do it. haha! I was thinking to attach a servo in the front changing the angle 45degrees in each direction. My vehicle performs badly without the battery. While moving forward or backward why would I want to spin 1 wheel faster than the other?

Corrected Code:

/*
Evan Johnson
Description: A bluetooth remote controlled car. The car has FA-130 motors,
a Tamiya universal plate and axel hinges for front end wheels, and a SM-S4303R servo.
Most likely using a LiPo 3.7v 1000mA battery to power the car.
 
*/


#include <Servo.h> 
 
Servo myservo;  // create servo object to control a servo

char serInStr[30];  // array that will hold the serial input string

int val = 45; // change angle of servo 45 degrees left from center
int val2 = 90; // change angle of servo to 90 degree center
int val3 = 135; // change angle of servo 45 degrees right from center
   

void setup()
{
  
  //Setup Channel A
  pinMode(12, OUTPUT); //Initiates Motor Channel A pin
  pinMode(9, OUTPUT); //Initiates Brake Channel A pin
  pinMode(3, OUTPUT); //Initiates Speed Channel A pin

  //Setup Channel B
  pinMode(13, OUTPUT); //Initiates Motor Channel B pin
  pinMode(8, OUTPUT);  //Initiates Brake Channel B pin
  pinMode(11, OUTPUT); //Initiates Speed Channel B pin

  myservo.attach(10);  // attaches the servo on pin 10 to the servo object 
    
  //Start the UART TX1/RX0 (D1/D0) communication at defined rate
  Serial.begin(115200);
  delay(1000);
  
  //Call menu function
  menu();
  delay(1000);
}

void loop()
{
  //read the serial port and create a string out of what you read
  if(readSerialString())
  {
    Serial.println(serInStr);
    char cmd = serInStr[0];
    int num = atoi(serInStr+1);

    switch(cmd)
    {
      case '8':
      {
        Serial.println("8");
        Serial.println("MADE IT IN 8 FOR FORWARD");
        
        //Motor A and Motor B engage breaks
        digitalWrite(9, HIGH); // ENGAGE BREAK ON CHANNEL A MOTOR
        digitalWrite(8, HIGH); // ENGAGE BREAK ON CHANNEL B MOTOR
        
        //Motor A background @ full speed
        digitalWrite(12, LOW); //Establish forward direction of channel A
        digitalWrite(9, LOW);   //Disengage the brake for channel A
        analogWrite(3, 255);   //Spins the motor on channel A at full speed
        
        //Motor B background @ full speed
        digitalWrite(13, LOW);  //Establishes forward direction of Channel B
        digitalWrite(8, LOW);   //Disengage the Brake for Channel B
        analogWrite(11, 255);    //Spins the motor on Channel B at full speed
      }
      case '2':
      {
        Serial.println("2");
        Serial.println("MADE IT IN 2 FOR BACKWARDS");
        
        //Motor A and Motor B engage breaks
        digitalWrite(9, HIGH); // ENGAGE BREAK ON CHANNEL A MOTOR
        digitalWrite(8, HIGH); // ENGAGE BREAK ON CHANNEL B MOTOR
        
        //Motor A forward @ full speed
        digitalWrite(12, HIGH); //Establish forward direction of channel A
        digitalWrite(9, LOW);   //Disengage the brake for channel A
        analogWrite(3, 255);   //Spins the motor on channel A at half speed
        
        //Motor B forward @ full speed
        digitalWrite(13, HIGH);  //Establishes forward direction of Channel B
        digitalWrite(8, LOW);   //Disengage the Brake for Channel B
        analogWrite(11, 255);    //Spins the motor on Channel B at half speed
      }
      case '4': 
      {
        Serial.println("4");
        Serial.println("MADE IT IN 4 FOR LEFT SERVO");
      
        myservo.write(val); // sets the servo position 45 degrees for right position 
        delay(15);          // waits for the servo to get there 
      }
      case '0':
      {
        Serial.println("0");
        Serial.println("MADE IT IN 0 FOR CENTER SERVO");
      
        myservo.write(val2); // sets the servo position 90 degrees for center position 
        delay(15);          // waits for the servo to get there 
      } 
      case '6':
      {
        Serial.println("6");
        Serial.println("MADE IT IN 6 FOR RIGHT SERVO");
      
        myservo.write(val3); // sets the servo position 45 degrees for left position 
        delay(15);          // waits for the servo to get there 
      }
      case '5': 
      {
        Serial.println("5");
        Serial.println("MADE IT IN 5 FOR BREAK MOTORS");
        
        //Motor A and Motor B engage breaks
        digitalWrite(9, HIGH); // ENGAGE BREAK ON CHANNEL A MOTOR
        digitalWrite(8, HIGH); // ENGAGE BREAK ON CHANNEL B MOTOR
      }
      default:
      {
        Serial.println("Invalid Selection. Please try again!");
        return;
      }
    }
  }
  delay(2);
}


//****************************************************
//1) Menu void/void function 
void menu()
{
  Serial.print("\r\nEvan's Double Gearbox Control!\n"
                  "'8' for forward motors\n"
                  "'2' for reverse motors\n"
                  "'4' for left servo\n"
                  "'0' for center servo\n"
                  "'6' for right servo\n"
                  "'5' for break motors\n"
                  "Please enter your command: ");
}


//2) Read a string from the serial and store it in an array
//you must supply the array variable
uint8_t readSerialString()
{
  if(!Serial.available())
  {
    return 0;
  }
  delay(10);  // wait a little for serial data
  int i = 0;
  while (Serial.available())
  {
    serInStr[i] = Serial.read();   // FIXME: doesn't check buffer overrun
    i++;
  }
  serInStr[i] = 0;  // indicate end of read string
  return i;  // return number of chars read
}

Spinning one wheel faster than the other provides the turn motion. I will be the guy asking the really dumb question... the non-driven wheels. They are not connected to the same axle are they? They are independently free-running, right?

Spinning in opposite directions provides rotation along the center of the axle. In your configuration, that won't work because you are trying to spin along the center of the rear axle and the other wheels will act as brakes trying to move sideways. Omniwheels would work like this, but not normal wheels. Having some swing (even it is not controlled) would allow the front wheels to change angle with the friction, which would help since they are not trying to move sideways) would probably work, but not optimal. This is what a caster does.

Spinning one motor faster than the other puts the center of rotation on the center of the wheel spinning slower. Since the whole base continues to move forward while it does this, you are also causing the front wheels to spin at the same speed (assuming they are free-running). Now, your rotation is in an arc, with the center of rotation along one side of the base, instead of in the middle.

With a four wheeled base like you have, this is the correct way to do it.

Basically just image trying to turn a push-cart with wheels fixed in straight forward direction. You cant just pull one side back and push the other forward. You would have to push harder on one side. Of course, the turn radius is much larger. To decrease the turn radius, you use casters on the front wheels. This is why a car turns the front wheels to steer.

(I'm sure I boggled up that explanation.)

I see now. What if I use the casters as the back wheels?

It's a bit early for me, but that should work. I would however link the casters so that they follow each other or you will likely have wobbling and jumping while they adjust unless you have alot of the weight centered over and evenly distributed over the casters. The longer the wheel base, the worse this will be. Also, you are not going to have a while lot of power this way. Might be better to drive from the front, and put casters in the rear in that case.

As long as it would work on my cart analogy, it will work. It's not ideal, but it will work.