/****************************************************************/ /* hp_das_12-22-96.c */ /* */ /* Used on FASTEX (JHare) */ /* */ /* hp_das.c is an Hewlett-Packard Data Acquisition System */ /* that acquires and archives data from the following */ /* instruments and Central Data Sytems SCSI terminal server */ /* port assignments: */ /* */ /* INSTRUMENT SERIAL PORT (on CDS) */ /* GILL Sonic Anemometer 1 */ /* Campbell CO2/K-Gill 2 */ /* Campbell Radiometers/Mean Met 3 */ /* Robertson Gyrocompass 4 */ /* Ophir Infrared Hygrometer 5 */ /* Campbell Ship Motion 6 */ /* Auxiliary Ship Information 7 */ /* Lowrance GPS 8 */ /* */ /* Output of data through the RS232(a) and RS232(b) ports */ /* on the HP computing unit is achieved when the directives */ /* OUT_RS232A and OUT_RS232B are defined in hp_das.h (see */ /* documentation in hp_das.h for definition instructions). */ /* When set, the output is at 9600 baud, no parity, 8 data */ /* bits and 1 stop bit. */ /* */ /* ASCII string output control for ports 3,5,7 and 8 is */ /* explained and set in hp_das.h . */ /* */ /* Data are output to files of the following path and form: */ /* */ /* ./data/Pp_dddhh */ /* */ /* where, p = serial port (on CDS) -1 */ /* ddd = julian day */ /* hh = hour (UTC) */ /* */ /* Compiled using: cc -ohp_das hp_das.c */ /* */ /* DGregg 8/95 */ /* DGottas 8/9/96 */ /* DGottas 12/5/96 */ /* JHare 12/21/96 */ /* */ /****************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "hp_das.h" /* define the number of SCSI terminals */ #define NTTYS 8 /* define MOTION_FIELDS as 6 if not previously defined in hp_das.h or defined as <=0 */ #ifndef MOTION_FIELDS #define MOTION_FIELDS 6 #else #if (MOTION_FIELDS<=0) #undef MOTION_FIELDS #define MOTION_FIELDS 6 #endif #endif /* define FASTEX_FIELDS as 10 if not previously defined in hp_das.h or defined as <=0 */ #ifndef FASTEX_FIELDS #define FASTEX_FIELDS 10 #else #if (FASTEX_FIELDS<=0) #undef FASTEX_FIELDS #define FASTEX_FIELDS 10 #endif #endif /* define the number of bytes in a motion record (2 bytes per field plus 2 leading bytes) */ #define MOTION_BYTES MOTION_FIELDS*2+2 /* define the number of bytes in a FASTEX record (2 bytes per field plus 2 leading bytes) */ #define FASTEX_BYTES FASTEX_FIELDS*2+2 /* define MAX_MEANS as 200 if not previously defined in hp_das.h or defined as <=0 */ #ifndef MAX_MEANS #define MAX_MEANS 200 #else #if (MAX_MEANS<=0) #undef MAX_MEANS #define MAX_MEANS 200 #endif #endif /* define MAX_HEADING as 200 if not previously defined in hp_das.h or defined as <=0 */ #ifndef MAX_HEADING #define MAX_HEADING 200 #else #if (MAX_HEADING<=0) #undef MAX_HEADING #define MAX_HEADING 200 #endif #endif /* define MAX_GPS as 200 if not previously defined in hp_das.h or defined as <=0 */ #ifndef MAX_GPS #define MAX_GPS 200 #else #if (MAX_GPS<=0) #undef MAX_GPS #define MAX_GPS 200 #endif #endif /* define MAX_OPHIR as 200 if not previously defined in hp_das.h or defined as <=0 */ #ifndef MAX_OPHIR #define MAX_OPHIR 200 #else #if (MAX_OPHIR<=0) #undef MAX_OPHIR #define MAX_OPHIR 200 #endif #endif /* define OUT_RS232A and OUT_RS232A as "" if not previously defined in hp_das.h */ #ifndef OUT_RS232A #define OUT_RS232A "" #endif #ifndef OUT_RS232B #define OUT_RS232B "" #endif /* define STATUS_INT as 60 if not previously defined in hp_das.h or defined as <=0 */ #ifndef STATUS_INT #define STATUS_INT 60 #else #if (STATUS_INT<=0) #undef STATUS_INT #define STATUS_INT 60 #endif #endif void main() { /* declare all functions and variables */ void key_quit(),get_time(); int motion_io(),fastex_io(),sonic_io(),ascii_io(),gyro(); char port0_file[25],port1_file[25],port2_file[25],port3_file[25],port4_file[25], port5_file[25],port6_file[25],port7_file[25], mean[MAX_MEANS],heading[MAX_HEADING],gps[MAX_GPS],ophir[MAX_OPHIR], test_buffer[25],DateString[50],*tok; int i=0,start_hour=0,curr_hour=0,nfound=0,j=0,stat=0,nread=0,port[10],flag[8], mean_index=0,heading_index=0,gps_index=0,ophir_index=0,OutPort=0, OutRS232A[8],OutRS232B[8]; long t_usec=0,timeout_count=0,nseconds=0,mean_usec=0,heading_usec=0,gps_usec=0,ophir_usec=0,status=0; unsigned long t_sec=0,dl_sec=0,mean_sec=0,heading_sec=0,gps_sec=0,ophir_sec=0; fd_set rfd; size_t max_size=50; mflag modem; struct timeval timeout; struct termios term_9600,term_9600_odd,term_4800; struct tm *ptr; FILE *port0_fp,*port1_fp,*port2_fp,*port3_fp,*port4_fp,*port5_fp,*port6_fp,*port7_fp, *port0,*port1,*port2,*port3,*port4,*port5,*port6,*port7,*port8,*port9; tok=strtok(OUT_RS232A," .,;:/\\"); /* strip first token off OUT_RS232A string */ while(tok!=NULL) /* while more tokens exist... */ { sscanf(tok,"%d",&OutPort); /* convert token to integer */ if((OutPort<1)||(OutPort>8)) continue; /* if invalid port...continue */ OutRS232A[OutPort-1]=1; /* set true boolean for output port */ tok=strtok(NULL," .,:;/\\"); /* get next token */ } tok=strtok(OUT_RS232B," .,;:/\\"); /* strip first token off OUT_RS232B string */ while(tok!=NULL) /* while more tokens exist... */ { sscanf(tok,"%d",&OutPort); /* convert token to integer */ if((OutPort<1)||(OutPort>8)) continue; /* if invalid port...continue */ OutRS232B[OutPort-1]=1; /* set true boolean for output port */ tok=strtok(NULL," .,:;/\\"); /* get next token */ } /* open ports 1-8 on the Central Data SCSI terminal server for low level I/O */ port[0]=open("/dev/ttyC50",O_RDWR); port[1]=open("/dev/ttyC51",O_RDWR); port[2]=open("/dev/ttyC52",O_RDWR); port[3]=open("/dev/ttyC53",O_RDWR); port[4]=open("/dev/ttyC54",O_RDWR); port[5]=open("/dev/ttyC55",O_RDWR); port[6]=open("/dev/ttyC56",O_RDWR); port[7]=open("/dev/ttyC57",O_RDWR); if(strlen(OUT_RS232A)) /* if ports have been specified in OUT_RS232A string... */ port[8]=open("/dev/tty0p0",O_WRONLY); /* open RS232(a) port on HP for low level I/0 */ if(strlen(OUT_RS232B)) /* if ports have been specified in OUT_RS232B string... */ port[9]=open("/dev/tty1p0",O_WRONLY); /* open RS232(b) port on HP for low level I/0 */ /* open ports 1-8 I/O streams */ if((port0 = fdopen(port[0],"rb+"))== NULL) perror("port0 stream pointer bad\n"); if((port1 = fdopen(port[1],"rb+"))== NULL) perror("port1 stream pointer bad\n"); if((port2 = fdopen(port[2],"r+"))== NULL) perror("port2 stream pointer bad\n"); if((port3 = fdopen(port[3],"rb+"))== NULL) perror("port3 stream pointer bad\n"); if((port4 = fdopen(port[4],"r+"))== NULL) perror("port4 stream pointer bad\n"); if((port5 = fdopen(port[5],"rb+"))== NULL) perror("port5 stream pointer bad\n"); if((port6 = fdopen(port[6],"r+"))== NULL) perror("port6 stream pointer bad\n"); if((port7 = fdopen(port[7],"r+"))== NULL) perror("port7 stream pointer bad\n"); if(strlen(OUT_RS232A)) /* if ports have been specified in OUT_RS232A string... */ if((port8 = fdopen(port[8],"w"))== NULL) perror("port8 stream pointer bad\n"); /* open RS232(a) I/O stream */ if(strlen(OUT_RS232B)) /* if ports have been specified in OUT_RS232B string... */ if((port9 = fdopen(port[9],"w"))== NULL) perror("port9 stream pointer bad\n"); /* open RS232(a) I/O stream */ tcgetattr(port[0],&term_4800); /* store terminal attributes from port 1 into term_4800 */ tcgetattr(port[4],&term_9600); /* store terminal attributes from port 5 into term_9600 */ /* create terminal settings for the 4800 baud/no parity/1 stop bit/8 data bits/input mode */ term_4800.c_lflag = 0; term_4800.c_oflag &= ~OPOST; term_4800.c_iflag &= ~(INPCK | PARMRK | BRKINT | INLCR | ICRNL | IUCLC | IXANY ); term_4800.c_iflag |= IGNBRK; term_4800.c_cflag &= ~(CSIZE | PARODD | PARENB | CSTOPB); term_4800.c_cflag |= (CREAD | CLOCAL | HUPCL|CS8); /* create terminal settings for the 9600 baud/no parity/1 stop bit/8 data bits/input mode */ term_9600.c_lflag = 0; term_9600.c_oflag &= ~OPOST; term_9600.c_iflag &= ~(INPCK | PARMRK | BRKINT | INLCR | ICRNL | IUCLC | IXANY ); term_9600.c_iflag |= IGNBRK; term_9600.c_cflag &= ~(CSIZE | PARODD | PARENB | CSTOPB); term_9600.c_cflag |= (CREAD | CLOCAL | HUPCL|CS8); /* create terminal settings for the 9600 baud/odd parity/1 stop bit/7 data bits/input mode */ term_9600_odd.c_lflag = 0; term_9600_odd.c_oflag &= ~OPOST; term_9600_odd.c_iflag &= ~(~INPCK | PARMRK | BRKINT | INLCR | ICRNL | IUCLC | IXANY ); term_9600_odd.c_iflag |= IGNBRK; term_9600_odd.c_cflag &= ~(CSIZE | PARODD | PARENB | CSTOPB ); term_9600_odd.c_cflag |=(CREAD | CLOCAL | HUPCL | CS7 | PARENB | PARODD | ~CSTOPB | IXON | IXOFF); cfsetispeed(&term_4800,B4800); /* set input baud rate in term_4800 to 4800 */ cfsetospeed(&term_4800,B4800); /* set output baud rate in term_4800 to 4800 */ cfsetispeed(&term_9600,B9600); /* set input baud rate in term_9600 to 9600 */ cfsetospeed(&term_9600,B9600); /* set output baud rate in term_9600 to 9600 */ cfsetispeed(&term_9600_odd,B9600); /* set input baud rate in term_9600_odd to 9600 */ cfsetospeed(&term_9600_odd,B9600); /* set output baud rate in term_9600_odd to 9600 */ /* set the terminal parameters for each SCSI port */ if(tcsetattr(port[0],TCSANOW,&term_4800) != 0) printf("port0 tcset error\n"); if(tcsetattr(port[1],TCSANOW,&term_9600) != 0) printf("port1 tcset error\n"); if(tcsetattr(port[2],TCSANOW,&term_9600) != 0) printf("port2 tcset error\n"); if(tcsetattr(port[3],TCSANOW,&term_9600_odd) != 0) printf("port3 tcset error\n"); if(tcsetattr(port[4],TCSANOW,&term_9600) != 0) printf("port4 tcset error\n"); if(tcsetattr(port[5],TCSANOW,&term_9600) != 0) printf("port5 tcset error\n"); if(tcsetattr(port[6],TCSANOW,&term_9600) != 0) printf("port6 tcset error\n"); if(tcsetattr(port[7],TCSANOW,&term_4800) != 0) printf("port7 tcset error\n"); if(strlen(OUT_RS232A)) if(tcsetattr(port[8],TCSANOW,&term_9600) != 0) printf("RS232(a) tcset error\n"); if(strlen(OUT_RS232B)) if(tcsetattr(port[9],TCSANOW,&term_9600) != 0) printf("RS232(b) tcset error\n"); /* set all modem lines to low except Data Terminal Ready and configure gyro port */ modem |= (~MRTS | ~MCTS | ~MDSR | ~MDCD | MDTR | ~MRI | ~MDRS); ioctl(port[3],MCSETA,&modem); /* start hourly acquisition loop */ Start: nseconds = status = time((long*)0); /* get seconds since 1970 */ ptr = gmtime(&nseconds); /* convert seconds to yr,mo,dy,hr...etc. */ start_hour=(*ptr).tm_hour; /* store hr as start_hour */ curr_hour=start_hour; /* store hr as current hour */ system("clear"); /* clear terminal */ /* formulate hourly output paths and filenames for all ports */ strftime(&port0_file,max_size,"./data/P0_%j%H",ptr); strftime(&port1_file,max_size,"./data/P1_%j%H",ptr); strftime(&port2_file,max_size,"./data/P2_%j%H",ptr); strftime(&port3_file,max_size,"./data/P3_%j%H",ptr); strftime(&port4_file,max_size,"./data/P4_%j%H",ptr); strftime(&port5_file,max_size,"./data/P5_%j%H",ptr); strftime(&port6_file,max_size,"./data/P6_%j%H",ptr); strftime(&port7_file,max_size,"./data/P7_%j%H",ptr); /* open output file streams for appending */ if((port0_fp = fopen(port0_file,"a+")) == NULL)perror("port0 file pointer bad\n"); if((port1_fp = fopen(port1_file,"a+")) == NULL)perror("port1 file pointer bad\n"); if((port2_fp = fopen(port2_file,"a+")) == NULL)perror("port2 file pointer bad\n"); if((port3_fp = fopen(port3_file,"a+")) == NULL)perror("port3 file pointer bad\n"); if((port4_fp = fopen(port4_file,"a+")) == NULL)perror("port4 file pointer bad\n"); if((port5_fp = fopen(port5_file,"a+")) == NULL)perror("port5 file pointer bad\n"); if((port6_fp = fopen(port6_file,"a+")) == NULL)perror("port6 file pointer bad\n"); if((port7_fp = fopen(port7_file,"a+")) == NULL)perror("port7 file pointer bad\n"); /* output data title header to each output file */ fprintf(port0_fp,"Sonic\n"); fprintf(port1_fp,"CO2 & K-Gill\n"); fprintf(port2_fp,"Radiometers & Mean Met\n"); fprintf(port3_fp,"Gyrocompass\n"); fprintf(port4_fp,"Ophir\n"); fprintf(port5_fp,"Ship Motion\n"); fprintf(port6_fp,"Auxiliary Ship\n"); fprintf(port7_fp,"GPS\n"); fputc('a',port4); /* query Ophir for 20Hz data output */ fflush(NULL); /* flush all file streams */ /* start main data acquisition loop */ while(start_hour == curr_hour) { if(signal(SIGINT,SIG_IGN) != SIG_IGN)signal(SIGINT,key_quit); /* trap CTRL-C to quit */ if(signal(SIGQUIT,SIG_IGN) != SIG_IGN)signal(SIGQUIT,key_quit); FD_ZERO(&rfd); /* zero out the read bitmask */ for(i=0;i<8;i++) /* loop over all SCSI channels */ FD_SET(port[i],&rfd); /* set each port mask to the read mask */ timeout.tv_sec = 0; /* set select timeout seconds to zero */ timeout.tv_usec =10; /* set select timeout milliseconds to 10 */ switch(nfound=select(NTTYS+11,&rfd,0,0,&timeout)) /* examine all ports for reading status */ { case -1: { printf("SELECT FAILED\r"); /* inform user of select failure */ exit(EXIT_FAILURE); /* exit program */ break; } case 0: { if(timeout_count >= 10000) /* if no port is ready for reading for 100 seconds... */ { printf("TIMED OUT FOR 100 SECONDS\n"); /* inform user of timeout */ exit(1); /* exit program */ } timeout_count +=1; /* if no ports are read for reading step the timeout counter */ break; } default: { timeout_count = 0; /* reset the timeout counter */ get_time(&t_usec,&t_sec); /* get current seconds and microseconds */ /* acquire sonic data if port is ready for reading... */ if(FD_ISSET(port[0],&rfd)) flag[0]+=sonic_io(port[0],port0,port0_fp,OutRS232A[0],OutRS232B[0],port8,port9); /* acquire CO2/K-Gill data if port is ready for reading... */ if(FD_ISSET(port[1],&rfd)) flag[1]+=fastex_io(port[1],port1,port1_fp,OutRS232A[1],OutRS232B[1],port8,port9); /* acquire Radiometer & Mean Met data if port is ready for reading... */ if(FD_ISSET(port[2],&rfd)) flag[2]+=ascii_io(port[2],port2,port2_fp,mean,&mean_index,&mean_sec,&mean_usec,MAX_MEANS,OutRS232A[2],OutRS232B[2],port8,port9,0); /* acquire gyrocompass data if port is ready for reading... */ if(FD_ISSET(port[3],&rfd)) flag[3]+=gyro(port[3],port3,port3_fp,OutRS232A[3],OutRS232B[3],port8,port9); /* acquire Ophir data if port is ready for reading... */ if(FD_ISSET(port[4],&rfd)) flag[4]+=ascii_io(port[4],port4,port4_fp,ophir,&ophir_index,&ophir_sec,&ophir_usec,MAX_OPHIR,OutRS232A[4],OutRS232B[4],port8,port9,0); /* acquire Ship Motion if port is ready for reading... */ if(FD_ISSET(port[5],&rfd)) flag[5]+=motion_io(port[5],port5,port5_fp,OutRS232A[5],OutRS232B[5],port8,port9); /* acquire Ship Heading data if port is ready for reading... */ if(FD_ISSET(port[6],&rfd)) flag[6]+=ascii_io(port[6],port6,port6_fp,heading,&heading_index,&heading_sec,&heading_usec,MAX_HEADING,OutRS232A[6],OutRS232B[6],port8,port9,0); /* acquire GPS data if port is ready for reading... */ if(FD_ISSET(port[7],&rfd)) flag[7]+=ascii_io(port[7],port7,port7_fp,gps,&gps_index,&gps_sec,&gps_usec,MAX_GPS,OutRS232A[7],OutRS232B[7],port8,port9,0); break; } } if(nseconds>=status) /* if status-nseconds seconds have elapsed... */ { nseconds = time((long*)0); /* get seconds since 1970 */ ptr = gmtime(&nseconds); /* convert seconds to yr,mo,dy,hr...etc. */ strftime(DateString,max_size,"%H:%M:%S",ptr); printf(" %s bytes/%d sec: ",DateString,STATUS_INT); for(i=0;i<8;i++) /* for ports 0-8 ... */ { printf("P%d=%d ",i,flag[i]); /* print number of bytes read */ flag[i]=0; /* reset activity flag to false */ } printf("\r"); /* print CR */ status=time(&status)+STATUS_INT; /* set the next status output time */ } nseconds = time((long*)0); /* get seconds since 1970 */ ptr = gmtime(&nseconds); /* convert seconds to yr,mo,dy,hr...etc. */ curr_hour=(*ptr).tm_hour; /* store hr to curr_hour */ } /* at the end of each hour output all incomplete ASCII strings to appropriate data output file */ ascii_io(port[2],port2,port2_fp,mean,&mean_index,&mean_sec,&mean_usec,MAX_MEANS,OutRS232A[2],OutRS232B[2],port8,port9,1); ascii_io(port[4],port4,port4_fp,ophir,&ophir_index,&ophir_sec, &ophir_usec,MAX_OPHIR,OutRS232A[4],OutRS232B[4],port8,port9,1); ascii_io(port[6],port6,port6_fp,heading,&heading_index,&heading_sec,&heading_usec,MAX_HEADING,OutRS232A[6],OutRS232B[6],port8,port9,1); ascii_io(port[7],port7,port7_fp,gps,&gps_index,&gps_sec,&gps_usec,MAX_GPS,OutRS232A[7],OutRS232B[7],port8,port9,1); /* close all data output files */ fclose(port0_fp); fclose(port1_fp); fclose(port2_fp); fclose(port3_fp); fclose(port4_fp); fclose(port5_fp); fclose(port6_fp); fclose(port7_fp); goto Start; /* loop back to Start: (hourly loop) */ exit(EXIT_SUCCESS); /* exit program */ } /***************************************************************************/ /* function get_time (acquires seconds and microseconds from OS) */ /***************************************************************************/ void get_time(t_usec,t_sec) long *t_usec; unsigned long *t_sec; { struct timeval clock; struct timezone zone; gettimeofday(&clock,&zone); /* get time from OS */ *t_usec=clock.tv_usec/100; /* assign microseconds/100 */ *t_sec=clock.tv_sec; /* assign seconds */ } /***************************************************************************/ /* function motion_io (acquire ship motion data) */ /***************************************************************************/ int motion_io(port,fp_motion,fp_file,RS232A,RS232B,fp_rs232a,fp_rs232b) int port,RS232A,RS232B; FILE *fp_motion,*fp_file,*fp_rs232a,*fp_rs232b; { static unsigned char bytes[MOTION_BYTES]; short int motion_int[MOTION_FIELDS]; int bytes_read=0,start_byte=2,i=0; static int index=0; float motion_flt[MOTION_FIELDS],motion_convert(); static long char_usec[MOTION_BYTES]; static unsigned long char_sec[MOTION_BYTES]; fd_set rfd; struct timeval timeout; for(i=0;iindex-1 to old bytes 2-index... */ { bytes[i]=bytes[i+1]; char_usec[i]=char_usec[i+1]; char_sec[i]=char_sec[i+1]; } index--; /* set byte index to index-1 */ } } for(i=0;iindex-1 to old bytes 2-index... */ { bytes[i]=bytes[i+1]; char_usec[i]=char_usec[i+1]; char_sec[i]=char_sec[i+1]; } index--; /* set byte index to index-1 */ } } for(i=0;iindex-1 to old bytes 2-index... */ { bytes[i]=bytes[i+1]; char_usec[i]=char_usec[i+1]; char_sec[i]=char_sec[i+1]; } index--; /* set byte index to index-1 */ } } for(i=0;i<5;i++) proc_data[i]=9999; /* set all array elements to 9999 */ timeout.tv_sec=0; /* set select timeout seconds */ timeout.tv_usec=10; /* set select timeout micros */ FD_ZERO(&rfd); /* zero out the read bitmask */ FD_SET(port,&rfd); /* copy the passed port mask to the read mask */ /* search all file descriptors for reading status... */ if(select(NTTYS+11,&rfd,0,0,&timeout)<=0) return(bytes_read); } while(FD_ISSET(port,&rfd)); /* ...while passed port is ready for reading */ return(bytes_read); /* return the number of bytes read to the calling function */ } /******************************************************************************/ /* function ascii_io (acquire Mean Met, Ship Heading and GPS data) */ /******************************************************************************/ int ascii_io(port,fp_ascii,fp_file,bytes,index,sec,usec,maxch,RS232A,RS232B,fp_rs232a,fp_rs232b,dump) int port,RS232A,RS232B; FILE *fp_ascii,*fp_file,*fp_rs232a,*fp_rs232b; char *bytes; int *index; long *usec; unsigned long *sec; int maxch,dump; { char ch; int bytes_read=0; fd_set rfd; struct timeval timeout; switch(dump) { case 0: /* normal acquisition mode */ { do { ch=(char)getc(fp_ascii); /* get and store char from buffer */ if((ch!='\r')&&(ch!='\n')) /* if not CR or LF... */ { bytes[(*index)++]=ch; /* store char and step index */ bytes_read++; /* step the number of bytes read */ } if(*index==1) get_time(usec,sec); /* if 1st char has been read store time */ if(*index >= maxch) /* if the number of characters stored is >= maxchar... */ { bytes[*index]='\0'; /* NUL terminate string */ /* output time and data strings to data output file and RS232 ports */ if(fprintf(fp_file,"%d,%d,%s\n", *sec,*usec,bytes)<1) printf("ascii_io error: file output failure\n"); if(RS232A) { if(fprintf(fp_rs232a,"%d,%d,%s\r\n", *sec,*usec,bytes)<1) printf("ascii_io error: RS232(a) output failure\n"); } if(RS232B) { if(fprintf(fp_rs232b,"%d,%d,%s\r\n", *sec,*usec,bytes)<1) printf("ascii_io error: RS232(b) output failure\n"); } *index=0; /* set array counter to zero */ } else { if((ch=='\n')&&(*index)) /* if char equals newline and index is not zero */ { bytes[*index]='\0'; /* NUL terminate string */ /* output time and data strings to data output file and RS232 ports */ if(fprintf(fp_file,"%d,%d,%s\n", *sec,*usec,bytes)<1) printf("ascii_io error: file output failure\n"); if(RS232A) { if(fprintf(fp_rs232a,"%d,%d,%s\r\n", *sec,*usec,bytes)<1) printf("ascii_io error: RS232(a) output failure\n"); } if(RS232B) { if(fprintf(fp_rs232b,"%d,%d,%s\r\n", *sec,*usec,bytes)<1) printf("ascii_io error: RS232(b) output failure\n"); } *index=0; /* set array counter to zero */ } } timeout.tv_sec=0; /* set select timeout seconds */ timeout.tv_usec=10; /* set select timeout micros */ FD_ZERO(&rfd); /* zero out the read bitmask */ FD_SET(port,&rfd); /* copy the passed port mask to the read mask */ /* examine all file descriptors for reading status... */ if(select(NTTYS+11,&rfd,0,0,&timeout)<=0) return(bytes_read); } while(FD_ISSET(port,&rfd)); /* ...while passed port is ready for reading */ break; } case 1: /* end of hour mode (output incomplete strings) */ { bytes[*index]='\0'; /* NUL terminate string */ /* output time and data strings to data output file and RS232 ports */ if(fprintf(fp_file,"%d,%d,%s\n", *sec,*usec,bytes)<1) printf("ascii_io error: file output failure\n"); if(RS232A) { if(fprintf(fp_rs232a,"%d,%d,%s\r\n", *sec,*usec,bytes)<1) printf("ascii_io error: RS232(a) output failure\n"); } if(RS232B) { if(fprintf(fp_rs232b,"%d,%d,%s\r\n", *sec,*usec,bytes)<1) printf("ascii_io error: RS232(b) output failure\n"); } *index=0; /* set array counter to zero */ } } return(bytes_read); /* return the number of bytes read to calling function */ } /***************************************************************************/ /* function gyro (acquires gyro-compass data) */ /***************************************************************************/ int gyro(port,fp_gyro,fp_file,RS232A,RS232B,fp_rs232a,fp_rs232b) int port,RS232A,RS232B; FILE *fp_gyro,*fp_file,*fp_rs232a,*fp_rs232b; { static char gyro_data[4]; int i=0,j=0,out_of_order=0,bytes_read=0; static int index=0; static long char_usec[4]; static unsigned long char_sec[4],out_sec=0; float gyro_heading=0.; fd_set rfd; struct timeval timeout; do { gyro_data[index]=(char)getc(fp_gyro); /* get and store char from buffer */ bytes_read++; /* accumulate the number of bytes read */ get_time(&char_usec[index],&char_sec[index]); /* store time for each read char */ index++; /* step number of characters read */ if(index==4) /* if four characters have been read */ { for(i=0;i=out_sec) /* if data is 1 second later */ { gyro_heading=gyro_heading-120; /* subtract 120 from total heading */ if(gyro_heading <0.0)gyro_heading=gyro_heading+360.0; /* add 360 if negative */ /* output time and heading to data output file and RS232 ports */ if(fprintf(fp_file,"%d,%d,%3.2f\n",char_sec[0],char_usec[0],gyro_heading)<1) printf("gyro error: file output failure\n"); if(RS232A) { if(fprintf(fp_rs232a,"%d,%d,%3.2f\r\n",char_sec[0],char_usec[0],gyro_heading)<1) printf("gyro error: RS232(a) output failure\n"); } if(RS232B) { if(fprintf(fp_rs232b,"%d,%d,%3.2f\r\n",char_sec[0],char_usec[0],gyro_heading)<1) printf("gyro error: RS232(b) output failure\n"); } out_sec=char_sec[0]+1; /* step to new second */ } index=0; /* reset byte counter */ break; } default: /* ... out of order ... */ { for(j=0;jindex-1 to old bytes 2-index...*/ { gyro_data[j]=gyro_data[j+1]; char_usec[j]=char_usec[j+1]; char_sec[j]=char_sec[j+1]; } index--; /* set byte to index-1 */ } } gyro_heading=0.;out_of_order=0; /* reset variables */ } timeout.tv_sec=0; /* set select timeout seconds */ timeout.tv_usec=10; /* set select timeout micros */ FD_ZERO(&rfd); /* zero out the read bitmask */ FD_SET(port,&rfd); /* copy the passed port mask to the read mask */ /* search all file descriptors for reading status... */ if(select(NTTYS+11,&rfd,0,0,&timeout)<=0) return(bytes_read); } while(FD_ISSET(port,&rfd)); /* ...while passed port is ready for reading */ return(bytes_read); /* return the number of bytes read to the calling function */ } /***************************************************************************/ /* function key_quit (exits acquisition program) */ /***************************************************************************/ void key_quit() { /* notify user of program exit */ printf("\n\nHP data acquisition program is now stopping\n"); printf("Please put your seats and tray-tables to their full upright position\n\n\n"); fflush(NULL); /* flush all flie streams */ exit(0); /* exit function */ }