| CMUCam with the Handyboard Last Modified: 2006-11-13 | | |
| Acroname Robotics | |||
| Introduction The code demonstrates an interface between the CMUcam kit and the Handyboard kit. This code enables a 2-wheel drive robot to track a colored-object. To use this example code, start Interactive C (IC) 4.0 and open the "cmuHBtest.lis" file. Then click "download" to load all the code into the Handyboard. Loading the ".ic" file by itself will not work. See the CMUcam documentation for more information about its serial connections. The CMUcam must be set to 9600 baud. A special cable is needed to plug into the Handyboard's RJ11 jack. You will need to refer to the schematic for pinouts. This information may be found on the Handyboard website. The robot that uses this code has both a neck and body. The camera is mounted on a "neck" servo. The CMUcam's own servo output is used to drive this neck servo. The neck pans the camera while it is tracking an object. When the tracked object makes small side-to-side motions, only the neck servo moves. When the object moves too far to one side, the body of the robot rotates to re-align the camera with the object and the neck continues to track while the body moves. If the object is too close to the camera the robot will back up. If the object gets too far away the robot will go forward. (On the robot used with this example, the servo tended to jerk a little during the camera configuration process. It was steadied by hand until the tracking color was initialized.) Since the camera board has its own regulator, it should be powered from a separate power supply. The servo power output on the camera board is NOT regulated so the separate power supply should not be more than 6 volts. Higher voltages may damage a servo. Source Code - Batch File The following is a batch file used for loading the assembly code for serial communication and the Interactive C routines onto the Handyboard. myserial.icb
cmuHBtest.ic
Source Code - Interactive C Main File /****************/
/* cmuHBtest.ic */
/****************/
/* These are the specifics for this particular robot. */
/* Motor port 0 controls the left motor, polarity is normal, green LED indicates Forward */
/* Motor port 1 controls the right motor, polarity is normal, green LED indicates Forward */
/* Analog port 5 has been modified for the Sharp GP2D12 IR Ranging sensor. Conversions are: */
/* | Distance | White Object | Black Object | */
/*_|__________|______________|______________|_*/
/* | 3" | 137 | 140 | */
/* | 3.5" | 127 | 131 | */
/* | 4" | 117 | 122 | */
/* | 4.5" | 106 | 112 | */
/* | 5" | 97 | 104 | */
/* | 5.5" | 90 | 96 | */
/* | 6" | 84 | 89 | */
/* | 6.5" | 80 | 85 | */
/* | 7" | 75 | 82 | */
/* | 7.5" | 70 | 78 | */
/* | 8" | 66 | 74 | */
/* | 8.5" | 64 | 70 | */
/* | 9" | 61 | 67 | */
/* | 9.5" | 58 | 65 | */
/* | 10" | 56 | 61 | */
/* | 15" | 39 | ?? | */
/* | 20" | 31 | 34 | */
/* | 30+" | 24 | 2 | */
/* CMUcam */
int l=0; /* Define left motor port */
int r=1; /* Define right motor port */
/* These may need to be adjusted to get your bot to go in a straight line **/
int lm=25; /* Left motor forward speed */
int rm=25; /* Right motor forward speed */
int lbump=13; /* Define bumper ports */
int rbump=11; /* The bump sensors are plugged into the HB's digital in's 13 & 11 */
char buff[11];
/*******************************************************************/
/* Main Command code */
/*******************************************************************/
void main()
{
printf("Press Start to Go!\\n");
while(!start_button()){}
tone(800.0,0.5);
serial_init(0);
sr_init_CMUcam();
while(1){
track();
printf("Pos=%d, Nod=%d Sz=%d, Cnf=%d\\n",buff[1],buff[3],buff[8],buff[9]);
/* buff[0]=77 always, buff[1]=Servo Pos, buff[2]=Mx, buff[3]=My */
/* buff[4] to buff[6]=X/Y box co-ords, */
/* buff[8]=size/distance of object, buff[9]=Confidence. */
/* (45 is center of scan and is servo center.) */
if(buff[9] < 49){
ao();
}
if(buff[1] > 66 < 94 && buff[8] > 121 < 253 && buff[9] > 50){
ao();
}
if(buff[8] < 120 && buff[9] > 50){
Bwd();
}
if(buff[8] > 253 && buff[9] >50){
Fwd();
}
if(buff[1] > 95 && buff[9] > 50){
Right();
}
if(buff[1] < 65 && buff[9] > 50){
Left();
}
}
}
/*************************/
/* Initialize CMU Camera */
/*************************/
void sr_init_CMUcam()
{
serial_string("RS\r");
serial_wait(0x3a);
printf("Camera Reset\\n");
sleep(0.1);
serial_string("CR\r");
serial_wait(0x3a);
serial_string("PM 0\r");
serial_wait(0x3a);
/* serial_string("S1 60\r");
serial_wait(0x3a);
sr_blink();
sleep(0.1); */
serial_string("MM 14\r");
serial_wait(0x3a);
printf("Middle Mass On\\n");
sleep(0.5);
serial_string("CR 18 44 19 32\r");
serial_wait(0x3a);
sleep(3.0);
printf("Auto White and Gain are Set\\n");
sleep(0.5);
printf("Grab Color...\\n");
serial_string("TW\r"); /* Acquire... */
sleep(1.0);
serial_string("\r");
serial_wait(0x3a);
printf("Color Locked In!\\n");
serial_string("PM 1\r");
serial_wait(0x3a);
serial_string("L1 2\r");
serial_wait(0x3a);
sleep(2.0);
serial_string("RM 3\r");
serial_wait(0x3a);
sleep(2.0);
}
/****************/
/***********************************************************/
/* Receive characters until desired character is received. */
/***********************************************************/
void serial_wait(int c){
int d=0;
while(d != c){
d = serial_getchar(0);
}
}
/*******************************************************/
/* Send string of ASCII characters to serial port. */
/* String MUST be terminated with carriage return (/r) */
/*******************************************************/
void serial_string(char c[])
{
int x,y=0;
while(y != 0x0d){
y = c[x++];
serial_putchar(y);
}
}
/***************************************************/
/* Track Color Command */
/***************************************************/
void track()
{
int x;
serial_string("TC\r");
serial_wait(0xff);
for(x=0;x<11;x++){
buff[x]=serial_getchar(0);
}
}
/***************************************************/
/* Motor Drive commands */
/***************************************************/
void Left(){
motor(l,-15);
motor(r,15);
}
void Right(){
motor(l,15);
motor(r,-15);
}
void Bwd(){
motor(l,25);
motor(r,25);
}
void Fwd(){
motor(l,-25);
motor(r,-25);
}
/**************************************/
/* Start Routine */
/**************************************/
void init(){
printf("Press Start to Go!\\n"); /* wait for start button to get */
while(!start_button()){} /* then run program. */
tone(800.,1.);
}
Source Code - Assembly Code for Serial Communication The following code is used to create a compiled "icb" file that can be loaded onto the Handyboard. See the Handyboard documentation for the necessary steps to create a compiled icb file. org MAIN_START
#include "6811regs.asm"
* Masks for serial port
PORTD_WOM EQU $20
BAUD9600 EQU $B0
TRENA EQU $0C ; Transmit, Receive ENAble
RDRF EQU $20 ; Receive Data Register Full
TDRE EQU $80 ; Transmit Data Register Empty
* initializes the serial port for transmission
* and reception of 9600 baud serial data:
subroutine_serial_init:
ldx #$1000
bclr SPCR,x #PORTD_WOM * turn off wired-or mode
ldaa #BAUD9600 * mask for 9600 baud speed
staa BAUD,x * stored into BAUD register
ldaa #TRENA * mask for Transmit, Rec. enable
staa SCCR2,x * store in control register
ldy #$1000 * send first character so next
ldaa #$40 * one won't get lost
staa SCDR,y
blah brclr SCSR,y TDRE blah
rts
* transmits a character and waits for it to finish transmission:
subroutine_serial_putchar:
ldy #$1000
tba * transfer character into A
staa SCDR,y * store A reg in SCDR
WCLoop brclr SCSR,y TDRE WCLoop * wait until data sent
rts
* The following code receives a character from the serial port:
subroutine_serial_getchar:
ldx #$1000
RCLoop brclr SCSR,x RDRF RCLoop * wait until char ready
ldaa SCDR,x * input character to A
tab * transfer A to B
clra * zero A to make D an int again
rts
Comments Thanks go to Dan Gates and Glen Hathaway for contributing the source code and notes for this example. Revision History:
| ||
| voice: 720-564-0373, email: sales@acroname.com, address: 4822 Sterling Dr., Boulder CO, 80301-2350, privacy © Copyright 1994-2012 Acroname, Inc., Boulder, Colorado. All rights reserved. |