Spinning

It’s time to get our hands dirty and really change this firmware. We’re going to make a motor spin, but to do that, firmware won’t be enough.

Preparation

Pick up a Motion Shield and:

  • 9v battery and connector
  • DC motor
  • Jumper
  • Wires
  • Tiny screwdriver

This ^ is the pinout diagram for the motion shield. It shows you how GPIO from the DevBoard are allocated.

We want to spin a motor, so we’re going to use one of the motor output ports at the bottom.

How do motors work?

The standard method of driving DC motors is with a structure called a Full Bridge:

There are two output stages that can assert a voltage of either GND or VS.

If stage A is HIGH and stage B is LOW, current would flow through the motor from + to - and the motor would exert a torque $\vec \tau$.

If stage A is LOW and stage B is HIGH, current would flow through the motor from - to + and the motor would exert a torque $-\vec \tau$.

So let’s try it. Looking at the bottom of the pinout diagram, we can see which GPIO correspond to each motor port.

Solder some wires onto your motor and plug them into a motor port. Also, place a jumper on the enable port for the motor channel you are using.

Let’s change our blinky code to configure two more output pins:

const unsigned int LED{17};
// add these
const unsigned int MTR_HI{?};
const unsigned int MTR_LO{?};

void setup() {
    pinMode(LED, OUTPUT);
    // and these
    pinMode(MTR_HI, OUTPUT);
    pinMode(MTR_LO, OUTPUT);

    // configure pins to spin the motor in a direction
    digitalWrite(MTR_HI, HIGH);
    digitalWrite(MTR_LO, LOW);
}

Run this, and watch the motor spin!

You can reverse the direction by inverting the levels of these pins. Try it!

Greater Granularity

You don’t always want to exert maximum torque in either direction, but rather some proportion of the maximum torque.

To achieve this, we can use Pulse Width Modulation (PWM).

Rather than holding the output stages steady at HIGH or LOW, we can rapidly change the state, targeting an on proportion.

Imagine we hold stage B LOW, and over intervals of 1us, pull stage A HIGH for 200ns and LOW for the remaining 800ns. On average, it would look as though the voltage on the switch node of stage A were $V_s \cdot \frac{200ns}{1us}=0.2V_s$, which roughly corresponds to 1/5th the maximum torque.

Arduino let’s us do this with the analogWrite function.

analogWrite accepts values in the range 0..=255 (unsigned 8bit integer).

The following is the equivalent of our previous test but with analogWrite:

analogWrite(MTR_HI, 255);
analogWrite(MTR_LO, 0);

Run this and watch the motor spin!

Swap these numbers and watch it spin the other way!

Challenge

Make the motor smoothly oscillate back and forth between spinning forward and backward.