Yan Tran
91.548
February 12, 2004
This lab called for prototyping an ambient display through the cricket and infrared communication with a PC that makes a TCP/IP connection to download data that is used to manipulate the cricket.
Joseph Giardina and I worked together to figure out the best way to communicate values to the cricket without the use of the logo software and to create a TCP/IP connection to a remote server to download information. Originally we attempted to send the cricket code to run, using the procedure described in final part of the first lab. However, we could not get the cricket to reliably run the code it was transmitted. Sometimes it would only run half the code or none at all. It was believed that there maybe either a timing issue or a echo-processing problem. In the end it was decided that the cricket should be pre-loaded with a procedure and the local linux machine would simply transmit values to it to react to. To download data through TCP/IP to the local machine from a remote server, it was decided that calling curl through a system() call for an HTTP transaction was the easiest way of obtaining dynamic data. Joseph Giardina and myself ultimately created different ambient displays but used these techniques for the end-products.
In this implementation, a cricket responds to a remote server's load average by beeping more frequently for larger load averages and less often for lower load averages. The cricket beeps are meant to simulate pulsating lights. Three devices were used in this project: a linux server, a linux local client, and a cricket.
pong.cs.uml.edu runs a program that repeatedly pipes output from the uptime command to a file that is downloadable from its web server. The code is accessible at www.cs.uml.edu/~ytran/robotics/lab2/server.c and is listed as follows:
/******** Yan Tran server.c repeatedly store server uptime info to file that will be downloadable from web. ********/ #includeint main (void){ while(1){ system("uptime > uptimefile.txt"); sleep(2); } return 0; }
Meanwhile a local linux machine runs a process that downloads uptimefile.txt
from pong.cs.uml.edu. The process parses the file to extract the most recent load average
reading. From that reading, it derives an integer value that it then transmits to the
cricket via infrared. The lower the load average, the higher the integer value transmitted.
This downloading and transmitted action is continuously repeated.
The client code available at www.cs.uml.edu/~ytran/robotics/lab2/client.c is as follows:
/***** Yan Tran Lab2 client.c This program downloads a file that has a uptime info from pong.cs.uml.edu. It then extracts the most recent load average and calculates a wait value to transfer through infrared to the cricket. The program continues download load average values and send calculated wait values to the cricket. The serial port communication code was originally developped by Andrew Oswald. *******/ #include#include /* Standard input/output definitions */ #include /* String function definitions */ #include /* UNIX standard function definitions */ #include /* File control definitions */ #include /* Error number definitions */ #include /* POSIX terminal control definitions */ /* * 'open_port()' - Open serial port 1. * * Returns the file descriptor on success or -1 on error. */ int init_serial(void) /***open the serial port for writing****/ { int fd; /* File descriptor for the port */ struct termios options; /* open the port */ fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY); if (fd == -1) { /* * Could not open the port. */ perror("open_port: Unable to open /dev/ttyS0 - "); } fcntl(fd, F_SETFL, 0); /* get the current options */ tcgetattr(fd, &options); /* Set to 9600 Baud */ cfsetispeed(&options, B9600); cfsetospeed(&options, B9600); /* set raw input, 1 second timeout */ options.c_cflag |= (CLOCAL | CREAD); options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); options.c_oflag &= ~OPOST; options.c_cc[VMIN] = 0; options.c_cc[VTIME] = 10; /* set the options */ tcsetattr(fd, TCSANOW, &options); return fd; } int send_to_serial(int fd,int sleeptime) /* I - Serial port file */ { char buffer; buffer = sleeptime; write(fd, &buffer,1); /***send to infrared through file descriptor***/ fflush(stdout); return 1; } int main(void){ FILE*fd = NULL; int fd2 = 0; char line[256]; float sleeptime; fd2 =init_serial(); //open serial port for writing while(1){ /*****Use curl to download a file from pong.cs.uml.edu*****/ system("curl -o downloadedfile.txt pong.cs.uml.edu/~ytran/robotics/uptimefile.txt"); system("cat downloadedfile.txt"); //parse file //send value to cricket /****open downloaded file*****/ fd = fopen("downloadedfile.txt", "r"); /****parse downloaded file****/ fscanf(fd,"%s", line); fscanf(fd,"%s", line); fscanf(fd,"%s", line); fscanf(fd,"%s", line); fscanf(fd,"%s", line); fscanf(fd,"%s", line); fscanf(fd,"%s", line); fscanf(fd,"%s", line); fscanf(fd,"%s", line); fscanf(fd,"%s", line); /***here is the load average***/ line[255] = '\0'; /****calculate a wait value from the load average****/ printf("\n%f\n", atof(line)); sleeptime = atof(line); if (sleeptime >1) sleeptime = 1; sleeptime = sleeptime*100; sleeptime = 100 - sleeptime; printf("sleeptime is %d\n",(int)sleeptime); fclose(fd); /****transmit wait value*****/ send_to_serial(fd2,sleeptime); sleep(1); } return 0; }
The cricket runs a procedure that initially waits for the first new value from the IR port.
After that first IR value is received, it goes into a loop where it takes in IR port values
transmitted from the local linux machine and uses them as wait values. Between waits, it
transmits beeps. So the longer the wait, the fewer the beeps.
Here is the code, available at www.cs.uml.edu/~ytran/robotics/lab2/beep.lgo, that the cricket runs:
global [sleeptime] to beeploop waituntil[newir?] loop[ setsleeptime ir; beep; wait sleeptime; ] beeploop end