/***************************************************************************/ /* */ /* 730DGPIB.C - Demonstration package containing the 730D GPIB Communication*/ /* routines. This program assumes that a dos installed device */ /* driver for B&C Microsystems PC488A communications card is */ /* present. */ /* */ /* V1.00 02/07/96 */ /* V1.01 06/17/96 added frequency, TTL I/O, dac, ref, etc.. */ /* */ /***************************************************************************/ #include #include #include #include #include #include #include /* The following are only for the demonstration routines */ #include #include #define FALSE 0 #define TRUE 1 /* * bit values to check status with */ #define BIT0 (0x0001) /* Bit 0 */ #define BIT1 (0x0002) /* Bit 1 */ #define BIT2 (0x0004) /* Bit 2 */ #define BIT3 (0x0008) /* Bit 3 */ #define BIT4 (0x0010) /* Bit 4 */ #define BIT5 (0x0020) /* Bit 5 */ #define BIT6 (0x0040) /* Bit 6 */ #define BIT7 (0x0080) /* Bit 7 */ #define BIT8 (0x0100) /* Bit 8 */ #define BIT9 (0x0200) /* Bit 9 */ #define BIT10 (0x0400) /* Bit 10 */ #define BIT11 (0x0800) /* Bit 11 */ #define BIT12 (0x1000) /* Bit 12 */ #define BIT13 (0x2000) /* Bit 13 */ #define BIT14 (0x4000) /* Bit 14 */ #define BIT15 (0x8000) /* Bit 15 */ /*********************************************************************/ /* */ /* The following #define's are used internally by the instrument */ /* routines. */ /* */ /*********************************************************************/ /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ #define MAX_BUFFER (255) /* Circular buffer size */ /* Definitions for communications */ #define HOST_ADDRESS (3) #define APP_ADDRESS (1) #define ACK ((char) 0x06) #define EOT ((char) 0xFF) #define ETX ((char) 0x03) #define NAK ((char) 0x15) #define STX ((char) 0x02) /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ /* communications message structure */ struct mess_packet { char mess[MAX_BUFFER + 1], retry, /* set to 5 when built */ addressout; /* address to send the character to */ unsigned int timer; /* set to curr_bios_time() */ } outbuff[6]; union { struct { unsigned sent_eot : 1; unsigned sent_address : 1; unsigned go : 1; unsigned end_message : 1; unsigned received_eot : 1; unsigned receive_data : 1; unsigned sent_ack_nak : 1; unsigned transmit_data : 1; unsigned transmit_done : 1; unsigned device_to_send : 1; unsigned transaction_done : 1; unsigned RNAK : 1; unsigned sent_nak : 1; unsigned dummy : 3; } b; unsigned word; } f; int MessageAvailable = 0; /* Holds # of messages in buffer */ char iir, iis; /* what mode are you in */ int data_to_send = 0, top_out = 0, bottom_out = 0, top_in = 0, bottom_in = 0; int restart_transfer; /* used to indicate polling only */ char addressout, lch; char inbuff[6][260]; int resend_z_command = 0, sending_z_command = 0; char APP_address; FILE *gpib_in = NULL, *gpib_out = NULL; char key_buffer[200]; int keyboard_top = 0, keyboard_bottom = 0; /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ int init_730(void); int send_730_reset(void); /* Internal function prototypes */ char CheckSum(char *); char make_string(char, char *, char *); void init_trans(void); void reset_buffer(void); int Setup_GPIB(void); int out_message(void); void set_transaction_done(void); int get_event(void); unsigned int curr_bios_time(void); int initEEE488(int, int); int process_GPIB_communication(void); int get_gpib_spoll(int); int send_gpib_command(char *); int receive_gpib_command(char *, int); int receive_binary_gpib(char *, int, int); int send_gpib_data(char *, int); int get_gpib_input(char *); char rc_getch(int); int rc_kbhit(void); void position_and_print(int y, int x, char *buff); int send_and_wait(char *buff, unsigned timetowait); int receive_command(char *command); int send_command(char *command); void UploadBufferedData(char *buff); int init_730(void) { int ret = 1; if(ret == 1 && !Setup_GPIB()) /* Get the port connection initialized */ ret = 2; return(ret); } int send_command(char *command) { int tt = top_out, return_val = 1, ttt = 1; if(make_string('\000', command, outbuff[top_out].mess)) { outbuff[tt].addressout = APP_address; outbuff[tt].retry = 5; outbuff[tt].timer = curr_bios_time(); ttt = out_message(); } else { return_val = 0; } if(ttt == 0) { return_val = 0; if(!sending_z_command) send_z_command(); } return(return_val); } int receive_command(char *command) { int i, retrys = 2, return_val = 1, tt, done = 0, filt, err, tc = 0, ttype, rangelvl, grat; char c, tbuff[80], *ptr, *ptr2, *ptr3, bbb[80]; static int tcount = 0; double sig, chop; double current_angle; restart_transfer = 1; while(retrys-- && return_val) { tt = top_out; if(make_string('\000', "I", outbuff[top_out].mess)) /*request data from the user */ { while(data_to_send) { outbuff[tt].retry = 100; outbuff[tt].addressout = APP_address | 0x80; return_val = out_message(); /* send the string to the wavelength drive */ if(!return_val && !sending_z_command) /* check to see if we are already doing something and if so then don't send z command */ { f.word = 0; send_z_command(); break; } else if(!return_val && sending_z_command) break; } } i = 0; while(return_val && i < 100) { /* * check for user abort */ if(MessageAvailable) /* have a message so check to see if it is a Y */ { if(--MessageAvailable < 0) MessageAvailable = 0; /* Decrement the message available flag */ strcpy(command, &inbuff[bottom_in][0]); if(++bottom_in > 5) bottom_in = 0; /* Print the incoming message, minus handshaking and checksum */ *(strchr(command, ETX)) = '\0'; /* Chop-off remainder */ disp_move(23, 0); disp_printf("%.*s", (strlen(&command[1]) > 75) ? 75 : strlen(&command[1]), &command[1]); c=command[1]; if(!sending_z_command && c == 'Z') /* got back an unwanted Z command so toss it out */ { ++retrys; /* Not the message we wanted so try again */ break; } else { done = 1; break; } } msleep(10); i++; } if(resend_z_command) /* controller was reset during a z command */ return_val = 0; if(done) break; } if(return_val) { if(!done) { return_val = 0; } } else reset_buffer(); return(return_val); } /**********************************************************************/ /* */ /* The following procedures are used internally by the instrument */ /* routines. You will definitely want to customize "get_event()", */ /* but probably will never have to mess with the others above */ /* translating them to work with your compiler. */ /* */ /**********************************************************************/ /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ /*----------------------------------------------------------------------- CheckSum will accumulate the values of the bytes in the buffer together and mask it with 7F hex to prevent a EOT on the line parameters : buffer - contains the values to accumulate -----------------------------------------------------------------------*/ char CheckSum(char *buffer) { char chk = 0; do { chk += *buffer++; } while (*buffer); chk = chk & 0x7F; return(chk); } /*-------------------------------------------------------------------- make_string will build the necessary string and insert the correct command protocols in the buffer. The start and end will need to be inserted into the buffer along with a call to CheckSum. parameters : Command : to tell the device what action to take 'W' - WAVE type of command CommandValue - to scale the command .. depends on command --------------------------------------------------------------------*/ char make_string (char Command, char *CommandValue, char *buffer) { int BufSize; char TChk; if(data_to_send < 6) { if(Command) sprintf(buffer,"%c%c%s%c\000", STX, Command, CommandValue, ETX); else sprintf(buffer,"%c%s%c\000", STX, CommandValue, ETX); /* calculate the checksum and put the checksum in the buffer */ BufSize = strlen(buffer); TChk = CheckSum(buffer); buffer[BufSize++] = TChk; buffer[BufSize] = '\000'; if(++top_out > 5) top_out = 0; data_to_send++; return(1); } else return(0); } /*--------------------------------------------------------------------- init_trans wil initiate the data transfer process. device_address : device address (high bit on = device send.) ----------------------------------------------------------------------*/ void init_trans(void) { f.word = 0; /* reset all bit flags */ outbuff[bottom_out].timer = curr_bios_time(); /* Update the time */ return; } /* -------------------------------------------------------------- * * Function : reset_buffer() * * Purpose : This function clears the buffer to a zero state. * * Entry : none. * * Return : none. ----------------------------------------------------------------*/ void reset_buffer(void) { f.word = data_to_send = top_in = top_out = bottom_in = bottom_out = MessageAvailable = 0; /* clear any previous messages */ } /*----------------------------------------------------------------*/ /* */ /* Function : Setup_GPIB() */ /* */ /* Purpose : This function sets up GPIB communications. */ /* */ /* Return -=> 0 if GPIB device not initialized, 1 otherwise. */ /* */ /*----------------------------------------------------------------*/ int Setup_GPIB(void) { int ok = 1; if(!initEEE488(3, 0)) /* initialize the GPIB bus card */ ok = 0; APP_address = APP_ADDRESS; return(ok); } /* * out_message() initiates data transfer to the application and checks * for time outs and errors */ int out_message() { int current, return_val = 1, cncl = 0, reprogram, timeout = 0; int ev = 0; current = bottom_out; reprogram = outbuff[current].retry; while(outbuff[current].retry-- > 0) { if(!return_val) break; init_trans(); /* Start the communications process */ while(return_val) { if(abs(curr_bios_time() - outbuff[current].timer) > 30) { timeout++; break; } if(f.b.transaction_done) /* restart the communica */ { outbuff[current].retry++; break; } ev = process_GPIB_communication(); /* check to see if there was an event */ if(ev) /* Must be a cancel */ { if(sending_z_command) /* already sending z command so abort z command */ { f.word = 0; /* shut off communications */ reset_buffer(); /* reset communications buffer */ return_val = 0; /* message never sent so return 0 */ break; } else { f.word = 0; return_val = 0; break; } } } if(!data_to_send) { timeout = 0; break; /* all done */ } else if(timeout) { if(reprogram) { reprogram--; if(!initEEE488(0,0)) return_val = 0; timeout = 0; outbuff[current].retry++; } } outbuff[current].timer = curr_bios_time(); } if(timeout) /* If all fails...then return a zero */ return_val = 0; return(return_val); } /* * This function will be used to set the transaction done flag for * the GPIB communications */ void set_transaction_done(void) { f.b.transaction_done = 1; } /**************************************************************************/ /* */ /* This function checks to see if the ESCAPE key has been hit, indicating */ /* that the current operation should be cancelled. You probably want to */ /* substitute your own conditions instead. */ /* */ /* Return -=> 1 if a key has been pressed and it's ESCAPE, 0 otherwise. */ /* */ /**************************************************************************/ int get_event(void) { /* ESCAPE = ASCII 27 */ return((kbhit() && (rc_getch(TRUE) == 27)) ? 1 : 0); } /**************************************************************************/ /* */ /* This function will poll the keyboard to see if any key is pressed. */ /* If pressed, the key will be checked to see if it is an ESCAPE...if so, */ /* the ESCAPE will be returned immediately and the keyboard input buffer */ /* will be flushed. All other keys will be buffered while in */ /* "get_event()", otherwise key presses will be returned. */ /* */ /**************************************************************************/ char rc_getch(int from_get_event) { char nextchar; if(kbhit()) /* get the key from the operating system and stuff it in the buffer */ { key_buffer[keyboard_top] = getch(); /* See if escape is pressed...if so then flush the buffer and return escape */ if(key_buffer[keyboard_top] == 27) { keyboard_top = keyboard_bottom = 0; return(27); } if(++keyboard_top >= 200) keyboard_top = 0; /* Loop the buffer around */ } if(from_get_event) return(0); /* Return a value other than escape to get_event() */ /* Alright, get_event() and escape are handled so let's get a key and return */ if(keyboard_bottom != keyboard_top) { nextchar = key_buffer[keyboard_bottom]; if(++keyboard_bottom >= 200) keyboard_bottom = 0; /* Loop the buffer around */ } else nextchar = getch(); /* None available so hang out until one is */ return(nextchar); } /***********************************************************************/ /* */ /* This routine will check to see if there is a key available first on */ /* the stack, then from the keyboard. */ /* */ /* Returns TRUE if key available, FALSE if not. */ /* */ /***********************************************************************/ int rc_kbhit(void) { return((keyboard_top != keyboard_bottom) || kbhit()); } /*************************************************************************/ /* */ /* This function returns timing information in ticks (approximately 18.2 */ /* ticks per second). Replace with a similar function call supported by */ /* your compiler. */ /* */ /* Return -=> A (relative) time in ticks. */ /* */ /*************************************************************************/ unsigned int curr_bios_time(void) { long btime; _bios_timeofday(0, &btime); /* Number o' ticks (18.2/second) since midnight */ return((unsigned int)btime); } /*********************************************************************** * This routine will init the GPIB controller/device. * * entry: int myadddress, - The address of the GPIB device/controller. * device; - 0 = controller. 1 = device. * * Return -=> 0 if GPIB device not responding, 1 otherwise. * */ int initEEE488(int myaddress, int device) { char buffer[256]; /* Close existing files */ if(gpib_in != NULL) fclose(gpib_in); if(gpib_out != NULL) fclose(gpib_out); /* Open and unbuffer the GPIB files */ if((gpib_in = fopen("PC488", "rb")) == NULL) return(0); setbuf(gpib_in, NULL); if((gpib_out = fopen("PC488", "wb")) == NULL) { fclose(gpib_in); return(0); } setbuf(gpib_out, NULL); if(!device) { /* These commands pertain to the system controller only */ send_gpib_command("RESET"); send_gpib_command("ABORT"); send_gpib_command("CLEAR"); } sprintf(buffer, "MYADDR %d", myaddress); send_gpib_command(buffer); send_gpib_command("SET 11;0"); /* Wait for available input */ return(1); } /* * This routine will handle the appropriate communications transaction for * the current outgoing message * * entry void; * exit int 1 = Cancelled, 0 = OK */ int process_GPIB_communication(void) { int status; char *b2; /* Are we here to transmit or to receive? */ status = 0; while(data_to_send) { if(outbuff[bottom_out].addressout & BIT7) /* High bit set means we are here to receive */ { status = get_gpib_spoll(outbuff[bottom_out].addressout & ~BIT7 & 0xff); if(status == -1) status = 1; else { if((status & BIT0) == BIT0) { if(receive_gpib_command(&inbuff[top_in][0], outbuff[bottom_out].addressout & ~BIT7 & 0xff) == 1) { MessageAvailable++; /* Tell the applications layer a message is available */ if(++top_in > 5) /* Bump the index pointer of the circular pointer */ top_in = 0; status = 0; } else status = 1; } else status = 0; } if(!status) { set_transaction_done(); if(!restart_transfer || MessageAvailable) /* Was poll sucessfull */ { if(data_to_send) /* Decrement the message to send buffer */ { data_to_send--; if(++bottom_out > 5) bottom_out = 0; } } } } else { b2 = strchr(outbuff[bottom_out].mess, ETX); if(b2) { b2++; *b2 = '\000'; /* Dont try to send it */ } status = !send_gpib_data(outbuff[bottom_out].mess, outbuff[bottom_out].addressout & ~BIT7 & 0xff); if(!status) { set_transaction_done(); if(++bottom_out > 5) /* Bump the index pointer of the circular pointer */ bottom_out = 0; data_to_send--; } } if(status) break; /* If break down in communications, then abort */ } return(get_event()); } /*****************************************************************************/ /* */ /* This function will SPOLL the desired device to see if it wants servicing. */ /* */ /* Input -=> n : Device to check. */ /* */ /* Return -=> The SPOLL value, or -1 if an error occurred. */ /* */ /*****************************************************************************/ int get_gpib_spoll(int n) { char s[256]; int err, status; sprintf(s, "SPOLL %d", n); if((err = send_gpib_command(s)) == 1) /* Send the request */ { if((err = get_gpib_input(s)) == 1) /* Receive the byte back */ status = atoi(s); } return((err == 1) ? status : -1); } /***********************************************************************/ /* */ /* This function will send a GPIB command. */ /* */ /* Input -=> s : Command to send. */ /* */ /* Return -=> 0 if an error happened, 1 otherwise. */ /* */ /***********************************************************************/ int send_gpib_command(char *s) { return((fprintf(gpib_out, "%s\r\n", s) == EOF) ? 0 : 1); } /**************************************************************/ /* */ /* This function receives a data string from a device. */ /* */ /* Input -=> s : Will contain the returned string. */ /* from_who : Device to grab the information from. */ /* */ /* Return -=> 0 if an error happened, 1 otherwise. */ /* */ /**************************************************************/ int receive_gpib_command(char *s, int from_who) { char buff[256]; int i; sprintf(buff, "ENTER %d", from_who); /* Get data from the device */ if(send_gpib_command(buff) == 0) return(0); return(get_gpib_input(s)); } /**************************************************************/ /* */ /*This function receives a binary data stream from the deviced*/ /* */ /* Input -=> s : Will contain the returned string. */ /* from_who : Device to grab the information from. */ /* */ /* Return -=> 0 if an error happened, 1 otherwise. */ /* */ /**************************************************************/ int receive_binary_gpib(char *s, int from_who, int numbytes) { char buff[256]; int i; s[0] = '|'; sprintf(buff, "ENTER %d#%d; %d : %d ", from_who, numbytes, FP_SEG(s), FP_OFF(s)); /* Get data from the device */ if(send_gpib_command(buff) == 0) return(0); if(s[0] == '|') return(0); else return(1); } /***************************************************************/ /* */ /* This function will send data to a device. */ /* */ /* Input -=> s : Information to send. */ /* to_who : The device which will receive the data. */ /* */ /* Return -=> 0 if an error happened, 1 otherwise. */ /* */ /***************************************************************/ int send_gpib_data(char *s, int to_who) { char buff[256]; /* Tell who to send the message to */ sprintf(buff, "OUTPUT %d;%s", to_who, s); return(send_gpib_command(buff)); } /*************************************************************/ /* */ /* This function will receive data from the GPIB controller. */ /* */ /* Input -=> s : Information obtained. */ /* */ /* Return -=> 0 if an error happened, 1 otherwise. */ /* */ /*************************************************************/ int get_gpib_input(char *s) { int i, err = 1; for(i = 0; err == 1; ++i) /* Accept input until terminator reached */ { err = ((s[i] = fgetc(gpib_in)) == EOF) ? 0 : 1; if(err == 0) break; /* Look for the terminator */ if(s[i] == '\n' && s[i - 1] == '\r') { s[i - 1] = '\0'; /* End the string and eliminate the terminator */ break; } } return(err); } // // This routine will be used to upload the buffered data from the 730D // controller. // // Command 'B' - Says enter binary buffer transfer mode // // The instrument will respond with an ASCII string that identifies the // number of elements, the type of data and the exponent of the data. // // "B # T E" Where, // B is the command. // # is the number of elements to be received. // T is the type of data i.e. 0 for Fixed float point (2 bytes per point) // 1 for floating point (4 bytes per point // E is the exponent of he data. // void UploadBufferedData(char *buff) { int elements, type, exponent, numbytes, i; void *retbuf; float *darray; int *iarray; FILE *fp; // pick off the elements, the data type and the exponents sscanf(buff, "%*c%*c%d%d%d", &exponent, &type, &elements); numbytes = elements * ((type == 0) ? sizeof(short int) : sizeof(float)); sprintf(buff, "Entering binary transfer mode: Reading %d bytes. Please Wait", numbytes); position_and_print(23, 0, buff); retbuf = malloc(numbytes); // // be sure memory could be allocated // if(retbuf == NULL ) { position_and_print(23, 0, "Memory Allocation Error. Function aborted"); return; } // Go receive the binary data from the device if(receive_binary_gpib(retbuf, APP_address, numbytes)) { position_and_print(23, 0, "Binary Data received, conversion in process..."); // // Need to convert from fixed floating point to floating point if(type == 0) { darray = malloc(elements * sizeof(float)); iarray = retbuf; for(i=0; i1)&&(i!=9)) // a detector record was found { if(i==2) // look for top line of description { fscanf(fptr,"%d",&tempi1); if(tempi1>=1 && tempi1<=25) { ch=getc(fptr); tempi2=0; // download line 1 of description while(((ch=getc(fptr))!='|') && tempi2<17) { sprintf(buff, "X %2d %2d ", tempi1, tempi2); buff[8]=ch; tempi2++; if(send_and_wait(buff, 100)) position_and_print(23, 0, buff); } i++; } else i=0; } // download cal factor while(i==3) { ch=getc(fptr); if(ch=='|') { tempi2=70; tempi3=8; sprintf(buff, "X %2d %2d ", tempi1, tempi2); ch=getc(fptr); while(ch=='E'||ch=='e'||ch==' '||ch=='.'||ch=='+'||ch=='-'||(ch>='0'&&ch<='9')) { buff[tempi3]=ch; tempi3++; ch=getc(fptr); } if(tempi3==8) sprintf(&buff[8],"+0.0E+00"); else buff[tempi3]=0; if(send_and_wait(buff, 100)) position_and_print(23, 0, buff); i=5; } else if(ch!=' ') i=0; } // download input type if(i==5) { ch=getc(fptr); while((ch!='|') && i) { if(ch==EOF || ch=='\n') i=0; ch=getc(fptr); } ch=getc(fptr); } while(i==5) { while(ch==' '||ch=='\t') ch=getc(fptr); if(ch>='0' || ch<='9') { sprintf(buff, "X %2d 61 ", tempi1); buff[8]=ch; if(send_and_wait(buff, 100)) position_and_print(23, 0, buff); i=7; } else if(ch==EOF) i=0; else // default to dc current /dc coupling { sprintf(buff, "X %2d 61 2 ", tempi1); if(send_and_wait(buff, 100)) position_and_print(23, 0, buff); if(ch=='\n') // default to hv off { sprintf(buff, "X %2d 60 0 ", tempi1); if(send_and_wait(buff, 100)) position_and_print(23, 0, buff); i=10; } else i=7; ungetc(ch,fptr); } } // download hv level if(i==7) { ch=getc(fptr); while(ch==' '||ch=='\t') ch=getc(fptr); tempi2=8; sprintf(buff, "X %2d 60 ", tempi1); while((ch>='0' && ch <='9')||ch=='+'||ch=='-') { buff[tempi2]=ch; tempi2++; ch=getc(fptr); } if(tempi2>8) { buff[tempi2]=0x00; i++; } else { buff[tempi2]='0'; i=10; ungetc(ch,fptr); } if(send_and_wait(buff, 100)) position_and_print(23, 0, buff); } // download flux limit if(i==8) { while(ch==' '||ch=='\t') ch=getc(fptr); tempi2=8; sprintf(buff, "X %2d 80 ", tempi1); while((ch>='0' && ch <='9')||ch=='+'||ch=='-'||ch=='.') { buff[tempi2]=ch; tempi2++; ch=getc(fptr); } if(tempi2>8) buff[tempi2]=0x00; else { buff[tempi2]='1'; tempi2++; buff[tempi2]=0x00; } if(send_and_wait(buff, 100)) position_and_print(23, 0, buff); i=10; ungetc(ch,fptr); } // download line 2 of description if(i==10) { while(ch!='|') ch=getc(fptr); tempi2=17; while(((ch=getc(fptr))!='|') && tempi2<37) { sprintf(buff, "X %2d %2d ", tempi1, tempi2); buff[8]=ch; tempi2++; if(send_and_wait(buff, 100)) position_and_print(23, 0, buff); } i++; ch=getc(fptr); } // download units while(i==11) { ch=getc(fptr); if(ch=='|') { tempi2=40; while(((ch=getc(fptr))!='|') && tempi2<60) { sprintf(buff, "X %2d %2d ", tempi1, tempi2); buff[8]=ch; tempi2++; if(send_and_wait(buff, 100)) position_and_print(23, 0, buff); } i=1; } else if(ch==EOF||ch=='\n') i=0; } } } fclose(fptr); break; case 'N': // upload a detector file // fptr=fopen("730.txt","w"); position_and_print(21,0,"Enter the filename: "); scanf("%s", &buff); if((fptr=fopen(buff,"w"))==NULL) { position_and_print(21,0,"Can't open file !"); break; } fputs(" CAL FACTOR AND DET PMT PMT\n",fptr); fputs(" DETECTOR DESCRIPTION UNITS DESCRIPTION INPUT VOLTS LIMIT(uA)\n",fptr); fputs("-------------------------------------------------------------------\n",fptr); tempi1=0; while(tempi1<26) { buff[9]=0x7f; while((buff[9]==0x7f||buff[9]==1) && tempi1<25) { tempi1++; sprintf(buff, "Y %2d 0 ", tempi1); if(send_and_wait(buff, 100)) position_and_print(23, 0, buff); } if(tempi1>25 || buff[9]==0x7f || buff[9]==1) break; tempi2=0; fprintf(fptr,"%c|%2d:",'\n',tempi1); // upload the 1st line of description while(tempi2<17) { sprintf(buff, "Y %2d %2d", tempi1,tempi2); if(send_and_wait(buff, 100)) position_and_print(23, 0, buff); putc(buff[9],fptr); tempi2++; } fputs("| | ",fptr); // upload the cal factor sprintf(buff, "Y %2d 70", tempi1); if(send_and_wait(buff, 100)) position_and_print(23, 0, buff); tempi2=9; while(tempi2<20 && buff[tempi2]!=0) { putc(buff[tempi2],fptr); tempi2++; } // upload the input type sprintf(buff, "Y %2d 61", tempi1); if(send_and_wait(buff, 100)) position_and_print(23, 0, buff); if(buff[9]=='0'||buff[9]=='1'||buff[9]=='2') fputs(" amps/ | ",fptr); else if(buff[9]=='3'||buff[9]=='4'||buff[9]=='5') fputs(" volts/ | ",fptr); else if(buff[9]=='6') fputs(" counts/| ",fptr); fputc(buff[9],fptr); //print the input type code // upload the hv level, limit sprintf(buff, "Y %2d 60", tempi1); if(send_and_wait(buff, 100)) position_and_print(23, 0, buff); buff[14]=0; sscanf(&buff[9],"%d",&tempi2); if(tempi2!=0) { tempi2=9; while(tempi2<15) { putc(buff[tempi2],fptr); tempi2++; } fputs(" ",fptr); sprintf(buff, "Y %2d 80", tempi1); if(send_and_wait(buff, 100)) position_and_print(23, 0, buff); tempi2=9; while(tempi2<15) { putc(buff[tempi2],fptr); tempi2++; } } fputs("\n|",fptr); // upload the 2nd line of description tempi2=17; while(tempi2<37) { sprintf(buff, "Y %2d %2d", tempi1,tempi2); if(send_and_wait(buff, 100)) position_and_print(23, 0, buff); putc(buff[9],fptr); tempi2++; } fputs("| |",fptr); // upload the units description tempi2=40; while(tempi2<60) { sprintf(buff, "Y %2d %2d", tempi1,tempi2); if(send_and_wait(buff, 100)) position_and_print(23, 0, buff); putc(buff[9],fptr); tempi2++; } fputs("|\n",fptr); } fclose(fptr); break; case 'O': // Set the number of points to read position_and_print(21,0,"Enter the number of points to read (1 to 2000): "); scanf("%d", &tempi1); position_and_print(21,0, ""); // // guard the range // if(tempi1<1) tempi1 = 1; else if(tempi1 > 2000) tempi1 = 2000; sprintf(buff, "P %d", tempi1); if(send_and_wait(buff, 100)) { position_and_print(23, 0, buff); } break; case 'P': // Trigger the photometer and take a reading sprintf(buff, "J "); if(send_and_wait(buff, 100)) { position_and_print(23, 0, buff); } break; case 'R': // setup the external trigger mode position_and_print(21,0,"Enter Trigger Pin (1 or 2): "); scanf("%d", &tempi1); position_and_print(21,0, ""); position_and_print(21,0,"Enter Trigger Mode (0 - Off, 1 - FE, 2 - RE, 3 - RE|FE): "); scanf("%d", &tempi2); // // guard the pin // if(tempi1<1) tempi1 = 1; else if(tempi1 > 2) tempi1 = 2; // // guard the mode if(tempi2<0) tempi2 = 0; else if(tempi2 > 3) tempi2 = 3; sprintf(buff, "A%d %d", tempi1,tempi2); if(send_and_wait(buff, 100)) { position_and_print(23, 0, buff); } break; case 'S': // upload the buffer memory from the 730D sprintf(buff, "B "); if(send_and_wait(buff, 100)) { UploadBufferedData(buff); } break; case 'T': // Set the TTL outputs, Read the trigger states position_and_print(21,0,"Enter the TTL outputs in binary form: "); scanf("%b", &tempi1); position_and_print(21,0, ""); sprintf(buff, "T %2X", tempi1); if(send_and_wait(buff, 100)) { position_and_print(23, 0, buff); } break; case 'Q': done=1; fclose(gpib_in); fclose(gpib_out); break; } } } void position_and_print(int y, int x, char *buff) { disp_move(y,x); disp_eeol(); disp_printf(buff); } /* ---------------------------------------------------------------------------- * * Function : send_z_command() - Function sends a Z (ABORT) command to the * Instrument and displays a please wait message * to the user. * * Parameters: none * * Return : 1 - Abort sucessful * 0 - Abort failed - serious problems. * */ int send_z_command(void) { int err, working = 1; char buff[300], c; sending_z_command = 1; /* flag the z command so user can't abort an abort */ /* Let the user know that an abort is in progress */ position_and_print(23, 0,"Resetting 730D. Please wait."); reset_buffer(); /* reset the communications buffer - clear any old commands */ /* build command to send to controller */ if(send_command("Z")) /* try to send command */ { while(working) /* keep trying to send the Z command */ { if(receive_command(buff)) /* ask for Z value back from controller */ { /* parse message (First char in buff is STX so skip to second char) */ err = sscanf(&buff[1], "%c", &c); if(err == 1 && c == 'Z') /* if not right message then keep trying */ break; } else /* Communications crash so tell the user */ { position_and_print(23, 0, "Communications Error Handler Needed ..."); working = 0; } } } sending_z_command = 0; /* finished sending the Z command */ position_and_print(23, 0, "Abort Successful..."); return(working); } int send_and_wait (char *buff, unsigned timetowait) { char instuff[300], c; int return_val = 0, err; unsigned ticker1; //!!!!!!!!!!!!!!!!!!! position_and_print(22,0,buff); //!!!!!!!!!!!!!!!!!!! if(send_command(buff)) /* try to send command */ { ticker1 = curr_bios_time(); while(abs(curr_bios_time() - ticker1) < timetowait) { if(receive_command(instuff)) /* ask for Z value back from controller */ { err = sscanf(&instuff[1], "%c", &c); if(err == 1 && c == *buff) /* if not right message then keep trying */ { strcpy(buff, instuff); return_val = 1; break; } } else /* Communications crash so tell the user */ break; } } if(!return_val) /* Communications crash so tell the user */ { position_and_print(23, 0, "Communications Error Handler Needed ..."); } return(return_val); }