Ardumoto Example

This example shows how to use the Ardumoto on the board. Ardumoto supports two DC motor driving.

There are also instructions on how to hook up the shield.

Motor A and Motor B are connected as below to the arduino pins:

  • Default connections
Pin number Functionality
2 Direction control for motor A
3 PWM control (speed) for motor A
4 Direction control for motor B
11 PWM control (speed) for motor B
  • Alternate Connections
Pin number Functionality
8 Direction control for motor A
9 PWM control (speed) for motor A
7 Direction control for motor B
10 PWM control (speed) for motor B

In this notebook, we will assume the first (default) pin configuration.

There are multiple ways to hook up the motor to the shield, as shown below:

In this notebook, we will assume the second way in the above picture.


In [1]:
from pynq.overlays.base import BaseOverlay

base = BaseOverlay("base.bit")


1. Use Microblaze to control the Ardumoto shield

First let's define a few constants.


In [2]:
MOTOR_A = 0
MOTOR_B = 1
POLAR_DEFAULT = 0
POLAR_REVERSE = 1
FORWARD = 0
BACKWARD = 1

Now we can use Microblaze program to control the shield.


In [3]:
%%microblaze base.ARDUINO

#include "xio_switch.h"
#include "gpio.h"
#include "timer.h"

#define DEFAULT_PERIOD 625998
#define DEFAULT_DUTY 312998

#define PWM_A_PIN 3
#define PWM_B_PIN 11
#define DIR_A_PIN 2
#define DIR_B_PIN 4

typedef enum motor {
MOTOR_A = 0,
MOTOR_B = 1,
}motor_e;

static unsigned int pol_a = 0, pol_b = 0;
static unsigned int dir_a = 0, dir_b = 0;
static unsigned int duty_a = 50, duty_b = 50;

static timer timer_a;
static timer timer_b;
static gpio gpio_a;
static gpio gpio_b;

unsigned int init_ardumoto(){    
    timer_a = timer_open_device(0);
    timer_b = timer_open_device(5);
    set_pin(PWM_A_PIN, PWM0);
    set_pin(PWM_B_PIN, PWM5);
    gpio_a = gpio_open(DIR_A_PIN);
    gpio_b = gpio_open(DIR_B_PIN);
    gpio_set_direction(gpio_a, GPIO_OUT);
    gpio_set_direction(gpio_b, GPIO_OUT);
    return 0;
}

void configure_polar(unsigned int motor, unsigned int polarity){
    if (motor == MOTOR_A) {
        pol_a = polarity;
    }else if (motor == MOTOR_B) {
        pol_b = polarity;
    }
}

void set_direction(unsigned int motor, unsigned int direction){
    if (motor == MOTOR_A){
        dir_a = (direction)? pol_a : !pol_a;
    }
    else if (motor == MOTOR_B){
        dir_b = (direction)? pol_b : !pol_b;
    }
}

void set_speed(unsigned int motor, unsigned int speed){
    if (motor == MOTOR_A) {
        duty_a = speed;
    } else if (motor == MOTOR_B) {
        duty_b = speed;
    }
}

void run(unsigned int motor){
    if (motor == MOTOR_A) {
        gpio_write(gpio_a, dir_a);
        timer_pwm_generate(timer_a, DEFAULT_PERIOD, 
                           duty_a*DEFAULT_PERIOD/100);
    }else if(motor == MOTOR_B) {
        gpio_write(gpio_b, dir_b);
        timer_pwm_generate(timer_b, DEFAULT_PERIOD, 
                           duty_b*DEFAULT_PERIOD/100);
    }
}

void stop(unsigned int motor){
    if (motor == MOTOR_A) {
        timer_pwm_stop(timer_a);
    }else if (motor == MOTOR_B){
        timer_pwm_stop(timer_b);
    }
}

2. Set pin and polarity configurations

We have to first initialize the device.


In [4]:
init_ardumoto()


Out[4]:
0

We can then set motor A and B to have the same polarity.


In [5]:
configure_polar(MOTOR_A, POLAR_DEFAULT) 
configure_polar(MOTOR_B, POLAR_DEFAULT)

3. Set direction and speed for each motor


In [6]:
set_direction(MOTOR_A, FORWARD)
set_direction(MOTOR_B, FORWARD)

Now let us set motor A speed to be 10% of the maximum speed.


In [7]:
set_speed(MOTOR_A, 10)

Set speed for motor B to be the maximum.


In [8]:
set_speed(MOTOR_B, 99)

Run each individual motor for a few seconds.


In [9]:
from time import sleep

run(MOTOR_A)
sleep(3)
stop(MOTOR_A)
sleep(1)
run(MOTOR_B)
sleep(3)
stop(MOTOR_B)

4. Run both motors together

The following cell will run both motors in the same direction, but with different speeds.


In [10]:
run(MOTOR_A)
run(MOTOR_B)
sleep(2)
stop(MOTOR_A)
stop(MOTOR_B)

Again, the rotation of the motor depends on the wiring to the shield. In our setup, the following cell will result in two motors rotating in opposite directions.


In [11]:
set_direction(MOTOR_A, FORWARD)
set_speed(MOTOR_A, 50)

set_direction(MOTOR_B, BACKWARD)
set_speed(MOTOR_B, 50)

run(MOTOR_A)
run(MOTOR_B)
sleep(3)
stop(MOTOR_A)
stop(MOTOR_B)