Subject:
|
Re: Serial Interface
|
Newsgroups:
|
lugnet.robotics.handyboard
|
Date:
|
Wed, 1 Jul 1998 15:56:30 GMT
|
Original-From:
|
Douglas Blank <{dblank@comp.uark.}StopSpammers{edu}>
|
Viewed:
|
1157 times
|
| |
| |
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
|
|
Message is in Reply To:
| | Serial Interface
|
| 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 (...) (26 years ago, 1-Jul-98, to lugnet.robotics.handyboard)
|
2 Messages in This Thread:
- Entire Thread on One Page:
- Nested:
All | Brief | Compact | Dots
Linear:
All | Brief | Compact
|
|
|
|