Alexander Robotics

From Idea to Prototype: Brains

The machine has a chassis and motors now, but still remains the Scarecrow of robots. There are two directions to take when giving a robot a brain: analog circuits or a microcontroller. BEAM robotics is the best example of analog circuits for logic, using transistors and comparators to determine the robot’s behavior. The schematic is the program. A microcontroller consists of a processor, input and output pins, voltage regulators, and some method to connect it to a computer for programming. The right microcontroller depends on your price and performance needs.

I went with an Arduino Duemillanove (pronunciation) microcontroller because at $30 it’s affordable and offers enough performance. And to get the blog cred. I bought the Arduino from Adafruit.com. I like what Lady Ada (Limor Fried) is doing for the Open Source Hardware movement and am happy to support the business.

The Arduino’s purpose in this iteration is simply to tell the two motors which direction to turn. Because an Arduino cannot provide the necessary power for these 12V motors, it controls a motor driver, which supplies the higher power.

A basic motor driver consist of an H-bridge and some supporting capacitors and diodes to help smooth the current. The SN754410 is a quad half H-bridge. If an H-bridge can control a single motor, the quad half H-bridge can power two motors (4 (quad) * .5 (half) * 1 = 2). The motor driver in this robot uses the SN754410 because it’s a popular chip with good documentation, can drive up to 36V at 1A continuous current, and is cheap at around $2 per chip.

Hardware

Fritzing schematic of Arduino and Motor Driver
Arduino and Motor Driver

The image of a completed motor driver connected to an Arduino may seem daunting. Let’s break it down into easier-to-digest chunks.

Diagram of the SN754410 motor driver.
SN754410

The core component in this motor driver is Texas Instrument’s SN754410. The datasheet tells us what each pin on the chip is for, what the voltage requirements of that pin are, and so forth. The datasheet is the reference when building a circuit.

Fritzing schematic of motor driver with an unregulated power supply.
Unregulated Power Supply

The motor driver uses a 12V unregulated power supply. Regulated power is a clean, steady voltage, usually from a component known as a Voltage Regulator. Unregulated power is the raw output from the power supply. Motors are thirsty beasts and need access to the raw power, which is why the 12V battery connects directly into the SN754410’s supply voltage (Vcc).

Fritzing schematic showing wiring to enable inputs on the motor
    driver.
Enable Inputs

The Arduino provides a constant 5V supply to three inputs on the SN754410. The top right input of the SN754410 (pin 16) supplies the power for the logic circuitry on the chip. The SN754410 avoids the noisy, unregulated supply for the more precise logic functionality.

The bottom right input (pin 9) enables the right motor, and the top left input (pin 1) enables the left motor. The two enable inputs are always set to High (5V) so, you guessed it, the two motors will always be enabled. To be clear here, enabled does not mean the motors will be on; it means they are allowed to turn on.

Fritzing schematic showing Arduino PWM pins connecting to the SN754410.
Arduino PWM pins to SN754410

The Arduino uses two pins for each motor to control that motor’s direction. The H-Bridge post brings some insight into why; essentially, one pin will be Low and one will be High for turning clockwise. To switch directions, simply switch the pins’ output voltage. To stop the motor (a coast stop, not an electronic brake), both pins should be set to Low.

When I use Low or High, I’m usually referencing Arduino’s digitalWrite function, which can write a 0V (Low) or 5V (High). It’s binary.

A quick note here: When using a function like digitalWrite or analogWrite, that pin will output the selected value until told otherwise. In other words, when you set pin 5 to Low and pin 6 to High, the motor will spin until you change the values of pin 5 and 6.

Now what if we want more control over speed, rather than Off and Fast? Enter Pulse Width Modulation (PWM). PWM still sends a High voltage through its pin, but in configurable bursts known as duty cycles. Calling analogWrite with a scale of 0–255 sets the PWM duty cycle. For example, analogWrite(pin, 255) is equivalent to digitalWrite(pin, High) and analogWrite(pin, 127) is about half the speed of the digitalWrite with High.

Only some pins on the Arduino support PWM; the pins used in this layout (5, 6, 9, 10) all do. A pin that supports PWM can be used with analogWrite or digitalWrite. Also — a point that confused me at first — since only one pin per motor is set to High or whatever PWM value, the other pin is still set to Low or 0 if using digitalWrite or analogWrite respectively.

Fritzing schematic of SN754410 output to motors
SN754410 output to motors

For the final hardware chunk, let’s look at how the SN754410 powers the motor. SN754410’s outputs 3 and 6 power the left motor, and outputs 11 and 14 power the right motor. You should be okay connecting these outputs directly to the motor leads. Still, motors are noisy and thirsty, so let’s alleviate these issues some.

A 0.1 μF capacitor sits between ground and each motor terminal. The capacitor serves two purposes: smooth the voltage to the motor and provide quick power when the battery can’t catch up (usually happens when the motor starts).

Another simple task to reduce motor noise is twist the wires connecting to the motor leads. Twisting reduces the “electromagnetic radiation” interference produced from the motor.

Software

A brief history of the Arduino is in order to answer a simple question: What language do you program an Arduino with?

Processing is an open source Java-based language with its own IDE (a programming environment). Processing was designed as a language for non-programmers to pick up. It hides a lot of the boilerplate code from the programmer.

The Wiring project came along as an affordable development board (sound familiar?). Wiring used the Processing IDE and a simplified C/C++ language for programming the board, which was based on an Atmel AVR chip.

The Arduino was originally derived from the Wiring project, using the Processing IDE and Wiring language. The original Arduino used a cheaper Atmel AVR chip than the wiring board, the ATmega 8.

Okay, to answer the question: The Arduino is programmed with the Wiring language, a language similar to C and C++ with some extra functionality for dealing with hardware and extras like Libraries. The IDE used to write the code and upload it to the Arduino is based on Processing. Phew. Oh, and an Arduino program is called a “sketch.”

The sketch below moves the robot forward for 10 seconds, then backwards, turns left, turns right, and repeats. The code uses Pulse Width Modulation when controlling the motors.

// Sets the Left motor to pins 5 and 6
int motor_left[] = {6, 5};
// Sets the Right motor to pins 9 and 10
int motor_right[] = {10, 9};

// Run when the Arduino starts up or is reset.
// Configures initial values for the first run.
void setup() {
  // Sets up Serial communication with the computer.
  // Not used in this sketch, but useful when printing
  // to the computer screen when debugging.
  Serial.begin(9600);
  
  // Sets the Arduino's pins to OUTPUT for controlling
  // the motor. A pin can be used to INPUT or OUTPUT.
  for (int i = 0; i < 2; i++) {
    pinMode(motor_left[i], OUTPUT);
    pinMode(motor_right[i], OUTPUT);
  }
}

// The loop runs as long as the Arduino is on.
void loop() {
  // Stops each motor
  motor_stop();
  // Delays in milliseconds, so 5000 = 5 seconds.
  // Added a delay here because I wanted a few seconds
  // for the robot to pause before each run.
  delay(5000);
  
  // Drive forward for 10 seconds. drive_forward()
  // sets the motion of the motion of the motors, the
  // delay sets the duration of the movement.
  drive_forward();
  delay(10000);
  motor_stop();

  // Drives backwards for 10 seconds
  drive_backward();
  delay(10000);
  motor_stop();

  // Turns Left
  turn_left();
  delay(5000);
  motor_stop();

  // Turns right
  turn_right();
  delay(5000);
  motor_stop();
}


// Sets each motor lead to 0V, causing the motor to
// coast to a stop.
void motor_stop() {
  analogWrite(motor_left[0], 0);
  analogWrite(motor_left[1], 0);

  analogWrite(motor_right[0], 0);
  analogWrite(motor_right[1], 0);
}

// Sets the motors to both go forward at a little
// over half speed. 150 is the Pulse Width Modulation
// setting, 255 is max, 0 is minimum.
void drive_forward() {
  analogWrite(motor_left[0], 150);
  analogWrite(motor_left[1], 0);

  analogWrite(motor_right[0], 150);
  analogWrite(motor_right[1], 0);
 
  // The digitalWrite equivalent
  //digitalWrite(motor_left[0], HIGH);
  //digitalWrite(motor_left[1], LOW);
  //digitalWrite(motor_right[0], HIGH);
  //digitalWrite(motor_right[1], LOW);  
}

// Sets the motors to drive backwards.
void drive_backward() {
  analogWrite(motor_left[0], 0);
  analogWrite(motor_left[1], 150);
  
  analogWrite(motor_right[0], 0);
  analogWrite(motor_right[1], 150);
}

// Turns left by turning one motor clockwise and the
// other counterclockwise.
void turn_left() {
  analogWrite(motor_left[0], 0);
  analogWrite(motor_left[1], 150);
  
  analogWrite(motor_right[0], 150);
  analogWrite(motor_right[1], 0);
}

// Turns Right by turning one motor counterclockwise
// and the other clockwise.
void turn_right() {
  analogWrite(motor_left[0], 150);
  analogWrite(motor_left[1], 0);
  
  analogWrite(motor_right[0], 0);
  analogWrite(motor_right[1], 150);
}

Downloads

The source for the Arduino to Motor Driver image requires the open source program Fritzing to view. The Arduino source code is available as well.

As this entire website is stored in source control — including posts, images, and files — you can check out GitHub for updates and history on any these files.

blog comments powered by Disqus