Example Source Code:
Interactive C for Sumo11
Description
This example is simply an update to the standard test program that comes with the SORC Sumo11 board. It uses the standard encoder.ic code that comes with Interactive C to interface to the WheelWatchers -- which is good news as you can reuse any code that depends on that file, like the various HandyBoard examples and RugWarrior examples.
Encoder.ic relies on the ChA and ChB signals only, which limits you to 32 counts per wheel rotation. However, the test itself will display all the WW-01 signals if hooked up.
Download
ww01_ic_s11tests.ic - Interactive C source
Source Code
ww01_ic_s11tests.ic
/*************************** S11tests.ic ********************************/
/*
Test program for the Sumo11 board
Version 1.4t 8/04
Modified by Pete Skeggs to add WheelWatcher encoder board tests.
I changed TESTNUM to 8; added "Menu: WW-01" to the array 'a',
added a call to testww01(); added count_digits() and print_spaces()
to help with screen formatting; and finally added testww01() itself.
This uses the encoders.ic file that comes with Interactive C. It
works great with the WheelWatcher in quadrature mode.
Wiring: Right ChA = digital 13, ChB = digital 8, DIR = digital 14
Left ChA = digital 7, ChB = digital 12, DIR = digital 10
Also, Right CLK = digital 15 and Left CLK = digital 11.
Version 1.4s 5/03
Modified by Dan Gates to test the functions of the sumo11 board.
Removed the srf04 sonar test, modified the motor test, sevo tests
and added the CMUcam blink test.
version 1.4 1/02
Changed by Randy Sargent for IC 4.0 and to include srf04 sonar test.
version 1.3 1/01
Changed by Anne Wright for Botball to allow selecting which test
using the knob. Program previously called hb-expbd-test.c. Also
includes hbmenu.c.
version 1.2 11/00
tests IR emitter -dpm
version 1.1 7/98
Expanded by Dave Miller 7/13/98 dmiller@kipr.org
to include servo and to handle menuing.
version 1.0 -- 26 nov 95
Fred G. Martin (fredm@media.mit.edu)
*/
#define TESTNUM 8
#use "serial.icb"
char buff[11];
void main()
{
char a[TESTNUM][16]={"Menu: Motors","Menu: Servo","Menu: Digitals",
"Menu: Analogs", "Menu: Knob", "Menu: IR", "Menu: CMUcam", "Menu: WW-01"};
printf("Sumo11 tests Press START\n");
while(!start_button());
printf("Turn knob to select test\n");
sleep(1.0);
while(1) {
int sel;
printf("Turn knob to select test\n");
sleep(1.0);
sel = select_string(a,TESTNUM);
if(sel==0) testmotors();
else if(sel==1) testservo();
else if(sel==2) testdigitals();
else if(sel==3) testanalogs();
else if(sel==4) testknob();
else if(sel==5) testir();
else if(sel==6) testcmu();
else if(sel==7) testww01();
else if (sel==8) break;
}
printf("Done\n");
}
void
testmotors(void)
{
printf("Motor test, Hold STOP to end \n");
while (!stop_button()) {
int i;
for (i= 0; (!stop_button() && (i< 2)); i++) {
fd(i); msleep(250L);
bk(i); msleep(250L);
off(i);
}
}
beep();
}
void
testservo(void)
{
int i;
printf("Attach Servos Press START\n");
while(!start_button());
init_servos(1);
while(!stop_button())
for (i=990;(!stop_button() && i<4150);i=i+50) {
printf("Hold STOP to end Servo=%d\n",i);
servo0=servo1=servo2=servo3=i;
msleep(50L);
}
init_servos(0);
beep();
}
void
testdigitals(void)
{
printf("Digital inputs STOP to end\n");
sleep(1.0);
printf("Turn knob to select port\n");
sleep(1.0);
while (!stop_button()) {
/* Get the value of the knob. The digital port numbering is 7-15 */
int val = knob_int_value(6, 15);
if(val == 6) { /* show all */
int i;
printf("Ports 15 ... 7 ");
for (i=15; i>6; i--)
if (digital(i)) printf("1");
else printf("0");
printf("\n");
}
else {
printf("Port %d: %d\n", val, digital(val));
}
msleep(100L);
}
beep();
}
void
testknob(void)
{
while (!stop_button()) {
printf("Turn knob; STOP to end -> %d\n", knob());
msleep(100L);
}
beep();
}
/* void
testsonar(void)
{
while (!stop_button()) {
printf("Test sonar; STOP to end -> %d\n", sonar());
msleep(100L);
}
beep();
}
*/
void
testanalogs(void)
{
printf("Analog ins; STOP to end\n");
sleep(1.0);
printf("Turn knob to select port\n");
sleep(1.0);
while (!stop_button()) {
/* Get the value of the knob. The A/D numbering is 0-6. */
int val = knob_int_value(0, 6);
printf("Port %d: %d\n", val, analog(val));
msleep(100L);
}
beep();
}
void hb_ir_transmit_on()
{
bit_set(0x1000,0b01000000);
}
void hb_ir_transmit_off()
{
bit_clear(0x1000,0b01000000);
}
void testir()
{
printf("Blinking IR xmit STOP to stop\n");
while(!stop_button()){
hb_ir_transmit_on();
sleep(.1);
hb_ir_transmit_off();
sleep(0.1);
}
beep();
}
void testcmu()
{
printf("Attach CMUcam Press START\n");
while(!start_button()){}
beep();msleep(50L);beep();
printf("Blink test, HoldSTOP to stop\n");
while(!stop_button()){
serial_init(0);
serial_string("rs\r");
sr_blink();
sr_blink();
sr_blink();
}
}
void sr_blink()
{
serial_string("L1 1\r");
msleep(100L);
serial_string("L1 0\r");
msleep(100L);
}
void serial_wait(int c){
int d=0;
while(d != c){
d = serial_getchar(0);
}
}
void serial_string(char c[])
{
int x,y=0;
while(y != 0x0d){
y = c[x++];
serial_putchar(y);
}
}
int count_digits(int val)
{
if ((val >= 0) && (val <= 9))
return 1;
else if (((val < 0) && (val >= -9)) || ((val >= 10) && (val <= 99)))
return 2;
else // good enough at 3...
return 3;
}
int print_spaces(int num)
{
while (num--)
printf(" ");
}
void testww01()
{
int right=0;
int left=0;
int prev_right=-1;
int prev_left=-1;
int ra = -1;
int rb = -1;
int rd = -1;
int la = -1;
int lb = -1;
int ld = -1;
int changed = 0;
printf("Turn wheels Press START\n");
while (!start_button()){}
beep();
set_quad_mode();
enable_encoder(0);
enable_encoder(1);
while (!stop_button()){
left = read_encoder(0);
right = read_encoder(1);
/* check for changes to any of the values; this helps us prevent ugly screen flashes on the LCD */
if ((left != prev_left) || (right != prev_right))
changed = 1;
prev_left = left;
prev_right = right;
if (digital(8) != ra) {
changed = 1;
ra = digital(8);
}
if (digital(13) != rb) {
changed = 1;
rb = digital(13);
}
if (digital(14) != rd) {
changed = 1;
rd = digital(14);
}
if (digital(7) != la) {
changed = 1;
la = digital(7);
}
if (digital(12) != lb) {
changed = 1;
lb = digital(12);
}
if (digital(10) != ld) {
changed = 1;
ld = digital(10);
}
if (changed) {
changed = 0;
printf("r:%d", right);
print_spaces(5 - count_digits(right)); /* make sure the line ends up being 16 chars, so the left encoder values start at left most column of LCD line 2 */
printf("a%d b%d d%d ", ra, rb, rd);
printf("l:%d", left);
print_spaces(5 - count_digits(left));
printf("a%d b%d d%d\n", la, lb, ld);
}
}
disable_encoder(0);
disable_encoder(1);
}
/****************************** hbmenu.c ********************************/
/* Menu functions which also allow variables to be set via the knob
and selection buttons
Version 1.0
Written for MIT 6.270 contest by Anne Wright 11/14/1991
Version 2.0
Converted for Handy Board for Botball by Anne Wright 1/13/2001
*/
/* abstractions for chosen_button */
#define NEITHER_B 0
#define START_B 1
#define STOP_B 2
/* abstractions for wait_button */
#define UP_B 3
#define DOWN_B 4
#define CYCLE_B 5
/*****************************button routines*************************/
/* Return minimum of two integers */
int min(int a,int b)
{
if(a<b)
return(a);
else
return(b);
}
/* Return minimum of two floats */
float fmin(float a,float b)
{
if(a<b)
return(a);
else
return(b);
}
/* Returns which button is depressed using definitions above. If
both are pressed, start has precedence */
int chosen_button()
{
if(start_button())
return START_B;
else if(stop_button())
return STOP_B;
else
return NEITHER_B;
}
/* wait until button is depressed(DOWN_B), released(UP_B), or
both(CYCLE_B) and return which button if any activated the
sequence */
int wait_button(int i)
{
if(i==DOWN_B){
while(!(start_button() || stop_button()));
return chosen_button();
}
else if (i==UP_B) {
int b;
b=chosen_button();
while(start_button() || stop_button());
return b;
}
else {
int b;
while(!(start_button() || stop_button()));
b=chosen_button();
while(start_button() || stop_button());
return b;
}
}
/********************* Knob to Number routines*****************************/
/* Returns an integer value from min_val to max_val based on the current
position of the knob */
int knob_int_value(int min_val,int max_val)
{
int val, coarseness=(255)/(max_val-min_val),selection;
val=min((knob())/coarseness+min_val,max_val);
return min(val,max_val);
}
/* Returns an float value from min_val to max_val based on the current
position of the knob */
float knob_float_value(float min_val,float max_val)
{
float val, coarseness=(255.)/(max_val-min_val),selection;
val=fmin(((float)knob())/coarseness+min_val,max_val);
return fmin(val,max_val);
}
/******************** Menu selection routines ****************************/
/* While waiting for a button press, display the string passed in and
the val, the integer value betwen min_val and max_val for the knob.
If the button pressed is the start button, returns the final value
of val. If the button pressed is the stop button, returns -1. */
int select_int_value(char s[],int min_val,int max_val)
{
int val, button;
printf("%s %d to %d\n",s,min_val, max_val);
sleep(0.8);
/* Wait until no button is pressed */
wait_button(UP_B);
/* While no button is pressed, display the string passed in and the
current value of val */
while((button = chosen_button())==NEITHER_B) {
val=knob_int_value(min_val,max_val);
printf("%s %d\n",s,val);
msleep(100L);
}
/* Wait until no button is pressed */
wait_button(UP_B);
if(button==STOP_B)
return(-1); /** -1 means stop pressed -- do not reset value **/
else
return(val); /* Stop not pressed, return val */
}
/* While waiting for a button press, display the string passed in and
the val, the float value betwen min_val and max_val for the knob.
If the button pressed is the start button, returns the final value
of val. If the button pressed is the stop button, returns -1. */
float select_float_value(char s[],float min_val,float max_val)
{
float val;
int button;
printf("%s %f to %f\n",s,min_val, max_val);
sleep(0.8);
/* Wait until no button is pressed */
wait_button(UP_B);
/* While no button is pressed, display the string passed in and the
current value of val */
while((button = chosen_button())==NEITHER_B) {
val=knob_float_value(min_val,max_val);
printf("%s %f\n",s,val);
msleep(100L);
}
/* Wait until no button is pressed */
wait_button(UP_B);
if(button==STOP_B)
return(-1.0); /** -1 means stop pressed -- do not reset value **/
else
return(val); /* Stop not pressed, return val */
}
/* While waiting for a button press, display the string from the array
of strings passed in which corresponds to the current position of
the knob (see select_int_value). If the button pressed is the
start button, returns the index of the string selected (0 to n-1).
If the button pressed is the stop button, returns -1. */
int select_string(char choices[][],int n)
{
int selection,last_selection=-1,button;
if(n>_array_size(choices))
n=_array_size(choices);
/* Wait until no button is pressed */
wait_button(UP_B);
/* While no button is pressed, display the string from the array
of strings passed in which corresponds to the current position
of the knob */
while((button = chosen_button())==NEITHER_B) {
selection=knob_int_value(0,n-1);
if(selection!=last_selection) {
printf("%s\n",choices[selection]);
msleep(150L);
last_selection=selection;
}
}
/* Wait until no button is pressed */
wait_button(UP_B);
if(button==STOP_B)
return(-1); /** -1 means stop pressed -- do not reset value **/
else
return(selection); /* Stop not pressed, return val */
}
/*
* Local variables:
* comment-column: 40
* c-indent-level: 4
* c-basic-offset: 4
* End:
*/
©2004-2005 Noetic Design, Inc. All Rights Reserved. Nubotics and WheelWatcher are trademarks of Noetic Design, Inc.