From dblank@comp.uark.edu Wed Jul 1 13:17:17 1998 Received: from aleve.media.mit.edu by hub.media.mit.edu; (5.65v3.2/1.1/06Jun95-8.2MPM) id AA10324; Wed, 1 Jul 1998 13:17:17 -0400 Received: from comp.uark.edu (root@comp.uark.edu [130.184.252.197]) by aleve.media.mit.edu (8.8.7/ML970927) with ESMTP id LAA00083 for <handyboard@media.mit.edu>; Wed, 1 Jul 1998 11:56:44 -0400 (EDT) Received: from comp.uark.edu (IDENT:dblank@dangermouse.uark.edu [130.184.201.233]) by comp.uark.edu (8.9.0/8.9.0) with ESMTP id KAA12202; Wed, 1 Jul 1998 10:56:30 -0500 (CDT) Sender: dblank@comp.uark.edu Message-Id: <359A5C2E.202B4BA3@comp.uark.edu> Date: Wed, 01 Jul 1998 10:56:30 -0500 From: Douglas Blank <dblank@comp.uark.edu> Organization: University of Arkansas, CS X-Mailer: Mozilla 4.04 [en] (X11; I; Linux 2.0.33 i686) Mime-Version: 1.0 To: Aaron Edsinger <aarone@sirius.com> Cc: handy <handyboard@media.mit.edu> Subject: Re: Serial Interface References: <199807010601.XAA26862@mail3.sirius.com> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Aaron Edsinger wrote: > Hello, > I've been having some problems using my HandyBoard to talk directly to my > PC via the serial interface. I disable Interactive C and then Poke() and > Peek() as has been described on this list. I send short character strings > from my PC to the HandyBoard under Windows 95. If I send strings longer > than 2 characters, it seems that some of the characters get lost. This > behavior seems to be affected by repositioning or slightly modifying the > code, suggesting perhaps a timing issue. Although there is the HEXMON program, I too, have been trying to do what you describe, and encountered the same problems. I found it to be a timing issue, and, through trial and error, have a found some settings that seem to work most of the time. My goal was to make C code that looked the same when compiled and run on the Host is the code that ran under IC. I am including the host and HB programs here. If anyone knows of a better way of communicating, please let us know. -Doug Blank ===================================================================== dblank@comp.uark.edu Douglas Blank, University of Arkansas Assistant Professor Computer Science ==================== http://www.uark.edu/~dblank ==================== This code was written for MS C++4.0 running on Win95. //************** BEGIN: serial_HOST.c /* VC++4.0 HandyBoard Host Programming System Dr. Douglas S. Blank University of Arkansas, Department of Computer Science www.uark.edu/~dblank This code runs on a host PC. */ #include <ctype.h> #include <conio.h> #include <stdlib.h> #include <stdio.h> #include "serial_HOST.h" void main(int argc, char *argv[]) { motor(0, 100); motor(1, 100); motor(2, 100); motor(3, 100); sleep(1000); motor(0, -100); motor(1, -100); motor(2, -100); motor(3, -100); sleep(1000); ao(); print("\nThis is a test"); printf("Knob is %d\n", knob() ); printf("Analog(0) is %d\n", analog(0)); printf("Digital(0) is %d\n", digital(0)); printf("Analog(1) is %d\n", analog(1)); printf("Digital(1) is %d\n", digital(1)); printf("Analog(2) is %d\n", analog(2)); printf("Digital(2) is %d\n", digital(2)); printf("Analog(3) is %d\n", analog(3)); printf("Digital(3) is %d\n", digital(3)); printf("Analog(4) is %d\n", analog(4)); printf("Digital(4) is %d\n", digital(4)); printf("Analog(5) is %d\n", analog(5)); printf("Digital(5) is %d\n", digital(5)); printf("Analog(6) is %d\n", analog(6)); printf("Digital(6) is %d\n", digital(6)); printf("Analog(7) is %d\n", analog(7)); printf("Digital(7) is %d\n", digital(7)); printf("Analog(8) is %d\n", analog(8)); printf("Digital(8) is %d\n", digital(8)); printf("Analog(9) is %d\n", analog(9)); printf("Digital(9) is %d\n", digital(9)); printf("Analog(10) is %d\n", analog(10)); printf("Digital(10) is %d\n", digital(10)); printf("Analog(11) is %d\n", analog(11)); printf("Digital(11) is %d\n", digital(11)); printf("Analog(12) is %d\n", analog(12)); printf("Digital(12) is %d\n", digital(12)); printf("Analog(13) is %d\n", analog(13)); printf("Digital(13) is %d\n", digital(13)); printf("Analog(14) is %d\n", analog(14)); printf("Digital(14) is %d\n", digital(14)); printf("Analog(15) is %d\n", analog(15)); printf("Digital(15) is %d\n", digital(15)); beep(); sleep(1000); while (! stop_button() ) { sprintf(buffer, "%d.0", (knob() * 10)); tone( buffer, "0.1"); } } //************** END: serial_HOST.c //************** BEGIN: serial_HOST.h /* VC++4.0 HandyBoard Host Programming System Dr. Douglas S. Blank University of Arkansas, Department of Computer Science www.uark.edu/~dblank */ #define MOTOR 0 #define AO 1 #define ANALOG 2 #define DIGITAL 3 #define PRINTF 4 #define KNOB 5 #define BEEP 6 #define TONE 7 #define START_BUTTON 8 #define STOP_BUTTON 9 #define QUIT 113 #define sleep(NUM) _sleep(NUM) #define SERIALWAIT 5 unsigned short PORT = 0x3f8; // LPT1: 0x378 COM1: 0x3f8 int send(int i) { int retval; retval = _outp( PORT, i); _sleep(SERIALWAIT); return retval; } int receive() { int retval; retval = _inp( PORT); _sleep(SERIALWAIT); retval = _inp( PORT); return retval; } void hangup() { send(QUIT); } void print(char buffer[]) { int i; send(PRINTF); for (i = 0; buffer[i] != 0; i++) send(buffer[i]); send('\0'); } void motor(int motornum, int power) { send(MOTOR); send(motornum); send(power + 100); // taken off on the other end } int analog(int sensor) { send(ANALOG); send(sensor); return receive(); } int digital(int sensor) { send(DIGITAL); send(sensor); return receive(); } void ao() { send(AO); } int knob() { send(KNOB); return receive(); } void beep() { send(BEEP); } void tone(char f1[], char f2[]) { int i; send(TONE); for (i = 0; f1[i] != 0; i++) send(f1[i]); send('\0'); for (i = 0; f2[i] != 0; i++) send(f2[i]); send('\0'); _sleep((unsigned long) (atof(f2) * 1000)); // to keep from overflowing serial line } void interactive() { char c; char key = ' '; while (key != 'q') { key = getch(); send(key); printf("Sent %c\n", key); c = receive(); printf("Got %c as a return value\n", c); } } int start_button() { send(START_BUTTON); return receive(); } int stop_button() { send(STOP_BUTTON); return receive(); } //************** END: serial_HOST.h //************** BEGIN: serial_HB.c /* VC++4.0 HandyBoard Programming System (Parts taken from other HB programs) Dr. Douglas S. Blank University of Arkansas, Department of Computer Science www.uark.edu/~dblank This code runs on the HB */ #define MOTOR 0 #define AO 1 #define ANALOG 2 #define DIGITAL 3 #define PRINTF 4 #define KNOB 5 #define BEEP 6 #define TONE 7 #define START_BUTTON 8 #define STOP_BUTTON 9 #define QUIT 113 int _isspace(int a) /* returns 1 for space or tab, 0 otherwise */ /* internal routine used by atof() and cgets() */ { return ((a == 32) || (a == 9)); /* 32 is space, 9 is tab */ } /*****************************************************************************/ int _isdigit(int a) /* returns 1 if a digit 0-9, 0 otherwise */ /* internal routine used by atof() */ { return ((a >= 48) && (a <= 57)); /* 48 is '0', 57 is '9' */ } float atof(char s[]) /* Convert a string containing a number in ASCII */ /* form (integer, float, or exponential float) to a */ /* float. Strips whitespace characters (space and */ /* tab) from the front of the string, but stops */ /* parsing at the first (unexpected) non-numeric */ /* character if the string has garbage at the end. */ /* This means that " 34.3foo78" translates to 34.3. */ /* Modified from atof() function in the standard */ /* library of the Hi-Tec C compiler for CP/M. */ /* Note: all string literals converted to decimal */ /* form because IC can't deal with string literals */ /* in math calculations. */ /* Also note: very ugly code because IC will not */ /* allow any math operations on pointers! Thus, the */ /* the number string has to be treated as an array! */ /* Also also note: no error handling; assumes that */ /* the string is a valid representation of a number! */ /* Valid range for exponential-format numbers is */ /* approximately 2.0e-38 to 3.4e+38. */ { int i=0; /* index into string array */ int sign=0; /* mantissa sign flag: 0=positive, 1=negative */ int exp0=0; /* mantissa exponent counter */ int eexp=0; /* E-form exponent counter */ int expsign=0; /* exponent sign flag: 0=positive, 1=negative */ float m=0.0; /* mantissa accumulator */ /* skip any leading whitespace (space, tab) */ while (_isspace(s[i])) i++; /* skip it */ /* check for mantissa sign */ if (s[i] == 45) /* 45 is '-' */ { sign = 1; /* flag minus sign */ i++; /* point to next */ } else if (s[i] == 43) /* 43 is '+' */ i++; /* point to next */ /* now get all digits up to either a decimal point or an e/E */ while (_isdigit(s[i])) { m = 10.0*m + (float)(s[i] - 48); /* 48 is '0' */ i++; /* point to next */ } /* no more digits, so check for decimal point */ if (s[i] == 46) /* 46 is '.' */ { i++; /* point to next */ /* get all digits after decimal point */ while (_isdigit(s[i])) { exp0--; m = 10.0*m + (float)(s[i] - 48); /* 48 is '0' */ i++; /* point to next */ } } /* check for e/E exponential form */ if ((s[i] == 101) || (s[i] == 69)) /* 101 is 'e', 69 is 'E' */ { i++; /* point to next */ /* check for exponent sign */ if (s[i] == 45) /* 45 is '-' */ { expsign = 1; /* flag negative exponent */ i++; /* point to next */ } else if (s[i] == 43) /* 43 is '+' */ i++; /* point to next */ /* now get exponent */ while (_isdigit(s[i])) { eexp = eexp*10 + s[i] - 48; /* 48 is '0' */ i++; /* point to next */ } /* adjust exponent sign */ if (expsign) eexp = -eexp; /* make it negative */ } /* compute absolute value of final float */ exp0 += eexp; while (exp0 < 0) /* for negative exponents */ { m = m / 10.0; exp0++; } while (exp0 > 0) /* for positive exponents */ { m = m * 10.0; exp0--; } /* adjust final float sign from mantissa */ if (sign) return (-m); /* negative */ else return (m); /* positive */ } void disable_pcode_serial() /* necessary to receive characters using serial_getchar */ { poke(0x3c, 1); } void reenable_pcode_serial() /* necessary for IC to interact with board again */ { poke(0x3c, 0); } /* ====================================================================== For sending and receiving single bytes, you can use Randy's IC code: */ void serial_putchar(int c) { while (!(peek(0x102e) & 0x80)); /* wait until serial transmit empty */ poke(0x102f, c); /* send character */ } int serial_getchar() { while (!(peek(0x102e) & 0x20)); /* wait for received character */ return peek(0x102f); } void main(void) { int pos, c = ' ', var1, var2; float f1, f2; char buffer[80]; disable_pcode_serial(); beep(); printf("\nSerial IO Mode!"); printf("Listening..."); msleep(500L); while (c != 'q') { c = serial_getchar(); /* printf("[%d] ", c); */ if (c == MOTOR) { var1 = serial_getchar(); var2 = serial_getchar() - 100; motor(var1, var2); } else if (c == AO) { ao(); } else if (c == ANALOG) { var1 = serial_getchar(); serial_putchar(analog(var1)); } else if (c == DIGITAL) { var1 = serial_getchar(); serial_putchar(digital(var1)); } else if (c == PRINTF) { pos = 0; while (c != 0) { buffer[pos++] = c; c = serial_getchar(); } buffer[pos] = '\0'; printf(buffer); } else if (c == TONE) { pos = 0; c = serial_getchar(); while (c != 0) { buffer[pos++] = c; c = serial_getchar(); } buffer[pos] = '\0'; f1 = atof(buffer); pos = 0; c = serial_getchar(); while (c != 0) { buffer[pos++] = c; c = serial_getchar(); } buffer[pos] = '\0'; f2 = atof(buffer); tone(f1, f2); } else if (c == START_BUTTON) { serial_putchar(start_button()); } else if (c == STOP_BUTTON) { serial_putchar(stop_button()); } else if (c == BEEP) { beep(); } else if (c == KNOB) { serial_putchar(knob()); } } reenable_pcode_serial(); printf("\nHB Mode!"); } //************** END: serial_HB.c