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:
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 |
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")
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);
}
}
In [4]:
init_ardumoto()
Out[4]:
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)
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)
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)