BB-8 (v2) drive electronics

This is how I did the electronics for version 2 of my BB-8 droid. Note that I could have done everything below with off-the-shelf parts but I wanted to keep the cost low by using what I had or could get very cheap or for free, and I wanted to use this to learn more basic electronics.

BB-8 motor control system.
BB-8 motor control system including H bridge circuits, motors, batteries and remove control receiver.
Drive electronics in place.
BB-8 (v2) drive system electronics in place.
Drive electronics in place - side view.
BB-8 (v2) drive system electronics in place - side view.

The 1st photo above is of the tank/differential motor drive system before mounting it all on a drive plate and with the circuits still on breadboards. The other photos are the completed drive systems that go in the ball. It works the same way that the Sphero BB-8 droid toy works. The schematic is also below. To make the ball rotate I'm using two motors salvaged from old cordless drills. Each drill is powered by its own drill battery and its own H bridge circuit. To tell them to move I'm using a remote control receiver from a toy RC truck. I simply disconnected the truck's motors and send that output to an intermediate circuit that converts it to something what works well with an Arduino. The Arduino then takes that and output to some transistors that then controls an H bridge circuit for each motor. The speed is controlled by having the Arduino pulse those transistors using Pulse Width Modulation (PWM).

In the photo below the motors are in the bottom half of the ball for testing while finallizing the circuit.

Motors in the ball during testing.
BB-8 motor control system in the ball for testing.

The following video is part 1 in a series on making this BB-8 droid and though it doesn't go through wiring up the electronics step-by-step, it does show them at different stages and mounting them in the BB-8.

BB-8 (v2) drive system schematic

Below is the schematic for the drive system. The section drawn below the Arduino is for taking input from my remote control (RC) receiver and converting it to a form that the Arduino can understand. The section above the Arduino is two H bridge circuits for controlling the two motors. You can buy single or dual H bridge boards already made, however, since I needed somewhere between 5 amps and 10 amps for my motors, commercially made H bridge boards for that current was above my budget so I made the circuits shown from scratch instead. But now that I know what my electrical current requirements are, I've found some dual H-bridge boards that are affordable and if I didn't value the learning experience in making my own, I would have bought a dual H-bridge/motor driver board instead instead. Here are some affordable dual H-bridge/motor driver boards which you can buy online:

BB-8 motor control system schematic.
BB-8 motor control system schematic.

Here is the parts list for the dual H-bridge board:

  • resistors: 4 x 10kΏ, 4 x 2kΏ
  • MOSFETs: 2 x FQP27P06, 2 x PSMN02230PL
  • NPN transistors: 4 x 2N2222A
  • diodes: 2 x G1750
  • switches: 2 that are rated at least 17V DC and 10A
  • fuses: 2 x 10A fuses (1/4" x 1 1/4") glass tube type
  • fuse holders: 2 (I cut mine from a fuse block that had two attached to each other)
  • heat sinks for mounting the MOSFETs on to (see the photos for what size worked for me, mine were cut from a larger piece)
  • female headers (pin headers): to plug wires into the board from the Arduino I put on some female headers with 5 holes. You can buy a pack of 5 36-pin 0.1" female headers from adafruit.com. You can see them labeled in the perfboard diagram below and in the video above.
  • couplers/connectors: to plug into the motors, battery and fuse holder I used couplers. You can see them labeled in the perfboard diagram below and in the video above.

Parts can be found in electronics stores, automotive stores, online, and recycled from electronics that is being thrown out as garbage. If you can't find the same part numbers as mine then look for what are called equivalent parts.

For mounting it, I put it on a piece of plastic but I first put it on a breadboard and worked out that a single H-bridge would fit on a perf board (a board with pre-made holes in it) as shown in the following diagram. For the dual H-bridge I simply put two of these side-by-side. Note that if your parts are different sizes than mine or your perf board holes are spaced apart a different amount then the dimensions in the diagram below may not help you.

Single H-bridge on a perf board.
How to fit the H-bridge on a perf board.

See below for more about H-bridge boards and the RC receiver to Arduino converter circuit.

BB-8 (v2) Arduino code/sketch

The following code simply turns the motors on and off when the remote control tells it to. There is no acceleration control, stabilization, or anything else.

/*
BB-8 (v2) Arduino code

July 6, 2016 - Switched pins 5 and 6 to 3 and 11 to use the
lower PWM frequency (Arduino UNO). This is because I'm using 
brushed motors, and unlike with brushless motors, the higher 
the frequency, the worse it is for brushed motors.

Full details about this BB-8 droid can be found at:
http://rimstar.org/science_electronics_projects/bb-8_star_wars_droid_v2.htm

Drive motor circuits
--------------------

The two motors are driven independently and so there are two
Radio Controls (RC), one for each motor. Each one can turn
in two directions. A circuit exists between the RC receiver
and the Arduino to give the Arduino the following inputs:
rc1FwdPin - a digital pin indicating that motor 1 should be
 turned on in the _forward_ direction (HIGH) or off (LOW)
rc1RvsPin - a digital pin indicating that motor 1 should be
 turned on in the _reverse_ direction (HIGH) or off (LOW)
rc2FwdPin - an analog pin indicating that motor 2 should be
 turned on in the _forward_ direction (value > 0) or off (0)
rc2RvsPin - a digital pin indicating that motor 2 should be
 turned on in the _reverse_ direction (HIGH) or off (LOW)
Note that one of the pins above is an anlog pin simply to
save on the cost of one more relay. The relays were needed
as using analog for all of them meant problems with common
ground in the RC receiver.

The two motors are then controlled using two H bridge circuits.
Controlling each H bridge circuit is done by the Arduino by
turning on and off transistors using digital pins. There
are two transistors for each H bridge, one for each direction
the motor can turn. The motors each can turn 
counter clockwise (CCW) or clockwise (CW) depending on which
transistor is turned on. Just which direction is called foward
and which is reverse is chosen arbitratily since the BB-8
doesn't really have a forward or reverse direction.
Pulse Width Modulation (PWM) is done to these pins for speed
control. The variables bridge1PWMduty, for motor 1, and 
bridge2PWMduty, for motor 2, have the PWM values. 0 turns
the transistor/motor off.
The pins are:
bridge1CWPin - digital pin for motor 1 clockwise
bridge1CCWPin - digital pin for motor 1 counter clockwise
bridge2CWPin - digital pin for motor 2 clockwise
bridge2CCWPin  - digital pin for motor 2 counter clockwise
Note that since it's a tank drive, to go forward one motor
must turn clockwise while the other motor turns counterclockwise.
*/

int bridge1CWPin = 9;    // digital pin 9 for PWM
int bridge1CCWPin = 10;  // digital pin 10 for PWM
int rc1FwdPin = 7;       // digital pin 7, relay's switch
int rc1RvsPin = 8;       // digital pin 8, relay's switch
int bridge1PWMduty = 48; // duty cycle for H bridge 1
                         // (a value of 25 blew a 1 amp fuse and
                         // 48 blew a 3 amp fuse but not a 5 amp fuse.)

int bridge2CWPin = 3;    // digital pin 3 for PWM
int bridge2CCWPin = 11;   // digital pin 11 for PWM
int rc2FwdPin = 0;       // analog pin 0
int rc2RvsPin = 4;       // digital pin 4, relay's switch
int bridge2PWMduty = 48; // duty cycle for H bridge 2
                         // (a value of 12 blew a 1 amp fuse and
                         // 48 blew a 3 amp fuse but not a 5 amp fuse.)

void turnMotor1Off()
{
  analogWrite(bridge1CWPin, 0); // off
  analogWrite(bridge1CCWPin, 0); // off
}
void turnMotor1CW()
{
  analogWrite(bridge1CWPin, bridge1PWMduty); // PWM duty cycle
  analogWrite(bridge1CCWPin, 0); // off
}
void turnMotor1CCW()
{
  analogWrite(bridge1CWPin, 0); // off
  analogWrite(bridge1CCWPin, bridge1PWMduty); // PWM duty cycle
}

void turnMotor2Off()
{
  analogWrite(bridge2CWPin, 0); // off
  analogWrite(bridge2CCWPin, 0); // off
}
void turnMotor2CW()
{
  analogWrite(bridge2CWPin, bridge2PWMduty); // PWM duty cycle
  analogWrite(bridge2CCWPin, 0); // off
}
void turnMotor2CCW()
{
  analogWrite(bridge2CWPin, 0); // off
  analogWrite(bridge2CCWPin, bridge2PWMduty); // PWM duty cycle
}

void setup()
{
  pinMode(bridge1CWPin, OUTPUT);
  pinMode(bridge1CCWPin, OUTPUT);
  pinMode(bridge2CWPin, OUTPUT);
  pinMode(bridge2CCWPin, OUTPUT);

  turnMotor1Off();
  turnMotor2Off();

  //Serial.begin(9600); // for sending debugging messages
}

boolean debounce(boolean last, int switchPin)
{
  boolean current = digitalRead(switchPin);
  if (last != current) {
    delay(5);
    current = digitalRead(switchPin);
  }
  return current;
}

int rc1FwdValPrev = LOW;
int rc1RvsValPrev = LOW;
int rc2FwdValPrev = 0;
int rc2RvsValPrev = LOW;

void loop()
{
  int rc1FwdVal = 0;
  int rc1RvsVal = 0;
  int rc2FwdVal = 0;
  int rc2RvsVal = 0;
  
  /*
   * Handle Motor 1
   */
   
  // get the relay's switch position
  rc1FwdVal = debounce(rc1FwdValPrev, rc1FwdPin);
  //Serial.print("1F:");
  //Serial.println(rc1FwdVal);
  if (rc1FwdValPrev != rc1FwdVal) {
    // the switch position changed
    rc1FwdValPrev = rc1FwdVal;
    if (rc1FwdVal == HIGH) {
      // the relay was turned on
      turnMotor1CCW();
    } else {
      // the relay was turned off
      turnMotor1Off();
    }
  }

  // get the relay's switch position
  rc1RvsVal = debounce(rc1RvsValPrev, rc1RvsPin);
  //Serial.print("1R:");
  //Serial.println(rc1RvsVal);
  if (rc1RvsValPrev != rc1RvsVal) {
    // the switch position changed
    rc1RvsValPrev = rc1RvsVal;
    if (rc1RvsVal == HIGH) {
      // the relay was turned on
      turnMotor1CW();
    } else {
      // the relay was turned off
      turnMotor1Off();
    }
  }

  /*
   * Handle Motor 2
   */

  rc2FwdVal = analogRead(rc2FwdPin);
  //Serial.print("2F:");
  //Serial.println(rc2FwdVal);
  if (rc2FwdVal > 0 && rc2FwdValPrev == 0) {
    turnMotor2CW();
    rc2FwdValPrev = rc2FwdVal;
  } else if (rc2FwdVal == 0 && rc2FwdValPrev > 0) {
    turnMotor2Off();
    rc2FwdValPrev = 0;
  }

  // get the relay's switch position
  rc2RvsVal = debounce(rc2RvsValPrev, rc2RvsPin);
  //Serial.print("2R:");
  //Serial.println(rc2RvsVal);
  if (rc2RvsValPrev != rc2RvsVal) {
    // the switch position changed
    rc2RvsValPrev = rc2RvsVal;
    if (rc2RvsVal == HIGH) {
      // the relay was turned on
      turnMotor2CCW();
    } else {
      // the relay was turned off
      turnMotor2Off();
    }
  }

  delay(50);
}

The H bridge circuit

The motors are DC motors and some way is needed to make them rotate in one direction or the other direction. As shown below, that can be done manually by connecting a DC motor to the battery one way, which in our example makes the motor rotate counterclockwise. Then, to make it rotate clockwise the connections to the battery are manually reversed.

Rotating counterclockwise.
Motor rotating counterclockwise.
Rotating clockwise.
Motor rotating clockwise.

An H bridge is a circuit that does the same thing electronically. The two NPN transistors in the circuit below are the key to selecting the motor direction using the Arduino.

In the diagram on the left below, the Arduino sets pin 10 HIGH, which means the Arduino applies 5 volts to the pin. That turns on the NPN transistor that's connected to that pin, which then lowers that side of the H bridge to 0V. That causes the lower N-type MOSFET on that side to be off. It also causes the causes the upper P-type MOSFET to be on, resulting in current to be able to flow through that upper MOSFET. For the MOSFETs on the left in that diagram, nothing's changed, and that means the voltages are such that top MOSFET is off and the bottom MOSFET is on. That all causes current to flow through the motor in the direction that makes it turn counterclockwise (for example.)

In the diagram on the right below, the Arduino instead sets pin 9 HIGH, which causes the same to happen to the other side of the H bridge instead. From there what happens is just a mirror of what's described in the paragraph above. Since current flows through the motor in the opposite direction, the motor this time turns clockwise.

Motor turning counterclockwise.
H bridge making a motor turn counterclockwise.
Motor turning clockwise.
H bridge making a motor turn clockwise.

I found this way of using NPN transistors to interface with the Arduino on Lewis Loflin's webpage.

I don't know exactly what the maximum normal current can be through the fuse and diode but I blew 5A fuses and the next highest rated fuse I had was a 10A fuse. As far as I can tell, the G1750 diode is rated for 6A, though it may be higher since all I had to go on was an equivalent diode's datasheet.

Below are views of the completed 2 H bridges on a single board, commonly referred to as a dual H bridge board. The red connectors are for connecting to the batteries and the motors. For the board itself I used a piece of plastic which I'd long ago bought from a hobby store because I didn't have enough perfboard at the time, and it works just as well.

I have found that running the BB-8 for a few minutes does cause the heat sinks that the MOSFETs are mounted on to heat up, so they are necessary.

Dual H bridge - top view.
Homemade/DIY dual H bridge - top view.
Dual H bridge - bottom view.
Homemade/DIY dual H bridge - bottom view.

The remote control receiver to Arduino converter circuit

RC controller to Arduino converter board.

You can find all the details of how I designed and made the radio control receiver to Arduino converter board here. That's the board that contains everything in the above schematic shown below the Arduino. It takes the output of the RC receiver and converts it to a form that the Arduino can understand.

rimstar.org
Contact:
Liked this? Share it with: