Appendix B. Using Other Hardware with Your Robot

You may want to add more capability to your robot or perhaps substitute different hardware than the items covered in the text. This chapter describes how to use some common alternative components.

Alternative Motor Controllers

Ardumoto

This popular H-bridge can be used instead of the Adafruit shield described in the text if you have a two wheeled robot (the shield only supports two motors). It also lacks the convenient layout for the analog sensors and you will need to add two 3 pin headers for the servo and distance sensor connections. The Motor code for Ardumoto is shown in Example B-1.

Continuous Rotation Servos

Continuous rotation servos are hobby servos modified to rotate continuously with a speed and rotation direction controlled by the Servo library that comes with Arduino. The servo rotates in one direction as the angle written to the servo is increased from 90 degrees; it rotates in the other direction when the angle is decreased from 90 degrees. The actual direction forward or backward depends on how you have the servos attached. Continuous rotation servos may not stop rotating when writing exactly 90 degrees. Some servos have a small potentiometer you can trim to adjust for this, or you can add or subtract a few degrees to the motorStopAngle element to stop the servo. This version uses digital pins 7 and 8 but you can change this by altering the elements of the servoPins array (the first element for all the arrays is the left servo, the second is the right servo). See Example B-2.

These functions convert requests to set the motor speed into servo angles that are written to the continuous rotation servos. The conversion is performed using the Arduino map function.

Note

This code uses the Servo library. If you want to build the infrared remote control project with continuous rotation servos, you will need to ensure that the IRremote library is configured to use a timer other than Timer 1) because the Servo library requires Timer 1. See Modifying a Library to Change Timer Allocation for timer usage and details on how to configure timers for the IRremote library.

Example B-1. RobotMotor library code for the Ardumoto shield

/*******************************************************
    RobotMotor.cpp // Ardumoto version
    low level motor driver for use with ardumoto motor shield and 2WD robot

    Michael Margolis May 8 2012
********************************************************/

#include <Arduino.h>  
#include "RobotMotor.h"

const int differential = 0; // % faster left motor turns compared to right 

/****** motor pin defines *************/
// Pins connected to the motor driver. The PWM pins control the speed, and the
//  other pins are select forward and reverse

// Motor uses pins : 3,11,12,13
const byte M_PWM_PIN[2]  = {11,3};  // ardumoto v13
const byte M_DIR_PIN[2]  = {13,12};
/* end of motor pin defines */

int  motorSpeed[2]  = {0,0}; // motor speed stored here (0-100%)

// tables hold time in ms to rotate robot 360 degrees at various speeds 
// this enables conversion of rotation angle into timed motor movement 
// The speeds are percent of max speed
// Note: low cost motors do not have enough torque at low speeds so
// the robot will not move below this value 
// Interpolation is used to get a time for any speed from MIN_SPEED to 100%

const int MIN_SPEED = 40; // first table entry is 40% speed
const int SPEED_TABLE_INTERVAL = 10; // each table entry is 10% faster speed
const int NBR_SPEEDS =  1 + (100 - MIN_SPEED)/ SPEED_TABLE_INTERVAL;
 
int speedTable[NBR_SPEEDS]  =  {40,     50,   60,   70,   80,   90,  100}; // speeds  
int rotationTime[NBR_SPEEDS] = {5500, 3300, 2400, 2000, 1750, 1550, 1150}; // time 

void motorBegin(int motor)
{
  pinMode(M_DIR_PIN[motor], OUTPUT);
  motorStop(motor);
}

// speed range is 0 to 100
void motorSetSpeed(int motor, int speed)
{
   motorSpeed[motor] = speed;           // save the value
   speed = map(speed, 0,100, 0,255);    // scale to PWM range
   analogWrite(M_PWM_PIN[motor], speed);  // write the value   
}

void motorForward(int motor, int speed)
{
  digitalWrite(M_DIR_PIN[motor], HIGH);
  motorSetSpeed(motor, speed); 
}

void motorReverse(int motor, int speed)
{
  digitalWrite(M_DIR_PIN[motor], LOW);
  motorSetSpeed(motor, speed);  
}

void motorStop(int motor)
{
  analogWrite(M_PWM_PIN[motor], 0);
}

void motorBrake(int motor)
{
  // Ardumoto does not support brake, so just stop the motor
  analogWrite(M_PWM_PIN[motor], 0);
}

Example B-2. RobotMotor library header for continuous rotation servos

/*******************************************************
    RobotMotor.cpp // continuous rotation servo version
	
    low level motor driver for use with continuous rotation servos and 2WD robot

    Copyright Michael Margolis May 8 2012
********************************************************/

#include <Arduino.h>  
#include <Servo.h>
#include "RobotMotor.h"

Servo myservo[2];               // create instances for two servos

const int MAX_ANGLE    = 60;    // number of degrees that motor driven at max speed
const int servoPins[2] = {7,8}; // digital pins connected to servos:(left,right)

                              // change sign to reverse direction of the motor 
int motorSense[2] = {1,-1};     // 1 increases angle for forward, -1 decreaes 

int motorStopAngle[2] = {90,90}; // inc or dec so motor stops when motorStop is called 

int motorSpeed[2] = {0,0};      // left and right motor speeds stored here (0-100%)

// tables hold time in ms to rotate robot 360 degrees at various speeds 
// this enables conversion of rotation angle into timed motor movement 
// The speeds are percent of max speed
// Note: low cost motors do not have enough torque at low speeds so
// the robot will not move below this value 
// Interpolation is used to get a time for any speed from MIN_SPEED to 100%

const int MIN_SPEED = 40; // first table entry is 40% speed
const int SPEED_TABLE_INTERVAL = 10; // each table entry is 10% faster speed
const int NBR_SPEEDS =  1 + (100 - MIN_SPEED)/ SPEED_TABLE_INTERVAL;
 
int speedTable[NBR_SPEEDS]  =  {40,     50,   60,   70,   80,   90,  100}; // speeds  
int rotationTime[NBR_SPEEDS] = {5500, 3300, 2400, 2000, 1750, 1550, 1150}; // time 

void motorBegin(int motor)
{
   myservo[motor].attach(servoPins[motor]);
}

// speed range is 0 to 100
void motorSetSpeed(int motor, int speed)
{
   motorSpeed[motor] = speed;           // save the value
}

void motorForward(int motor, int speed)
{
  motorSetSpeed(motor, speed); 
  int stopAngle = motorStopAngle[motor];
  int maxSpeedAngle =  stopAngle + (MAX_ANGLE *  motorSense[motor]); 
  int angle = map(speed, 0,100, stopAngle, maxSpeedAngle);   
  myservo[motor].write(angle);
}

void motorReverse(int motor, int speed)
{
  motorSetSpeed(motor, speed); 
  int stopAngle = motorStopAngle[motor];
  int maxSpeedAngle =  stopAngle - (MAX_ANGLE *  motorSense[motor]); 
  int angle = map(speed, 0,100, stopAngle, maxSpeedAngle);   
  myservo[motor].write(angle);  
}

void motorStop(int motor)
{
  myservo[motor].write(motorStopAngle[motor]);
}

void motorBrake(int motor)
{
  myservo[motor].write(motorStopAngle[motor]);
} 
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.205.30