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.
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 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.
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]); }
3.147.205.30