Go Down

Topic: WHy does my robot work when connected to PC but not when on battery power? (Read 5983 times) previous topic - next topic

road_thing

I've built a very simple object avoidance robot using a Tamiya twin-motor chassis, an L9110 motor controller, and a 9G micro servo scanning a HC-SR04 sensor.  Battery pack is 4XAA rechargeables.  I run power to the onboard Arduino Uno via the barrel connector, with a separate power wire straight to the L9110 to make sure it gets enough current.  There's probably thousands of them just like mine out there.

The problem I'm having is this:  When I try to run the robot off the battery pack, all it does is run straight ahead with the servo scanning the sensor back and forth, but it doesn't react to obstacles.  If I plug the USB cable into the Arduino's USB port, I can monitor the sensor via the serial monitor, and it reacts properly, i.e., when there's an obstacle in front it prints "object within"  "(Distance)" "cm in front" just like the sketch says, and the motors stop, reverse, spin left and resume forward.

Can anybody tell me why it doesn't do the same thing when it's not plugged into the USB but is running solely off the battery pack?  (the batteries have a fresh charge and the pack reads 5.8V).  Is there a different power circuit or could I have blown something up on the Arduino?

Thanks in advance...

Isaac96

Try separate battery packs for the arduino and motors. All you have to do is connect the grounds and connect 1 positive wire to the Arduino and the other one to the L9110. 
Do not PM me for help. I will delete immediately.
CONNECT THE GROUNDS!

After Tuesday, even the calendar goes W T F

JimboZA

Battery pack is 4XAA rechargeables.  I run power to the onboard Arduino Uno via the barrel connector,
That's 4x1.2v nominal, so 4.8 total, or as you say just under 6V when they're fresh.

Alas, that's not enough:

Quote
The board can be supplied with power ... from the DC power jack (7 - 12V)
Johannesburg hams call me: ZS6JMB on Highveld rep 145.7875 (-600 & 88.5 tone)
Dr Perry Cox: "Help me to help you, help me to help you...."
Your answer may already be here: https://forum.arduino.cc/index.php?topic=384198.0

road_thing

Thanks, guys, I have a remarkable flair for ignoring the obvious...

I hooked a 9V cell to the Arduino via the barrel connector, then plugged the battery pack to the motor chip, with everything on a common ground.  The problem persists.  When I plug the USB cable in it works right, even with the 9V and 4XAA connected.  As soon as I unplug the USB, it quits responding to the sensor.

I'll check my wiring and try again.

mart256

Thanks, guys, I have a remarkable flair for ignoring the obvious...

I hooked a 9V cell to the Arduino via the barrel connector, then plugged the battery pack to the motor chip, with everything on a common ground.  The problem persists.  When I plug the USB cable in it works right, even with the 9V and 4XAA connected.  As soon as I unplug the USB, it quits responding to the sensor.

I'll check my wiring and try again.
Disable the serial commands and serial begin when not running from usb. Ive got trouble with some arduinos not running well when you call the serial port and the usb is not connected.

road_thing

mart256, thanks!

I tried it, but I get the same result.

Here's my sketch:

Code: [Select]


//   this sketch moves a robot vehicle forward,
//   using a 9110 motor driver chip and
//    sweeping a servo (connected to pin 9) back and forth
//    when the sensor detects an obstacle, the robot turns away and continues to move forward
//========================================


// ----------LIBRARIES--------------

#include <Servo.h>
#include <NewPing.h>

// --------CONSTANTS (won't change)---------------

const int servoPin = 9;               // the pin number for the servo signal
const int servoMinDegrees = 0;        // the limits to servo movement
const int servoMaxDegrees = 180;      //speeder position numbers are on the left end of the sweep

#define TRIGGER_PIN  12  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     11  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.



const int AIA = 3;                    // (pwm) pin 9 connected to pin A-IA   (left motor fwrd)
const int AIB = 5;                    // (pwm) pin 5 connected to pin A-IB   (left motor bkwd)
const int BIA = 4;                   // (pwm) pin 10 connected to pin B-IA  (right motor fwrd)
const int BIB = 6;                    // (pwm) pin 6 connected to pin B-IB   (right motor bkwd)

byte speed = 250;                    // change this (0-255) to control the speed of the motors

 

//------------ VARIABLES (will change)---------------------


Servo myservo;  // create servo object to control a servo
int Distance = 0;
int servoPosition = 90;                     // the current angle of the servo - starting at 90.
//int servoSlowInterval = 10;               // millisecs between servo moves in two-speed case
//int servoFastInterval = 10;               // millisecs between servo moves in two-speed cas
int servoInterval = 5;                     //this sets the constant sweep speed if not using the two-speed feature
int servoDegrees = 1;                       // amount servo moves at each step
                                              //    will be changed to negative value for movement in the other direction
 
unsigned long currentMillis = 0;              // stores the value of millis() in each iteration of loop()

unsigned long previousServoMillis = 0;           // the time when the servo was last moved


//========================================



void setup() {

  //Serial.begin(115200);
 // Serial.println("Starting Servo Sweep Using Millis function");  // so we know what sketch is running

  pinMode(TRIGGER_PIN, OUTPUT);   //  set up sensor pins
  pinMode(ECHO_PIN, INPUT); 
 
  myservo.write(servoPosition); // sets the initial position
  myservo.attach(servoPin);
 
  pinMode(AIA, OUTPUT); // set motor pins to output
  pinMode(AIB, OUTPUT);
  pinMode(BIA, OUTPUT);
  pinMode(BIB, OUTPUT);
 
  digitalWrite(3, speed);                              //start both motors forward
  digitalWrite(4, speed);

}

//========================================
void loop() {                                          //Notice that none of the action happens in loop() apart from reading millis()
                                                      //   it just calls the functions that have the action code

  currentMillis = millis();                           // capture the latest value of millis()
 
 
 
  servoSweep();

}

//============Subroutines   ========================================




void forward()
{
  digitalWrite(AIA, speed);
  digitalWrite(AIB, 0);
  digitalWrite(BIA, speed);
  digitalWrite(BIB, 0);
}

void backward()
{
  digitalWrite(AIA, 0);
  digitalWrite(AIB, speed);
  digitalWrite(BIA, 0);
  digitalWrite(BIB, speed);
}

void rightSpin()
{
  digitalWrite(AIA, speed);
  digitalWrite(AIB, 0);
  digitalWrite(BIA, 0);
  digitalWrite(BIB, speed);
}

void leftSpin()
{
  digitalWrite(AIA, 0);
  digitalWrite(AIB, speed);
  digitalWrite(BIA, speed);
  digitalWrite(BIB, 0);
}

void rightSlide()
{
  digitalWrite(AIA, speed);
  digitalWrite(AIB, 0);
  digitalWrite(BIA, 0);
  digitalWrite(BIB, 0);
}

void leftSlide()
{
  digitalWrite(AIA, 0);
  digitalWrite(AIB, 0);
  digitalWrite(BIA, speed);
  digitalWrite(BIB, 0);
}

void fullStop()
{
  digitalWrite(AIA, 0);
  digitalWrite(AIB, 0);
  digitalWrite(BIA, 0);
  digitalWrite(BIB, 0);
}

void servoSweep() {
 
  if (currentMillis - previousServoMillis >= servoInterval) {            // its time for another move

    previousServoMillis += servoInterval;                                // update
   
    servoPosition = servoPosition + servoDegrees;                        // servoDegrees might be negative

   
    if ((servoPosition >= servoMaxDegrees) || (servoPosition <= servoMinDegrees))  {            // if the servo is at either extreme change the sign of the degrees to make it move the other way

      servoDegrees = - servoDegrees;                                     // reverse direction
      servoPosition = servoPosition + servoDegrees;                        // and update the position to ensure it is within range

    }
   
       
       
   if (servoPosition == 1)  {                                  //  if servo facing right side
    //int Distance = 199;                                        // Distance must never equal 0
    Distance = sonar.ping_cm();                                //  ping
    if (Distance !=0) {                                         // if Non-zero value for Distance

   if (Distance < 30) {                                        // If object is close

      //Serial.print("object within  ");                         //output to monitor for debugging
      //Serial.print (Distance);                                 
      //Serial.println (" cm on right");                         
      fullStop();
      delay(50);
      //Serial.println (" stopped ");                                   
      leftSlide();
      delay(3000);
      //Serial.println (" sliding left ");                             
      forward();
      //Serial.println (" moving forward ");                             

   }       
   }
   }   
  if (servoPosition == 90)   {                                  // ping if servo facing front
    //int Distance = 199;
    Distance = sonar.ping_cm();
     if (Distance !=0) {
                                                                //If object is within 30 cm, avoid 
    if (Distance < 30) {                                         
      //Serial.print("object within  ");
      //Serial.print (Distance);
      //Serial.println (" cm in front ");                           
      fullStop();
      delay(50);
      backward();
      delay(1000);
      leftSpin();
      delay(2000);
      forward();
    }     
    }
    }
  if (servoPosition == 179) {                                     // ping if servo facing left side
    //int Distance = 199;
    Distance = sonar.ping_cm();
    if (Distance !=0) {
                                                                  //If object is within 30 cm, avoid
  if (Distance < 30) {
      //Serial.print("object within  ");
     // Serial.print (Distance);
     // Serial.println (" cm on left");
      fullStop();
      delay(50);
      rightSlide();
      delay(3000);
      forward();     
     }
     }
     }
    myservo.write(servoPosition);                                       // make the servo move to the next position
                                                                        // and record the time when the move happened (??)

 //   Serial.println(servoPosition);

  }
  }
 
//========================================END

road_thing

OK, I got it working.  I had been powering the sensor and the servo from the Arduino outputs (5V for the servo and 3.3V for the sensor), but when I switched the servo power from the Arduino to the 4XAA battery pack everything smoothed out and it runs like it should.  I did switch the sensor over to the 5V pin.

I don't know if the servo pulls enough current from the Arduino to "starve" the sensor, or if it sets up some noise in the circuit that the sensor doesn't like, but this seems to be the fix.

Thanks for taking the time to offer advice!

mart256

OK, I got it working.  I had been powering the sensor and the servo from the Arduino outputs (5V for the servo and 3.3V for the sensor), but when I switched the servo power from the Arduino to the 4XAA battery pack everything smoothed out and it runs like it should.  I did switch the sensor over to the 5V pin.

I don't know if the servo pulls enough current from the Arduino to "starve" the sensor, or if it sets up some noise in the circuit that the sensor doesn't like, but this seems to be the fix.

Thanks for taking the time to offer advice!
Didnt you try this before as said in one of your previous posts?

TomGeorge

Hi,
Have you lifted the robot up so it was not driving, ie motors under no load, what happens in either condition.
Do you have 0.1uF caps across the motor terminals.
What I am suggesting is motor noise is causing problems, your USB supply is low impedance so any noise on the supply will to a degree be damped by the low imedance.
Battery power, the impedance is usually higher so less damping.
A 0.1uF at both battery terminals may help.
The fact that the servo scans properly in both cases is puzzling.

Can you post a picture of your project please.

Thanks..  Tom... :)
Everything runs on smoke, let the smoke out, it stops running....

road_thing

mart256:  Maybe I'm not understanding your question but, no, I hadn't tried this before.

TomGeorge:  It's working loaded and unloaded now.  No caps on the motors, I'll try that next time I have it apart, but for right now it's working OK.  Here's a picture:

Southpark

Can anybody tell me why it doesn't do the same thing when it's not plugged into the USB but is running solely off the battery pack?  (the batteries have a fresh charge and the pack reads 5.8V).  Is there a different power circuit or could I have blown something up on the Arduino?

Thanks in advance...
Can always check by using your multimeter to take measurements. Such as measuring supply voltages to your board and your sensors etc. And, if possible, add some kind of wireless communications system so that the bot can broadcast some sensor values to your computer, where you can see the values - to make sure that sensible values are coming out. If the bot wants to move, then prop something under it so that its wheels can spin but it won't go anywhere.

Go Up