I am using Pololu Micro Serial Servo Controller and a Pololu Low-Voltage Dual Serial Motor Controller with a Arduino Diecimilla board. I have used Pin 1 (TX) to connect to Pin 4 on the Motor controller. How should the “logic-level serial input” on the Servo Controller be connected to the Arduino? I have included my code to clarify my project.
I understand from the guide that: “This motor controller interface protocol is compatiable with other Pololu serial devices such as our servo controllers.” but need help on how to use both controllers.
/*
Sample code for RobotShop Rover v1.0
www.RobotShop.com
This code uses subroutines to explore all aspects of the RobotShop Rover, including the
motors, motor controller, IR Sensor and Pan/Tilt. The Rover will proceed in a straight
line and once it encounters an obstacle will stop, flash the LED, move the pan and tilt to a
new location, reverse, rotate ~90 degrees, re-center the pan and tilt and proceed until the
next obstacle. We encourage you to experiment with and improve the code.
Note 1: The kit does not include a servo controller; however, the pan and tilt can be
controlled directly from the Arduino. A servo needs to be refreshed at least once every
500ms, though when working directly off the Arduino, it is difficult to refresh the servo
especially if the delay() function is used. The system works best when using 1.2V
rechargeable batteries (instead of 1.5V alkaline) as the servos retain their last position due
to friction. For proper control of the pan and tilt, consider the RB-Pol-18 “Pololu Micro
Serial 8 Servo Controller”.
Note 2: The motor controller manual specifies that the controller should be OFF when
uploading code to the microcontroller. Use one of the included ON/OFF switches to
ensure the controller is OFF when uploading code (or physically disconnect the Tx/Rx
wires to the controller). You only need to do this when uploading new code.
Note 3: As with any electro-mechanical system, the ideal choice is to use high capacity
rechargeable batteries. The rover should last for roughly 30minutes depending on many
factors (terrain, incline, speed of motors). The 9V battery ONLY powers the Arduino
microcontroller. If the system is behaving erratically, check the battery power; a
minimum of 9V is required by the Arduino.
Note 4: Triple check that all wires are properly connected before loading the code. Test
each system individually by commenting the code using two backslashes.
*/
#define MIN_POS 500 // the minuimum pulse width for your servos
#define MAX_POS 5500 // maximum pulse width for your servos
// set servo speed, goes from 1 to 127
int servoSpeed = 120; // 1 = fastest 127 = slowest
//int servopulse1 = 1250; //test servo tilt position (0 to 180)
//int servopulse2 = 1550; //test servo pan position (0 to 180)
//int servopin1 = 9; //analog pin 1=15
//int servopin2 = 10; //analog pin 3=17
int motor_reset = 2; //digital pin 2 assigned to motor reset
int irpin = 3;
int distance = 0;
int period;
int timeUp = 680; // 1000000/(2 * frequency)
//int ledpin = 13;
int speakerOut = 9;
struct t_mtab { char c, pat; } ;
struct t_mtab morsetab[] = {
{'.', 106},
{',', 115},
{'?', 76},
{'/', 41},
{'A', 6},
{'B', 17},
{'C', 21},
{'D', 9},
{'E', 2},
{'F', 20},
{'G', 11},
{'H', 16},
{'I', 4},
{'J', 30},
{'K', 13},
{'L', 18},
{'M', 7},
{'N', 5},
{'O', 15},
{'P', 22},
{'Q', 27},
{'R', 10},
{'S', 8},
{'T', 3},
{'U', 12},
{'V', 24},
{'W', 14},
{'X', 25},
{'Y', 29},
{'Z', 19},
{'1', 62},
{'2', 60},
{'3', 56},
{'4', 48},
{'5', 32},
{'6', 33},
{'7', 35},
{'8', 39},
{'9', 47},
{'0', 63}
} ;
#define N_MORSE (sizeof(morsetab)/sizeof(morsetab[0]))
#define SPEED (5)
#define DOTLEN (1200/SPEED)
#define DASHLEN (3*(1200/SPEED))
void
dash()
{
digitalWrite(speakerOut, LOW);
period = DASHLEN;
while (period > 0)
{
digitalWrite(speakerOut, HIGH);
delayMicroseconds(timeUp);
digitalWrite(speakerOut, LOW);
delayMicroseconds(timeUp);
--period;
}
digitalWrite(speakerOut, LOW);
delay(DOTLEN);
//digitalWrite(LEDpin, HIGH) ;
//delay(DASHLEN);
//digitalWrite(LEDpin, LOW) ;
//delay(DOTLEN) ;
}
void
dit()
{
digitalWrite(speakerOut, LOW);
period = DOTLEN;
while (period > 0)
{
digitalWrite(speakerOut, HIGH);
delayMicroseconds(timeUp);
digitalWrite(speakerOut, LOW);
delayMicroseconds(timeUp);
--period;
}
digitalWrite(speakerOut, LOW);
delay(DOTLEN);
//digitalWrite(LEDpin, HIGH) ;
//delay(DOTLEN);
//digitalWrite(LEDpin, LOW) ;
//delay(DOTLEN);
}
void
send(char c)
{
int i ;
if (c == ' ') {
Serial.print(c) ;
delay(7*DOTLEN) ;
return ;
}
for (i=0; i<N_MORSE; i++) {
if (morsetab[i].c == c) {
unsigned char p = morsetab[i].pat ;
Serial.print(morsetab[i].c) ;
while (p != 1) {
if (p & 1)
dash() ;
else
dit() ;
p = p / 2 ;
}
delay(2*DOTLEN) ;
return ;
}
}
/* if we drop off the end, then we send a space */
Serial.print("?") ;
}
void
sendmsg(char *str)
{
while (*str)
send(*str++) ;
Serial.println("");
}
void setup()
{
pinMode(motor_reset, OUTPUT);
pinMode(speakerOut, OUTPUT);
//pinMode(servopin1, OUTPUT);
//pinMode(servopin2, OUTPUT);
Serial.begin(9600);
digitalWrite(motor_reset, LOW);
delay(50);
digitalWrite(motor_reset, HIGH);
delay(50);
// reset motor controller
// set servo pin and speed
if (servoSpeed >= 1 && servoSpeed <= 127)
{
servoSetSpeed(0, servoSpeed);
servoSetSpeed(1, servoSpeed);
}
}
void loop()
{
//servoposition();
//delay(20);
//digitalWrite(servopin1, LOW);
//digitalWrite(servopin2, LOW);
put(0, 3000);
delay(25);
put(1, 3000);
delay(25);
motorforward();
irdetection();
}
/*subroutine servoposition
void servoposition()
{
for(int i=1; i<=20; i++) // Ensures the servos reach their final position
{
digitalWrite(servopin1, HIGH); // Turn the L motor on
delayMicroseconds(servopulse1); // Length of the pulse sets the motor position
digitalWrite(servopin1, LOW); // Turn the L motor off
delay(20);
digitalWrite(servopin2, HIGH); // Turn the L motor on
delayMicroseconds(servopulse2); // Length of the pulse sets the motor position
digitalWrite(servopin2, LOW); // Turn the L motor off
delay(20);
}
}
*/
void irdetection()
{
distance=analogRead(irpin); // Interface with the Sharp IR Sensor
if (distance<=575&&distance>=425) // Detecting objects within roughly 10cm
{
motorstop(); // stop the rover
//ledwarning(); // light up the LED for 1 second
sendmsg("ZL1XXX QRZ") ;
delay(3000);
//servopulse1=1250; // move the pan/tilt
//servopulse2=2000;
//servoposition(); // refresh the servos
put(0, 1250);
delay(25);
//put(1, 2000);
delay(500);
motorreverse(); // reverse the motors for 1 second
delay(1000);
motorstop(); // stop the motors
delay(1000); // wait 1 second
rotateccw(); // rotate for 2 seconds
delay(2000);
motorstop(); // stop the motors
delay(1000);
//servopulse1=550; // move the servos
//servopulse2=1500;
//servoposition();
put(0, 550);
delay(25);
put(1, 1500);
delay(1000);
}
}
//void ledwarning()
//{
//digitalWrite(ledpin, HIGH); // sets the LED on
//delay(1000);
//digitalWrite(ledpin, LOW); // sets the LED off
//}
//subroutine motor forward
void motorforward()
{
//left motor
unsigned char buff1[6];
buff1[0]=0x80; //start byte - do not change
buff1[1]=0x00; //Device type byte
buff1[2]=0x01; //Motor number and direction byte; motor one =00,01
buff1[3]=0x45; //Motor speed "0 to 128" (ex 100 is 64 in hex)
for(int i=0; i<4; i++) {Serial.print(buff1[i], BYTE);}
//right motor
unsigned char buff2[6];
buff2[0]=0x80; //start byte - do not change
buff2[1]=0x00; //Device type byte
buff2[2]=0x03; //Motor number and direction byte; motor two=02,03
buff2[3]=0x45; //Motor speed "0 to 128" (ex 100 is 64 in hex)
for(int i=0; i<4; i++) {Serial.print(buff2[i], BYTE);}
}
//subroutine reverse at half speedd
void motorreverse()
{
//left motor
unsigned char buff3[6];
buff3[0]=0x80; //start byte - do not change
buff3[1]=0x00; //Device type byte
buff3[2]=0x00; //Motor number and direction byte; motor one =00,01
buff3[3]=0x35; //Motor speed "0 to 128" (ex 100 is 64 in hex)
for(int i=0; i<4; i++) {Serial.print(buff3[i], BYTE);}
//right motor
unsigned char buff4[6];
buff4[0]=0x80; //start byte - do not change
buff4[1]=0x00; //Device type byte
buff4[2]=0x02; //Motor number and direction byte; motor two=02,03
buff4[3]=0x35; //Motor speed "0 to 128" (ex 100 is 64 in hex)
for(int i=0; i<4; i++) {Serial.print(buff4[i], BYTE);}
}
//Motor all stop
void motorstop()
{
//left motor
unsigned char buff3[6];
buff3[0]=0x80; //start byte - do not change
buff3[1]=0x00; //Device type byte
buff3[2]=0x00; //Motor number and direction byte; motor one =00,01
buff3[3]=0x00; //Motor speed "0 to 128" (ex 100 is 64 in hex)
for(int i=0; i<4; i++) {Serial.print(buff3[i], BYTE);}
//right motor
unsigned char buff4[6];
buff4[0]=0x80; //start byte - do not change
buff4[1]=0x00; //Device type byte
buff4[2]=0x02; //Motor number and direction byte; motor two=02,03
buff4[3]=0x00; //Motor speed "0 to 128" (ex 100 is 64 in hex)
for(int i=0; i<4; i++) {Serial.print(buff4[i], BYTE);}
}
void rotateccw()
{
//left motor
unsigned char buff1[6];
buff1[0]=0x80; //start byte - do not change
buff1[1]=0x00; //Device type byte
buff1[2]=0x01; //Motor number and direction byte; motor one =00,01
buff1[3]=0x40; //Motor speed "0 to 128" (ex 100 is 64 in hex)
for(int i=0; i<4; i++) {Serial.print(buff1[i], BYTE);}
//right motor
unsigned char buff2[6];
buff2[0]=0x80; //start byte - do not change
buff2[1]=0x00; //Device type byte
buff2[2]=0x02; //Motor number and direction byte; motor two=02,03
buff2[3]=0x40; //Motor speed "0 to 128" (ex 100 is 64 in hex)
for(int i=0; i<4; i++) {Serial.print(buff2[i], BYTE);}
}
void put(int servo, int angle)
{
//servo is the servo number (typically 0-7)
//angle is the absolute position from 500 to 5500
unsigned char buff[6];
unsigned int temp;
unsigned char pos_hi,pos_low;
//Convert the angle data into two 7-bit bytes
temp=angle&0x1f80;
pos_hi=temp>>7;
pos_low=angle & 0x7f;
//Construct a Pololu Protocol command sentence
buff[0]=0x80; //start byte: always 0x80
buff[1]=0x01; //device id: always 0x01 for an pololu 8 servo controller
buff[2]=0x04; //command number: 0x04 to set absolute values
buff[3]=servo; //servo number: 0 to 7
buff[4]=pos_hi; //data1
buff[5]=pos_low; //data2
//Send the command to the servo controller
for(int i=0;i<6;i++){
Serial.print(buff[i],BYTE);
}
}
void servoSetSpeed(int servo, int speed){
//servo is the servo number (typically 0-7)
//speed is servo speed (1=fastest, 127=slowest)
//set speed to zero to turn off speed limiting
unsigned char buff[5];
unsigned char speedcmd;
speedcmd=speed&0x7f;//take only lower 7 bits of speed
buff[0]=0x80;//start byte
buff[1]=0x01;//device id
buff[2]=0x01;//command number
buff[3]=servo;//servo number
buff[4]=speed;//data1
for(int i=0;i<5;i++){
Serial.print(buff[i],BYTE);
}
}