motor controller not working properly Please Help

Hi, I am new to arduino and microcontrolling and I decided to buy the following parts to build a tank

-1x twin motor gear box - tamiya
-1x track and wheel set- tamiya
-1x universal plate set- tamiya
-1x Adruino Uno R3- Aruino
-1x set of jumper cables X60- spark fun
-1x TB6612FNG Dual 1 a motor controller- spark fun
-1x L3GD20 3-Axis Gyro- Adafruit
-1X LV- ManxSonar-EZ4 MB1040- Adafruit
-5x 9V battery clips- Radio Shack
-1x Mini Bread Board- Sparkfun
-1x Arduino Ethernet Shield R3- Amazon
(end parts list)

How do i properally control the tank over serial connection

I have the base code that was supplied by Spark fun so I decided if i could modify the base code to the point where i could simply just have the tank drive fwd for 5 seconds and turn around and come back.

all of the connections are perfect the tank operates but only goes forward.
it seems that the tank only is able to move forward and despite the fact that in the code i have instructed that after 5 second for the left motor to move forward and for the right one to move in reverse.

the point of the other censors is that this tank will be an automated system the range finder for the ability for it not to run into anything the gyro to if the tank is on an angle and it is moving at a angle too steep for the tank to remain in the upright position, it will right the wrong.

the Ethernet shield so that I can use the built in SD card slot as a data logger because the system will map out a 50ft x 50ft room and based on basic reading that the censors give it it will know its position in the room and be able to move freely

but in the mean time before the automation I would like to get the tank running on a serial connection from the computer or from an Ethernet cable that will tell it what direction to move in.

Also I have some Rechargeable batteries that I used to use on my RC Destroyer like this 7.2 volt AA mAh800 battery and i have various other 9.6 volt 2000 aMh batteries what configuration would i need for the proper powering of this tank i went through 3 9v's in 2 hours just off of testing last night so far i only have the motor controller hocked up the gyro is there but not connected and the Ethernet shield is not hooked up yet.

the code so far stands at such

[code]//motor A connected between A01 and A02
//motor B connected between B01 and B02

int STBY = 10; //standby

//Motor A
int PWMA = 3; //Speed control 
int AIN1 = 9; //Direction
int AIN2 = 8; //Direction

//Motor B
int PWMB = 5; //Speed control
int BIN1 = 11; //Direction
int BIN2 = 12; //Direction

void setup(){
  pinMode(STBY, OUTPUT);

  pinMode(PWMA, OUTPUT);
  pinMode(AIN1, OUTPUT);
  pinMode(AIN2, OUTPUT);

  pinMode(PWMB, OUTPUT);
  pinMode(BIN1, OUTPUT);
  pinMode(BIN2, OUTPUT);
}

void loop(){
  move(1, 255, 0); //motor 1, full speed, left
  move(2, 255, 0); //motor 2, full speed, left

  delay(5000); //go for 1 second
  stop(); //stop
  delay(1000); //hold for 250ms until move again

  move(1, 255, 1); //motor 1, half speed, right
  move(2, 255, 0); //motor 2, half speed, right

  delay(5000);
  stop();
  delay(1000);
}


void move(int motor, int speed, int direction){
//Move specific motor at speed and direction
//motor: 0 for B 1 for A
//speed: 0 is off, and 255 is full speed
//direction: 0 clockwise, 1 counter-clockwise

  digitalWrite(STBY, HIGH); //disable standby

  boolean inPin1 = LOW;
  boolean inPin2 = HIGH;

  if(direction == 1){
    inPin1 = HIGH;
    inPin2 = LOW;
  }
    
  if(direction == 0){
     inPin1 = LOW;
     inPin2 = HIGH;
   }

  if(motor == 1){
    digitalWrite(AIN1, inPin1);
    digitalWrite(AIN2, inPin2);
    analogWrite(PWMA, speed);
  }else{
    digitalWrite(BIN1, inPin1);
    digitalWrite(BIN2, inPin2);
    analogWrite(PWMB, speed);
  }
  
    if(motor == 0){
    digitalWrite(AIN1, inPin1);
    digitalWrite(AIN2, inPin2);
    analogWrite(PWMA, speed);
  }else{
    digitalWrite(BIN1, inPin1);
    digitalWrite(BIN2, inPin2);
    analogWrite(PWMB, speed);
  }
}

void stop(){
//enable standby  
  digitalWrite(STBY, LOW); 
}

that is for the motors ^^ for the gyroscope

#include <Wire.h> 
#include <Adafruit_L3GD20.h>


#define USE_I2C

  Adafruit_L3GD20 gyro;


void setup() 
{
  Serial.begin(9600);
  
   if (!gyro.begin(gyro.L3DS20_RANGE_250DPS))
  {
    Serial.println("Oops ... unable to initialize the L3GD20. Check your wiring!");
    while (1);
  }
}

void loop() 
{
  gyro.read();
  Serial.print("X: "); Serial.print((int)gyro.data.x);   Serial.print(" ");
  Serial.print("Y: "); Serial.print((int)gyro.data.y);   Serial.print(" ");
  Serial.print("Z: "); Serial.println((int)gyro.data.z); Serial.print(" ");
  delay(100);
}

I realize that this is coded for serial I am yet to figure out how to translate it for just the Uno to read

Thank you Greatly For Your Time [/code]

How do i properally control the tank over serial connection

Don't bother even testing it on just 9V batteries, they cannot produce enough current, the Arduino
may well be resetting due to the input voltage dropping like a stone when you power up the motors
(or try to switch from forward to reverse).

Use proper battery set for the motors, reserve the 9V for just the Arduino and sensors (unless they draw
much current).

No point trying to debug the software if the basic hardware setup isn't robust I feel...

the arduino and the motor set both have 1 9v battery a piece and it still does not work what now :sweat_smile:

Hi Scooter,
What type of 9V batteries are you using, the motors take a lot of current so you need something good! Is there a good GND connection between the motor board and Uno. I can't see why you want to control it via Serial? Don't you want it running around the floor under it's own steam and control?

I'm on about my 5th Bot now, but it will be my first with the Arduino (Uno) as in a previous life I was a Picaxe fan, but it don't touch the Uno and C, but I am struggling a bit with the C...

My last bot used lots of Tamiya bits like you, here's a picture or 2. My current bot is my last bot converted to the Uno, I also make the odd PCB, etc and did my Picaxe version of the shield for a Picaxe 20M2...

Hope it helps, regards.

Mel.

scooter2335:
the arduino and the motor set both have 1 9v battery a piece and it still does not work what now :sweat_smile:

Doesn't necessarily help, the motor may well suck current from the Arduino Vcc line via the motor driver chip if it has to.
Get a proper supply to the motors before worrying about anything else.

Hi, I think at this moment we need a circuit diagram of how batteries, arduino,motor controller and motors are hooked up.
I notice in the software that the loop refers to move motors 1 and or 2. BUT the move function is assigned 0 and 1 as the motor desigators.
Tom.

This is the basic set up of the motor controller to the Arduino Uno only I had an external power supply of 9V for the motors and for the Arduino itself.

I have redone my mapping of the space on the board and I added in my Arduino Ethernet shield on top of the uno, which i recieved today, And moved all of the wires up one tier. I have also located and utilized a AA battery tray and clip that holds 4 AA batteries at once. with a higher current I am able to power the motors, the issue comes in at the motors still have the inability to turn around. I have added a 16 GB fat 16 formatted micro sd card to the Ethernet shield for data logging with the sonar and the Gyro. Both of which i have connected and wired up to the board. the 3- Axis Gyro is using the pins SCL and SDA and is receiving ground and 5V from the arduino, the Max sonar is using now the Analog pins A0- A3 which match up corresponding to the pins on the the Sonar pins GND 5V 0, 0, AN PW BW. when individually tested all of these components operate at full use. the issue comes in when all three are combined which do i prioritize in the While loop how do i properly make this work????????????????? Greatly appreciated

Scott

Did you check this posting I left you in post 5?

I notice in the software that the loop refers to move motors 1 and or 2. BUT the move function is assigned 0 and 1 as the motor desigators.

In the loop you are controlling motor 1 and 2, but in the function they are called motor 0 and 1?
In the loop try controlling motor 0 and 1 and see if that makes a difference.
Tom..

Nope, even after adjusting the code and applying the newer higher aperture battery back, which scared the hell out of me, it seems to be registering the second command as another move ahead. What am I doing wrong here?

Scott.

scooter2335:
Nope, even after adjusting the code and applying the newer higher aperture battery back, which scared the hell out of me, it seems to be registering the second command as another move ahead. What am I doing wrong here?

Scott.

Can you post the adjusted code? So we're talking about the same thing...

//motor A connected between A01 and A02
//motor B connected between B01 and B02

int STBY = 10; //standby

//Motor A
int PWMA = 3; //Speed control 
int AIN1 = 9; //Direction
int AIN2 = 8; //Direction

//Motor B
int PWMB = 5; //Speed control
int BIN1 = 11; //Direction
int BIN2 = 12; //Direction

void setup(){
  pinMode(STBY, OUTPUT);

  pinMode(PWMA, OUTPUT);
  pinMode(AIN1, OUTPUT);
  pinMode(AIN2, OUTPUT);

  pinMode(PWMB, OUTPUT);
  pinMode(BIN1, OUTPUT);
  pinMode(BIN2, OUTPUT);
}

void loop(){
  move(1, 100, 0); //motor 1, full speed, left
  move(0, 100, 0); //motor 2, full speed, left

  delay(1000); //go for 1 second
  stop(); //stop
  delay(2000); //hold for 250ms until move again

  move(1, 255, 1); //motor 1, half speed, right
  move(0, 255, 0); //motor 2, half speed, right

  delay(1000);
  stop();
  delay(1000);
}


void move(int motor, int speed, int direction){
//Move specific motor at speed and direction
//motor: 0 for B 1 for A
//speed: 0 is off, and 255 is full speed
//direction: 0 clockwise, 1 counter-clockwise

  digitalWrite(STBY, HIGH); //disable standby

  boolean inPin1 = LOW;
  boolean inPin2 = HIGH;

  if(direction == 1){
    inPin1 = HIGH;
    inPin2 = LOW;
  }
    
  if(direction == 0){
     inPin1 = LOW;
     inPin2 = HIGH;
   }

  if(motor == 1){
    digitalWrite(AIN1, inPin1);
    digitalWrite(AIN2, inPin2);
    analogWrite(PWMA, speed);
  }else{
    digitalWrite(BIN1, inPin1);
    digitalWrite(BIN2, inPin2);
    analogWrite(PWMB, speed);
  }
  
    if(motor == 0){
    digitalWrite(AIN1, inPin1);
    digitalWrite(AIN2, inPin2);
    analogWrite(PWMA, speed);
  }else{
    digitalWrite(BIN1, inPin1);
    digitalWrite(BIN2, inPin2);
    analogWrite(PWMB, speed);
  }
}

void stop(){
//enable standby  
  digitalWrite(STBY, LOW); 
}

There is the modified code according to the requests

sorry for the delay i had work today

thanks again for your help

scott

This is odd:

  if(motor == 1){
    digitalWrite(AIN1, inPin1);
    digitalWrite(AIN2, inPin2);
    analogWrite(PWMA, speed);
  }else{
    digitalWrite(BIN1, inPin1);
    digitalWrite(BIN2, inPin2);
    analogWrite(PWMB, speed);
  }
  
    if(motor == 0){
    digitalWrite(AIN1, inPin1);
    digitalWrite(AIN2, inPin2);
    analogWrite(PWMA, speed);
  }else{
    digitalWrite(BIN1, inPin1);
    digitalWrite(BIN2, inPin2);
    analogWrite(PWMB, speed);
  }

It starts out nicely, if motor is 1, set motor A's pins, else (because motor is 0) set motor B's.

But then you have another if which, when motor is 1, sets motor B's pins & vice versa.

It appears to me that the second section should not be there.

after fixing the code from the combined input the tank moves as desired. But I have a question? when i have the other censors added to the chassis which needs to come first in the code? the code for the rangefinder's code before the motor code, or the gyro code before the motor controller and rangefinder code?

Hi Scooter,
The code for the US rangefinder needs to be perhaps in a loop, where the motors are going forward, as this is I think the only practical use for it?? just call the function when needed and the same for the gyro, etc.

Here's how I did it in my code, but I am no expert with C in fact still a learner..

But it might help, Regards.

Mel.

/*
*******************************
 ;    Filename:        PololuDrive	
 ;    Date: 	       10/08/2013		
 ;    File Version:    27082013	
 ;    Written by :     Mel Saunders		
 ;    Function:	       BuggyDrive	
 ;    Last Revision:   08/09/2013
 ;    Target           Uno
 ; ******************************* 
 
 This program demonstrates the use of an L293 dual H bridge.
 This can run 2x DC motors, control their speed and direction.
 Also servos and various switch inputs are used.
 */

#include <Servo.h>

  Servo scanservo;     //Ping Sensor Servo
  int Left=180, Centre=90, Right=0;  //Servo angle in Degrees ??Hextronic servo works back to front LEFT=180, RIGHT=0
  int distance,cm,FRQ,TD,A,B,TurnTime,switches;
  int randNumber,motorSpeed,action;
  const int MA1=0,MA2=1,MB1=2,MB2=3;  //Motor pins
  const int PWMpin=11;  //Enable pin on L293 for PWM 
  const int scanservopin = A0;  // Pin number for scan servo 
  boolean go; 

void setup()
{ 
  pinMode(MA1, OUTPUT);      // sets the digital pin as output     
  pinMode(MA2, OUTPUT);      // sets the digital pin as output
  pinMode(MB1, OUTPUT);      // sets the digital pin as output      
  pinMode(MB2, OUTPUT);      // sets the digital pin as output
  pinMode(scanservopin, OUTPUT);
  go = true;
  scanservo.attach(scanservopin);  // Attach the scan servo to pin 11

}

// * * * start of Main program * * * *

void loop()
{
  if (go == true)
  {
    scan();      //**** This line calls the US sensor

    do
    {
      distance=scanner(cm);    //***** This line gets the distance from US sensor
      delay(200);
      sound(2200,10);
      delay(200);
    }
    while(distance >20);

    startup();

  }  //go = false, start here!
  distance=scanner(cm);
  if(distance <=10)
  {
    TD=300;  //TimeDelay value
    Halt(TD);
    BackOff();
    TD=500;
    Halt(TD);
    Radar();
  }

  if(distance >=12 and distance <=20)
  { 
    analogWrite(PWMpin,85);
    delay(600);
  }

  if(distance >20)
  {
    switches=0;
    digitalWrite(MA1,HIGH);       //Left motor forward
    digitalWrite(MA2,LOW);
    digitalWrite(MB1,HIGH);      //Right motor forward 
    digitalWrite(MB2,LOW);
    randomSeed(millis());
    TurnTime = random(320,1023);      // Speed for turning, reverese, etc.
    motorSpeed= map(TurnTime,320,1023,255,120);            //random motor speed
    action=motorSpeed && 1;
    switches=analogRead(A1);        //Read analogue switches, TILT, etc.

    if(switches >5)
    {
      Escape();
    }   
  }  
}// end Main loop


//------------------------------------------------------------------
void startup()
{
  digitalWrite(MA1,HIGH);       //Left motor forward
  digitalWrite(MA2,LOW);
  digitalWrite(MB1,HIGH);      //Right motor forward 
  digitalWrite(MB2,LOW);

  for (int i= 40; i <= 255; i++) //start slow, increase speed
  { 
    analogWrite(PWMpin,i);
    delay(50);
  }
  go = false;      //Set go to false
}
//-----------------------------------------------------------------
void Halt(int TD)      //Both motors STOP 
{
  digitalWrite(MA1,LOW);           
  digitalWrite(MA2,LOW);
  digitalWrite(MB1,LOW);      
  digitalWrite(MB2,LOW);
  delay(TD);
}
//------------------------------------------------------------------
void Rturn()      //Turn right
{
  analogWrite(PWMpin,motorSpeed);  //Set Motor Speed
  digitalWrite(MA1,HIGH);       //Left motor forward
  digitalWrite(MA2,LOW);
  digitalWrite(MB1,LOW);       //Right motor reverse 
  digitalWrite(MB2,HIGH);
  delay(TurnTime);            //Set Motor Turn Time
}
//------------------------------------------------------------------
void Lturn()      //Turn left
{
  analogWrite(PWMpin,motorSpeed);   //Set Motor Speed
  digitalWrite(MA1,LOW);            //Left motor reverse
  digitalWrite(MA2,HIGH);
  digitalWrite(MB1,HIGH);           //Right motor forward
  digitalWrite(MB2,LOW);
  delay(TurnTime);                 //Set Motor Turn Time

} 
//------------------------------------------------------------------
void Forward()      //forward
{
  digitalWrite(MA1,HIGH);       //Left motor forward
  digitalWrite(MA2,LOW);
  digitalWrite(MB1,HIGH);      //Right motor forward 
  digitalWrite(MB2,LOW);
}

//------------------------------------------------------------------ 

int  Back(int TD)      //Reverse
{
  analogWrite(PWMpin,motorSpeed);
  digitalWrite(MA1,LOW);       //Left motor reverse
  digitalWrite(MA2,HIGH);
  digitalWrite(MB1,LOW);      //Right motor reverse
  digitalWrite(MB2,HIGH);
  delay(TurnTime);
}
//------------------------------------------------------------------ 
void  BackOff()      //back off!
{
  analogWrite(PWMpin,motorSpeed);
  delay(100);
  digitalWrite(MA1,LOW);       //Left motor reverse
  digitalWrite(MA2,HIGH);
  digitalWrite(MB1,LOW);      //Right motor reverse
  digitalWrite(MB2,HIGH);
  delay(TurnTime);
}
//------------------------------------------------------------------ 
void sound(int FRQ,int TD)
{
  tone(12,FRQ,TD);
}
//------------------------------------------------------------------
void scan()
{
  for (int i=Left; i <= Right; i++) 
  {
    scanservo.write(i); 
    delay(20);
  }
  scanservo.write(Centre); 
}
//------------------------------------------------------------------
long scanner(long cm)
{
  const int pingPin=7, EchoPin=8;
  long duration;

  // The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  pinMode(pingPin, OUTPUT);
  pinMode(EchoPin, INPUT);  
  
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW); 
  duration = pulseIn(EchoPin, HIGH);
  delay(100);

  // convert the time into a distance
  // inches = microsecondsToInches(duration);
  cm = microsecondsToCentimeters(duration);

  delay(100);

  return (cm);
}
long microsecondsToCentimeters(long microseconds)
{
  // The speed of sound is 340 m/s or 29 microseconds per centimeter.
  // The ping travels out and back, so to find the distance of the
  // object we take half of the distance travelled.
  return microseconds / 29 / 2;
}
//------------------------------------------------------------------  
//------------------------------------------------------------------
//------------------------------------------------------------------
//------------------------------------------------------------------

void Radar()
{
  scanservo.write(180);        //Turn (Hexareonic) servo LEFT
  delay(300);
  tone(12,1500,30);            //Beep
  A=scanner(cm);               //Read distance
  delay(100);
  scanservo.write(0);          //Turn (Hexareonic) servo RIGHT
  delay(300);  
  tone(12,1500,30);
  B=scanner(cm);              //Read distance
  delay(100);
  scanservo.write(90);        //Point scanner forward
  delay(100);  

  if (A>B)                    //If Left distance longer then Right, then turn Left. 
  {
    Lturn();  //Then turn left
  }
  else  
  {
    Rturn();  //Then turn right
  }
  delay(100);
}
//------------------------------------------------------------------  
  void Escape()
{ 
   switches=analogRead(A1);    //Read analogue switches, TILT, etc.
  if(switches>245 and switches <255)
 {
   BackOff();                 //Reverse awhile
   twirl();                   //A short spin around 
 }
}
//------------------------------------------------------------------  
void twirl()
{
  action=TurnTime & 1;
  if(action=1)                  //Twirl Left
  {
  digitalWrite(MA1,LOW);       //Left motor reverse
  digitalWrite(MA2,HIGH);
  digitalWrite(MB1,HIGH);      //Right motor forward
  digitalWrite(MB2,LOW);
  delay(2000);
  }
  else                          //Twirl Right
  {
  digitalWrite(MA1,HIGH);       //Left motor forward
  digitalWrite(MA2,LOW);
  digitalWrite(MB1,LOW);       //Right motor reverse 
  digitalWrite(MB2,HIGH);
  delay(2000);
  }
 }

Given that loop is called repeatedly, the order is really not critical, but generally, people read the sensors first and then command the mechanicals - you don't then have to worry about issues on the first iteration when there is not sensor data available but you're instructing the motors anyway.