/* FOR SENSOR S/N 217 THIS PROGRAM WAS MODIFIED TO WORK WITH THE LAMONT-BUILT BUFFER. NEAR END OF CODE THE SCALE FACTOR IS MULTIPLIED BY 4 ADDITIONAL CHANGES MADE TO INCREASE THE NUMBER OF FILES (INCREMENTAL FILE NUMBERING) TO 9999.... ALSO CHANGED MAX FILE SIXE TO 110000 BYTES... AND ELIMINATED NEW FILE START AT MIDNIGHTS... R. E. HERR 01FEB2001 From stennett@ewing.ldgo.columbia.edu Tue Aug 15 17:36:42 1995 Received: from otter.ldgo.columbia.edu (otter-gate.ldgo.columbia.edu) by lamont.ldgo.columbia.edu (4.1/SMI-3.2) id AA05176; Tue, 15 Aug 95 17:36:35 EDT Received: by otter.ldgo.columbia.edu (4.1/SHORE-1.0) id AA01542; Tue, 15 Aug 95 17:36:33 EDT Return-Path: Received: from squid.noname by shark.ldgo.columbia.edu (4.1/SHIP-1.0) id AA23757; Tue, 15 Aug 95 12:26:37 GMT Date: Tue, 15 Aug 95 12:26:37 GMT From: stennett@ewing.ldgo.columbia.edu (Joe Stennett) Message-Id: <9508151226.AA23757@shark.ldgo.columbia.edu> To: bjc@lamont.ldgo.columbia.edu Subject: gravity logger Status: R Hi Bernie, You bet I still have your program. It works better than most of the stuff on this tub. Here it comes. Regards joe 15aug95 */ /* Gets data from Joe Stennetts pretty good BGM-3 serial interface using and interupt service routine and puts it on the tube. HISTORY: GPSREAL.C Dale Chayes 14 Nov 1984 Hudson84-0046 SM8408 which was from: DeSmet's DUMBTERM.C */ /*this program modified 22 Sept 1990. The gravity bias cannot be changed while the program is running. Also the gravity flag cannot be turned off. jope stennett */ #include "stdio.h" #include "math.h" #include "test_log.h" char brcv_err, boverflow; char print_buffer[BUFFER_SIZE]; /* log file output buffer */ /* structure for character buffer of gravity meter output. Individual structures are linked in a ring */ struct BUFF { char c; struct BUFF *next; }; struct BUFF *wbufhead; /* pointer to the begining of the unread portion of the gravity buffer */ struct BUFF *wbuftail; /* pointer to the end of the unread portion of the gravity buffer */ int i = 0; /* set when new line is ready */ long int loop = 0; /* how many times have we output to screen */ long int buff = 0; /* how many complete reads of the gravity buffer */ int month,year; /* month number (1-12), years AD */ unsigned int plot_flag = FALSE; /* screen plotting flag */ unsigned int grav_flag = FALSE; /* gravity input flag */ unsigned int log_flag = FALSE; /* logging on flag */ unsigned int go_go_go = FALSE; /* while TRUE do */ unsigned int erron = FALSE; /* command line arg error flag */ unsigned int gravity_ready = FALSE; /* gravity value available for output and anomaly calculation */ long int real_time,new,start; /* system time current, begin */ int file_number =0; /* log file number strcat'd to root name */ int header_size = 0; /* size of file header */ int grav_out_length = 25; /* number of bytes of gravity output */ int sample_length = 1; /* filter length, 1 - means no filtering */ int half_sample = 0; /* (sample_length - 1)/2 */ int delta_T; /* time offset between plotted gravity values */ int grav_size; /* sizeof(struct GRAV) */ int buff_size; /* sizeof(struct BUFF) */ int bell_count; /* number of bell rings executed to call attention to error condition on meter */ long int go_count = 0; /* number of times the while loop executes per output cycle */ long int buffer_count = 0; /* current output buffer size */ double file_size = 0.0; /* current file size */ double hold_bias,g_bias = 855291.40; /*02FEB01 for s/n 217REHERR*/ /*ch. fr. 855758.1 7/14/92*/ long int del_t = 1; /* time between meter outputs */ /*double g_scale = 4.951639; scale from counts to acceleration gravity = counts * g_scale + g_bias */ double g_scale = 4.997044; /*19APR2000 for s/n 217*/ double gaussian[MAX_FILTER_LENGTH]; /* array containing gaussian filter coefficients from gaussian[0] to gaussian[half_sample] */ char file_name[30]; /* root filename for logging output */ char status_string[81]; /* output string for header and screen display*/ struct GRAV *active; /* pointer to current anomaly being calculated, the central value of the filter */ int kount; int plot_delta_T = 0; double delta_mgal = 0.0; main( argc, argv) int argc; char **argv; { int i,k; /* command line args, four flags, file rootname, and base reference (if not supplied = 0) */ for (i = 1; i < argc; i++) { /* Loop over input arguments */ if (argv[i][0] == '-') { switch (argv[i][1]) { case 'G': case 'g': grav_flag = TRUE; /* gravity input on */ hold_bias = atof(&argv[i][2]); if(hold_bias > 0.0) /* if bias provided, take it */ /* g_bias = hold_bias; */ break; case 'P': case 'p': plot_flag = TRUE; /* plotting on */ for(k = 2; argv[i][k] && argv[i][k] != '/'; k++); if(argv[i][k] == '/') /* time between plot refresh */ plot_delta_T = atoi(&argv[i][k+1]); argv[i][k] = '\0'; delta_mgal = (double)atoi(&argv[i][2]); break; case 'F': case 'f': /* get filter length in number of delta_T increments */ sample_length = atoi(&argv[i][2]); if(sample_length >= MAX_FILTER_LENGTH || sample_length < 3) erron = TRUE; break; case 'L': case 'l': log_flag = TRUE; /* logging on, get file name */ strcpy(file_name,&argv[i][2]); if(strlen(file_name) > 4) erron = TRUE; break; default: erron = TRUE; /* if non-options requested */ break; } } } /* if plot parameters are not provided, assign default values */ if(!plot_delta_T) plot_delta_T = (int)(sample_length/2) + 1; if(!delta_mgal) delta_mgal = (double)(ROWS - 2); if(!grav_flag) erron = TRUE; /* why do you want to run it then */ if(erron) { /* a little education */ fprintf(stderr, "usage: log_grav -g -p\n -b -f -l\n"); fprintf(stderr, " -g gravity input is expected, bias is in mgals.\n"); fprintf(stderr, " -p initiates plotting\n"); fprintf(stderr, " -f specifies gaussian filtering, with integer filter length.\n"); fprintf(stderr, " -l turns on logging and uses given name for output file.\n"); fprintf(stderr, " (root filename must be 6 characters or less.) \n"); exit(-1); } grav_size = sizeof( struct GRAV ); buff_size = sizeof( struct BUFF ); initialize_input(file_name); /* based on initial flags start the ball rolling */ go_go_go = TRUE; /* don't stop until your told */ /* run while go_go_go is TRUE or until the gravity buffer is completely read */ while(go_go_go || wbuftail != wbufhead) { go_count++; /* number of loop passes per output */ if(grav_flag && gravity_buffer_check()) { /* if gravity on and buffer read complete */ get_grav(begin_g); /* break down read buffer and add to chain of gravity values */ real_time += begin_g->end_count_time; begin_g->end_count_time = time_get(); /* todays time, which may conflict with the buffer time, causing offsets */ reduce_gravity(); /* produce filtered gravity, write to output buffer */ if(real_time/DAY_LENGTH_SEC >= 1.0) { buff -= DAY_LENGTH_SEC; /* decrement number of buffer reads */ real_time -= DAY_LENGTH_SEC; /* reset accumulated buffer time */ } if(log_flag) { /* logging on ? */ /* if((active->end_count_time+del_t) >= DAY_LENGTH_SEC) {*/ /* if TRUE new day has dawned */ /* clear buffer and open new file for new day */ /* file_size += (double)log_data(file_name,print_buffer,buffer_count); open_new_file(file_name); file_size = 0.0; } */ if(buffer_count + grav_out_length > BUFFER_SIZE) { /* if next increment to buffer will extend beyond the buffer end */ file_size += (double)log_data(file_name,print_buffer,buffer_count); if(file_size + (double)BUFFER_SIZE > FILE_SIZE) { /* if we are about to extend beyond desired file size limit */ open_new_file(file_name); file_size = 0.0; } } if(plot_flag) { plot_data(); /* picture this */ write_status_string(); print_message(1,ROWS-1,status_string); print_message(2+strlen(status_string),ROWS-1,begin_g->raw_grav); } else /* output to screen */ printf("\n%ld %d %ld %ld %ld", begin_g->counts,begin_g->flag, begin_g->end_count_time-start,buff,go_count); go_count = 0; /* reset while loop execution counter */ active->gravity = 0.0; /* reset gravity for next time */ active = active->next; /* increment central filter pointer */ end_g = end_g->next; /* advance pointer to new end-of-filter */ begin_g = begin_g->next; /* advance pointer to position for new read */ } } get_screen_input(); /* what now? */ } /* if done (go_go_go = FALSE) clean up and go write all values following the central filter value, indicated by the pointer active, in the GRAV structure chain */ if(log_flag) off_log(file_name); if(grav_flag) off_grav(); if(plot_flag) off_plot(); } int gravity_buffer_check() { static int i; /* position in string buffer */ int flag = FALSE; /* return status */ char c = '\0'; /* next character */ /* if something in buffer -- get 1st character & fix pointers */ while(wbufhead != wbuftail /* don't over read the begining */ && (c = wbufhead->c) /* assign the new character */ && (wbufhead = wbufhead->next) /* advance the buffer pointer */ && c != '\r') { /* if true, read completed */ if(c != '\n') /* if true, new read begins */ begin_g->raw_grav[i++] = c; /* put new character in array */ } if(c == '\r') { begin_g->raw_grav[i] = '\0'; /* complete string */ i = 0; /* reset counter */ flag = TRUE; /* ready to go, execute main loop */ buff += del_t; /* new read complete */ } if(brcv_err) /* test RS232 receive status; display errors */ { printf("", brcv_err); brcv_err = 0; } if(boverflow) { puts(""); boverflow = 0; } return(flag); /* return flag, execute main loop */ } void ISR() { static struct BUFF *next; static char err; /* get error bits */ if(err = (_inb(LSR) & 0x1E)) brcv_err = err; /* get incoming character and buffer it */ if((next = wbuftail->next) != wbufhead) /* save next pointer */ { wbuftail->c = _inb(RBR); /* assign new character to buffer */ wbuftail = next; /* advance pointer after read */ } else boverflow++; /* signal end of interrupt to 8259 */ #asm cli # _outb(0x20, 0x20); /* return to interrupt handler */ } /* clear out the interupt stuff */ void cleanup() { /* disable IRQ4 on 8259 */ #asm cli # _outb((_inb(0x21) | 0x10), 0x21); /* disable 8250 data ready interrupt */ _outb((_inb(LCR) & 0x7F), LCR); _outb(0, IER); /* disable OUT2 on 8250 */ _outb(0, MCR); #asm sti # /* display bye-bye */ print_message(40,19,"---OFFLINE---"); } /* initialize RS232 */ void rs232_init(port, parm) int port; char parm; { #asm mov dx,[bp+4] ; port mov al,byte [bp+6] ; parm mov ah,0 ; initialize int 14H ; RS232_IO # } /* RS232 write */ void rs232_out(port, data) int port; char data; { #asm ;CAUTION: hard coded for COM1! MCR equ 3FCH ; modem control reg MSR equ 3FEH ; modem status reg LSR equ 3FDH ; line status reg THR equ 3F8H ; xmit holding reg ; the following lines are commented because I don't have a modem. ; if you do, remove the comments. ; mov dx,MCR ; modem control reg ; mov al,0BH ; OUT2, DTR, RTS ; out dx,al ; sub cx,cx ; timeout count ; mov dx,MSR ; modem status reg ; --- wait for DSR rs100: ; in al,dx ; test al,20H ; data set ready? ; jnz rs150 ; yes ; loop rs100 ; no, retry until time-out ; mov ah,80H ; set time-out ; jmp rsxit ; and quit ; --- wait for CTS rs150: ; sub cx,cx ; another timeout count rs200: ; in al,dx ; test al,10H ; clear to send? ; jnz rs250 ; yes ; loop rs200 ; no, retry until time-out ; mov ah,80H ; set time-out ; jmp rsxit ; and quit ; --- wait for THRE rs250: mov dx,LSR ; line status register sub cx,cx ; yet another timeout count rs300: in al,dx ; lsr status test al,20H ; xmit holding reg empty? jnz rs350 ; yes loop rs300 ; no, retry until time-out mov ah,80H ; set time-out jmp rsxit ; and quit ; --- get line status, send char rs350: mov ah,al ; get line status for return and ah,7FH ; clear time-out bit mov al,byte [bp+6] ; get data byte mov dx,THR ; xmit holding reg out dx,al ; RS232_IO rsxit: # } /* interrupt handler */ void set_int(n, addr, stack) int n, addr, stack; { #asm ; ---- save ds interrupt routine and local stack address mov cs:dsreg,ds mov ax,[bp+6] mov cs:iaddr,ax mov ax,[bp+8] mov cs:saddr,ax ; ---- set up interrupt vector cli ; interrupts off during setup mov dx,offset irtn mov ax,cs mov ds,ax ; DS:DX points to interrupt handler mov ax,[bp+4] ; interrupt number mov ah,25H ; DOS ivec routine int 21H ; call DOS mov ds,cs:dsreg ; restore ds ; ---- return pop bp ret ; ---- interrupt handler data dsreg: dw 0 iaddr: dw 0 saddr: dw 0 savds: dw 0 savss: dw 0 savsp: dw 0 ; ---- interrupt handler irtn: ; ---- save interrupted environment mov cs:savds,ds mov cs:savss,ss mov cs:savsp,sp ; ---- restore C environment mov ds,cs:dsreg mov ss,cs:dsreg mov sp,cs:saddr sti ; allow other interrupts ; ---- save registers push ax push bx push cx push dx push di push si push es ; C will save and restore bp call cs:iaddr ; call interrupt routine ; ---- return from interrupt routine cli ; no interrupts during restore ; ---- restore registers pop es pop si pop di pop dx pop cx pop bx pop ax ; ---- restore interrupted state mov ds,cs:savds mov ss,cs:savss mov sp,cs:savsp iret # } void clear_interupt() { #asm /* this makes inline assembler code */ cli # } int initialize_input(file_name) char *file_name; { int k; CLR_SCRN; /* clear screen*/ wbufhead = wbuftail = (struct BUFF *)malloc(buff_size); /* set up circular buffer of characters read from the BGM-3 output buffer */ k = 0; while(k < BUFSIZE) { /* create new structures up to BUFSIZE */ wbuftail->next = (struct BUFF *)malloc(buff_size); wbuftail = wbuftail->next; /* link to the chain */ ++k; } wbuftail->next = wbufhead; /* close the chain */ wbufhead = wbuftail; /* start together; wbufhead is advanced by reading the BGM-3 output buffer; wbuftail is advanced by writing to the character string; begin_g->raw_grav[i++] */ if(sample_length > 1) /* calculate filter coefficients */ calculate_filter_coefficients(); else gaussian[0] = 1.0; /* if log flag, open output file */ if(log_flag) log_flag = on_log(file_name); /* if grav flag, open grav channel */ if(grav_flag) grav_flag = on_grav(); /* if plot flag, begin plotting */ if(plot_flag) plot_flag = on_plot(); } int get_screen_input() { static char c[LINE_LENGTH+1]; static int count; /* read until end of line, return on line or max command size */ while(csts() && (*(c+count) = ci()) && !isspace(*(c+count)) && count <= LINE_LENGTH) { if(*(c+count) == ESC) { go_go_go = 0; return(FALSE); } CUR_MV(count+1,1); co(*(c+count)); count++; } if(isspace(*(c+count))) { /* if control character passed, string end */ *(c+count) = '\0'; /* add NULL character, make it a string */ count = 0; /* reset counter */ return(do_commands(c)); /* do something about it */ } if(count >= LINE_LENGTH) { /* error time, keep your hands off the keys */ count = 0; command_error_message(c); } return(FALSE); /* no complete string, nothing done yet */ } int do_commands(string) char *string; { int kount = 0; struct PLOT *hold; double delta,gravit; /* if command recognized, change or display current state */ if(!strcmp(string,"clear")) { /* clear display, reset bell counter */ bell_count = 0; CLR_SCRN; } /*else if(!strncmp(string,"gravity",7)) { if(!grav_flag) { turn grav on or off, get new bias if(*(string+7) == '-') g_bias = atof((char*)(string+8)); grav_flag = on_grav(); } else grav_flag = off_grav(); } */ else if(!strcmp(string,"plot")) { if(!plot_flag) /* turn plot on or off */ plot_flag = on_plot(); else plot_flag = off_plot(); } else if(!strncmp(string,"rescale",7)) { if(*(string+7) == '-') { /* rescale screen */ delta = delta_mgal; kount = 8; /* calculate new scale parameters */ while(*(string+kount) != '/'&& kount < LINE_LENGTH+1) ++kount; if(kount <= LINE_LENGTH) { *(string+kount) = '\0'; delta_mgal = (double)atoi((char*)(string+8)); ++kount; plot_delta_T = atoi((char*)(string+kount)); hold = first_point; /* rescale plotted values */ do { hold->wrap = (double)floor(hold->grav/delta_mgal); hold->row = (int)((ROWS - 2) * (1.0 - (hold->grav/delta_mgal - hold->wrap))); hold = hold->next; } while(hold != last_point); CLR_SCRN; } else command_error_message(string); } } else if(!strncmp(string,"log",3)) { if(!log_flag) { /* turn logging on or off */ if(*(string+3) == '-') { file_number = 0; /* get new file name */ strcpy(file_name,(char*)(string+4)); } log_flag = on_log(file_name); } else log_flag = off_log(file_name); } else if(!strcmp(string,"kill")) /* stop, done */ go_go_go = FALSE; else { command_error_message(string); return(FALSE); } if(!grav_flag) /* shut it down */ go_go_go = FALSE; return(TRUE); } long int log_data(file_name,buffer,buffer_size) char *file_name; char *buffer; long int buffer_size; { long int number_bytes; int file; /* open file */ file = fopen(file_name,"a"); /* write buffer */ number_bytes = (long int)write(file,buffer,(unsigned int)(buffer_size)); /* close file */ close(file); /* clear buffer */ *buffer = '\0'; buffer_count = 0; /* return length of written data */ return(number_bytes); } int on_grav(){ int test = 0; int i,count; struct GRAV *hold; bell_count = 0; /* sets up the serial port (baud rate and junk) establishes the interupt service routine */ /* initialize RS232: 9600,8,N,1 */ rs232_init(COM1, B9600 | DATA8 | NO_PARITY | STOP1); #asm cli # /* set up INT x'0C' for IRQ4 this is COM1 */ set_int(0x0C, ISR, salloc(512)); /* clear xmit/rcv bufs & line status */ /* enable IRQ4 on 8259 interrupt controller */ _outb((_inb(0x21) & 0xEF), 0x21); /* enable 8250 (the UART) data ready interrupt */ _outb((_inb(LCR) & 0x7F), LCR); /* reset "DLAB" for IER access */ _outb(1, IER); /* enable "data ready" interrupt */ /* enable OUT2 on 8250 */ _outb(0x0B, MCR); #asm sti # /* initialize GRAV structure chain */ hold = active = begin_g = end_g = &grav_1; active->num = begin_g->num = end_g->num = -1; /* allocate GRAV structures until we have a chain of length sample_length + 1 */ for(i = 0; i < sample_length; ++i) { active = (struct GRAV *)malloc(grav_size); active->num = i; active->gravity = 0.0; active->counts = 0; end_g->next = active; end_g = end_g->next; } end_g->next = begin_g; /* close loop */ end_g = begin_g->next; /* begin_g points to new value read */ begin_g = end_g; /* end_g points to the last value in the filter */ /* force buffer read until buffer is clear */ while(!gravity_buffer_check()); loop = buff = i = 0; begin_g->end_count_time = real_time = start = buff = time_get(); i = 0; do { /* force buffer read */ do { test = gravity_buffer_check(); ++go_count; } while(!test); test = FALSE; /* break input down into counts, count time and flags */ sscanf(begin_g->raw_grav,"%2ld:%6ld %2d", &(begin_g->end_count_time), &(begin_g->counts),&(begin_g->flag)); if(begin_g->end_count_time != del_t) { buff += begin_g->end_count_time - del_t; del_t = begin_g->end_count_time; } real_time += begin_g->end_count_time; begin_g->end_count_time = time_get(); /* test on flags */ if(begin_g->flag) read_grav_flag(begin_g); /* write to output string*/ if(log_flag && i < half_sample) { sprintf((char*)(print_buffer),"%6ld%2d%6ld %9.1f\n", begin_g->counts,begin_g->flag,begin_g->end_count_time, begin_g->gravity); file_size += (double)log_data(file_name,print_buffer,grav_out_length); hold = begin_g; ++i; } printf("\n%ld %d %ld %ld %ld %ld %ld", begin_g->counts,begin_g->flag, begin_g->end_count_time,buff,++loop,real_time,go_count); go_count = 0; begin_g = begin_g->next; } while(begin_g != active); /* fill filter buffer until next read will complete filter length */ active = hold->next; /* set filter mid-point */ g_scale =(g_scale/(double)del_t)*4; /*fix done 8/22/95 by reh (*4 then removed 7/25/97 for utig buffer AND ADDED AGAIN FOR THE LAMONT BUFFER*/ print_message(40,22,"---gravity ONLINE---"); return(TRUE); } int off_grav(){ struct GRAV *hold1,*hold2; /* disable IRQ4 on 8259 */ #asm cli # _outb((_inb(0x21) | 0x10), 0x21); /* disable 8250 data ready interrupt */ _outb((_inb(LCR) & 0x7F), LCR); _outb(0, IER); /* disable OUT2 on 8250 */ _outb(0, MCR); #asm sti # /* clear memory, clear pointers, display bye-bye */ end_g = begin_g->next; begin_g->next = NULL; while(end_g) { begin_g = end_g->next; free(end_g); end_g = begin_g; } active = NULL; g_scale *= (double)del_t; print_message(40,22,"---gravity OFFLINE ---"); return(FALSE); } int on_log(file_name) char *file_name; { /* clear buffer, open file */ *print_buffer = '\0'; if(*file_name != '\0') { open_new_file(file_name); print_message(40,21,"---logging ON---\n"); return(TRUE); } return(FALSE); } int off_log(file_name) char *file_name; { int reference,i; struct GRAV *hold; /* clear buffer */ file_size += (double)log_data(file_name,print_buffer,buffer_count); i = 0; while(i < half_sample) { /* print remaining filter half-width */ sprintf((char*)(print_buffer),"%6ld%2d%6ld %9.1f\n", active->counts,active->flag,active->end_count_time, active->gravity); buffer_count = grav_out_length; /* log these values */ file_size += (double)log_data(file_name,print_buffer,buffer_count); if(!plot_flag) printf("\n%ld %d %ld %ld %ld %ld %ld", active->counts,active->flag, active->end_count_time-start,buff,++loop,real_time,go_count); ++i; active = active->next; } write_header(file_name); print_message(40,21,"---logging OFF---"); return(FALSE); } int on_plot() { int plot_sz,i; CLR_SCRN; /* clear screen */ plot_sz = sizeof( struct PLOT ); /* set-up plot structure chain */ last_point = first_point; first_point->wrap = 0; first_point->row = 0; first_point->time = 0; for(i = 0; i < COLUMNS; ++i) { /* one structure for each screen column */ last_point->next = (struct PLOT*)malloc(plot_sz); last_point = last_point->next; last_point->wrap = 0; last_point->row = 0; last_point->time = 0; } last_point->next = first_point; return(TRUE); } int off_plot(){ struct PLOT *hold; struct PLOT *save; hold = first_point->next; /* clear memory */ while(hold) { save = hold->next; free(hold); hold = save; } print_message(40,20,"---plotting OFF---"); return(FALSE); } int read_grav_flag(gravity) struct GRAV *gravity; { /* read gravity flag, print message, hit bell */ if(!gravity->flag) return(FALSE); if(gravity->flag == 1) print_message(1,1,"Platform data not valid."); else if(gravity->flag == 2) print_message(1,1,"Sensor data not valid."); else if(gravity->flag == 3) print_message(1,1,"Platform and sensor not valid."); else print_message(1,1,"Unknown meter flag encountered."); if(bell_count++ < BELL_RINGS) BELL; return(TRUE); } struct GRAV *get_grav(new_grav) struct GRAV *new_grav; { int i; /* break input down into counts, count time and flags */ sscanf(new_grav->raw_grav,"%2ld:%6ld %2d", &(new_grav->end_count_time), &(new_grav->counts),&(new_grav->flag)); /* test on flags */ if(new_grav->flag) read_grav_flag(new_grav); return(new_grav); } int reduce_gravity() { static struct GRAV *left,*right; static int kount; /* calculate raw gravity, converting counts into mgals */ left = end_g; right = active->next; active->gravity = (double)(active->counts) * gaussian[0]; for(kount = 1; kount <= half_sample; ++kount) { active->gravity += (double)(right->counts) * gaussian[kount]; active->gravity += (double)(left->counts) * gaussian[half_sample-kount+1]; left = left->next; right = right->next; } active->gravity *= g_scale; active->gravity += g_bias; if(log_flag) { sprintf((char*)(print_buffer+buffer_count),"%6ld%2d%6ld %9.1f\n", active->counts,active->flag,active->end_count_time, active->gravity); buffer_count += grav_out_length; } return(TRUE); } void command_error_message(string) char *string; { CUR_MV(5,5); printf("\n %s - bad command, options are:\n",string); /* printf("\n gravity-bias\n"); */ printf(" log-filename\n"); printf(" rescale-delta mgal\delta T\n"); printf(" plot\n"); printf(" kill or clear\n"); } void plot_data() { static char string[80]; sprintf(string,"sys %6ld sum %6ld buf %6ld file %8.0f go %5ld out %10.2f", begin_g->end_count_time,real_time,buff,file_size,go_count,active->gravity); print_message(COLUMNS-strlen(string),ROWS,string); if(((active->end_count_time - start)% plot_delta_T) ) return; struct PLOT *move; int current_x = 1; int move_y; first_point = first_point->next; first_point->time = active->end_count_time; first_point->grav = active->gravity; first_point->wrap = (double)floor(active->gravity/delta_mgal); first_point->row = (int)((ROWS - 2) * (1.0 - (active->gravity/delta_mgal - first_point->wrap))) + 1; /* print active max and min milli-gal values on screen */ sprintf(string," %9.1f",first_point->wrap * delta_mgal); print_message(COLUMNS-strlen(string),ROWS-1,string); sprintf(string," %9.1f",(first_point->wrap+1) * delta_mgal); print_message(COLUMNS-strlen(string),1,string); move = first_point->next; do { /* plot only if different than what is being erased */ if(move->next->row != move->row && move->row > 0) { CUR_MV(current_x,move->row); putchar(' '); CUR_MV(current_x,move->next->row); putchar('*'); } ++current_x; move = move->next; } while( current_x <= COLUMNS ); return; } void open_new_file(string) char *string; { int file_reference; static int length; char append[10]; char filter[80]; /* write tail of old file */ if(file_number > 0) write_header(string); else { if(*(file_name) == '\0') strcpy(file_name,"output"); length = strlen(string); } *(string + length) = '\0'; /* add new number */ sprintf(append,"%0*d.%0*d",4,file_number,3,date_get()); strcat(string,append); /* create new file, it is returned closed, all routines that write will open it */ close(creat(string)); /* write header */ write_header(string); /* write out filter coefficients */ /*if(sample_length > 1) { sprintf((char*)(filter), "filter coefficients -\n"); file_size += (double)log_data(file_name,filter,strlen(filter)); for(i = 0; i <= half_sample; ++i) { sprintf((char*)(filter+strlen(filter))," %8.6f",gaussian[i]); if(!((i+1) % 8)) { sprintf((char*)(filter+strlen(filter)),"\n"); file_size += (double)log_data(file_name,filter,strlen(filter)); } } sprintf((char*)(filter+strlen(filter)),"\n\n"); file_size += (double)log_data(file_name,filter,strlen(filter)); } */ file_number++; /* for next time */ return; } void print_message(x,y,message) int x,y; char *message; { CUR_MV(x,y); /* move cursor to col x, row y */ fputs(message,stderr); /* print message */ } long int time_get() { static char buff[10]; long int h,m,s; /* get system time and break string down in hours, minutes and seconds */ times(buff); sscanf(buff,"%2ld:%2ld:%2ld",&h,&m,&s); return((((h * 60) + m) * 60 + s)); } void write_header(name) char *name; { int reference; char string[80]; header_size = 0; /* poll program about current status of flags and constants */ write_header_string(string); /* open file */ reference = fopen(name,"a"); /* dump header buffers, string, status_string */ header_size += write(reference,string,(unsigned int)strlen(string)); file_size += (double)header_size; close(reference); } int date_get() { static char buff[12]; int day; /* get system date, break down into day, month and year */ dates(buff); sscanf(buff,"%2d-%2d-%4d",&month,&day,&year); /* year += CENTURY; */ return(day_of_year(month,day,year)); } int day_of_year(month,day,year) int month,day,year; { int i,d,leap; static int day_tab[2][13] = { { 0,31,28,31,30,31,30,31,31,30,31,30,31 }, { 0,31,29,31,30,31,30,31,31,30,31,30,31 } }; /* calculate the numerical date since january 1, inclusive */ d = day; leap = year % 4 == 0 && year % 100 != 0 || year % 400 == 0; for(i = 1; i < month; i++) d += day_tab[leap][i]; return(d); } void write_status_string() { char buffer[10]; times(buffer); sprintf(status_string,"time %8s g %9.2f l %s p %4.1f %3d f %3d ", buffer,g_bias,file_name,delta_mgal,plot_delta_T,sample_length); } void write_header_string(string) char *string;{ char buffer[10]; times(buffer); sprintf(string,"* %s %8s %3d %4d %9.2f %8.6f\n", file_name,buffer,date_get(),year,g_bias,g_scale,buffer); } void calculate_filter_coefficients() { int i; double gauss_sum,x,fraction; /* calculate position of central filter value */ half_sample = (int)(0.5 * (double)sample_length); /* best if sample length is odd */ sample_length = 2.0 * half_sample + 1; /* calculate weighting factors, scaled by the meter constant g_scale, for the gaussian filter */ gauss_sum = 0.0; fraction = 6.0/(double)sample_length; for(i = half_sample; i >= 0; --i) { x = (double)(half_sample - i) * fraction; x = -0.5 * pow(x,2.0); gaussian[half_sample - i] = exp(x); gauss_sum += gaussian[half_sample - i]; } for(i = 1; i <= half_sample; ++i) gauss_sum += gaussian[i]; gauss_sum = 1.0/gauss_sum; /* normalize coefficients */ for(i = 0; i <= half_sample; ++i) gaussian[i] *= gauss_sum; }