Running an external 5v power supply with an arduino

Hi All,

So I'm working on my FYP which is an Arduino / Pi based onboard-evolution object avoidance and mapping robot.

My issue is that I've used a motor shield on my Mega - Motor Shield - Arduino motor/stepper/servo control

As you can see there were no headers with this shield so I'm stuck using the pins which protrude beyond the shield on the Mega. This isn't much of an issue.

My problem is that I need to provide power to a servo, HC-SR04, Sharp IR sensor (GP2Y0A21YK0F), 4 home-made encoders and 4 home-made IR sensors (based off of this design but using photodiodes http://www.societyofrobots.com/schematics_infraredemitdet.shtml)

Currently I have a 9.6v battery pack connected to the motor shield and a 9.6v battery pack connected in parallel to the arduino and raspberry pi. What I want to do is to pull another 5v line off of this in parallel and provide 5v power to all of these modules.

  1. How would I go about connecting the ground on my current power board and the ground on the arduino for these pins? I assume that I need to connect these 5v supplies to the arduino ground, or will any ground and 5v power supply do and I just need to run the output pins back to the arduino? (or the input and output in the case of the SR04)

  2. If I just need the external 5v and ground will I need to de-couple all of these devices?

  3. Am I putting too much stress on one 9.6v battery for these devices? Is it likely that I will see strange behaviour resulting from this design?

I'm pretty new to electronics so any smarter solutions would be much appreciated here.

Thanks

Liam

What kind of motors are connected to the motor shield, beside the servo ?

Your encoders and sensors use little current. So it is best to power them with the 5V pin of the Arduino (I assume that the Arduino is used to read the sensors).

The servo probably is a 5V servo ?
Those servos could easily use 1A. The best solution is to use a DC/DC converter to make 5V.

I don't understand you question about grounding. Can you make a photo or a drawing ?

I have four 6v motors wired into the shield.

The servo is a towerpro sg90 micro servo

I was going to attach the servo to the motor shield's servo1 pins, is this not the best way to do this?

Proposed circuit is below, let me know if you have any more questions and thanks for the help so far

Signal wires needs a ground wire. So yes, the Arduino ground should be connected to the circuit board and sensors.

I agree with Krodal's suggestion. Feed the Arduino Vin pin (or barrel jack) from 9.6V, power the sensors from the Arduino's 5V pin, and use a DC-DC converter to generate 5V for the servos. That way, the Arduino and sensors get a smoother, better regulated 5V supply.

So what you're suggesting is that I feed the sensors from the arduino but the servo from an external 5v?

Also the issue here is feeding several devices the 5v, should I run a wire from the 5v on the arduino through all the devices? I only have access to two 5v pins due to the shield placement.

liomry:
Also the issue here is feeding several devices the 5v, should I run a wire from the 5v on the arduino through all the devices? I only have access to two 5v pins due to the shield placement.

Better to make a junction close to the 5V Arduino pin and star the 5V supplies out from there. Similarly for the grounds.

So if I understand correctly -

Swap my original proposal, have the BEC feed the servo and the circuit board fed from the arduino +5v and feeding into the arduino ground?

Is this not in danger of exceeding the 40ma per pin threshold or does that not apply to the 5v pins?

The 40mA per pin limit applies to the output pins of the atmega328p (and hence the Arduino output pins), not the 5V and ground connections. With 9.6V input to the Arduino, you should be able to draw up to about 100mA from the 5V pin before the regulator runs uncomfortably hot.

All this time I thought it did :astonished:

Thanks a million for all the help on this, I'm breadboarding the new circuit now and will report back with how I get on

Ok so I have the servo being fed from the external power supply and the HC-SR04 and one of my passive sensors attached to the arduino 5v via a breadboard.

I'm running into problems with the ultrasonic sensor. My program and a sample output are below. The problem is that it's giving incorrect readings. To explain, the SR04 is mounted on the servo and acting like a radar so I want to bulid an array of distances as it sweeps for mapping the environment.

As you can see it gives two very inaccurate readings and then defaults to 0 for a few pings. I am assuming that this is some form of power problem resulting from this circuit. Any suggestions? I've already tried running the sensor from the same supply as the servo with no difference.

The reason I'm taking a median ping of 1 in the program is because 3 was making the servo rotate too slowly, I might change to median of 3 with 20 degree intervals, however that will still give the same issue if most of my pings are 0cm.

Ping: 0cm
308
Ping: 0cm
311
Ping: 0cm
309
Ping: 0cm
311
Ping: 49cm
314
Ping: 185cm
312
Ping: 0cm
312
Ping: 0cm
311
Ping: 0cm
311
Ping: 0cm
308
Ping: 0cm
311
Ping: 0cm
309
Ping: 0cm
311

Are the readings any different if you disconnect the servo?

I solved the issue by going back to basics and making sure to send a low signal immediately before the high signal. The problem here seems to have been the newping library, or my use of it at least.

Following on from this I have two minor issues

  1. When I open a serial monitor when running the arduino via usb the servo stops traversing for a few seconds and then resets position - is this the normal behaviour and can it be altered?

  2. The servo traversal isn't very smooth, I was hoping for a 180 degree traversal and return roughly every second and a half taking readings at 5 or 10 degree intervals. Possibly there's a better way to program in order to achieve this? Current code is below (pieced together from the servo tutorial and the SR04 example for the most part)

I realise I've gone well beyond the original question here, should I maybe open a new thread in the relevant forum or is it better to keep the same project together?

#include <AFMotor.h>
#include <Servo.h>
Servo myservo;  // create servo object to control a servo 
                // a maximum of eight servo objects can be created 
long duration, inches, cm; 
int pos = 0;
int sensorPin = A8; // select the input pin for the potentiometer int ledPin = 13; // select the pin for the LED int sensorValue = 0; // variable to store the value coming from the sensor
int sensorValue = 0;
int trigPin=52;
int echoPin=53;

void setup()                    // run once, when the sketch starts
{
  Serial.begin(9600); 
  myservo.attach(9);  
    pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop() {
   for(pos = 0; pos < 180; pos += 5)  // goes from 0 degrees to 180 degrees 
  {                                  // in steps of 1 degree 
    myservo.write(pos); 
ping();
  sensorValue = analogRead(sensorPin);    
  Serial.println(sensorValue);    // tell servo to go to position in variable 'pos' 
    delay(5);                     
  } 
  for(pos = 180; pos>=1; pos-=5)     // goes from 180 degrees to 0 degrees 
  {                                
    myservo.write(pos);
ping();
  sensorValue = analogRead(sensorPin);    
  Serial.println(sensorValue);    // tell servo to go to position in variable 'pos' 
    delay(5);                       
  }               

}

void ping()
{ 
  // 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(trigPin, OUTPUT);
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  //delayMicroseconds(2);
 
  // a HIGH
  // pulse whose duration is the time (in microseconds) from the sending
  // of the ping to the reception of its echo off of an object.
  
  duration = pulseIn(echoPin, HIGH);
 
  // convert the time into a distance
  inches = microsecondsToInches(duration);
  cm = microsecondsToCentimeters(duration);
  
  Serial.print("Distance: [");
  Serial.print(inches);
  Serial.print("]inches. [");
  Serial.print(cm);
  Serial.print("]cm\n");
  delay(10);
}
 
long microsecondsToInches(long microseconds)
{
  // According to Parallax's datasheet for the PING))), there are
  // 73.746 microseconds per inch (i.e. sound travels at 1130 feet per
  // second).  This gives the distance travelled by the ping, outbound
  // and return, so we divide by 2 to get the distance of the obstacle.
  return microseconds / 74 / 2;
}
 
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;
}