%{ /* hpf.cmd * $Log: hpf.cmd,v $ * Revision 1.1 2000/11/03 16:34:31 nort * Initial revision * # Oct96:nmd # SWScanning # Laser offline distinct from laser background # 22Jul96: nmd # SWStepper pos # # Revision 1.4 1993/08/26 18:59:27 nmd # autorunning # # Revision 1.3 1993/08/09 18:25:14 nmd # last version before new manifold added # # Revision 1.2 1993/07/24 21:44:38 nmd # Extended command and control # # Revision 1.1 1993/07/14 15:36:50 nmd # Initial revision # */ #include #include #include #include #include #include #include "globmsg.h" #include "cmdctrl.h" #include "indexer.h" #include "cc.h" #include "msg.h" #include "subbus.h" #include "status.h" #include "collect.h" #include "softdata.h" #pragma off (unreferenced) static char cmdrcsid[] = "$Id: hpf.cmd,v 1.1 2000/11/03 16:34:31 nort Exp nort $"; #pragma on (unreferenced) static send_id colsend_id; void moveEtalon(short numSteps){ static FILE* serialPort=NULL; if ( ! serialPort ){ serialPort = fopen("//5/dev/ser2","w"); if ( !serialPort ) return; /* disable limit switches, and set holding torque to 50% */ fprintf(serialPort,"8LD3\r8SC4\r8SCA2\r"); fflush(serialPort); } fprintf(serialPort,"8A10 8V10 8D%d 8G\r",numSteps); fflush(serialPort); SWData.etalonStep += numSteps; SWData.etalonTarget = SWData.etalonStep; Col_send(colsend_id); } static unsigned int digIOAddr[8] = { VALVE_ONOFF_ADDR_1, VALVE_ONOFF_ADDR_1, VALVE_ONOFF_ADDR_2, VALVE_ONOFF_ADDR_2, VALVE_ONOFF_ADDR_2, VALVE_ONOFF_ADDR_1, VALVE_ONOFF_ADDR_1, VALVE_ONOFF_ADDR_2 }; #define VACUUM_VALVE_NUM 0 #define N2_VALVE_NUM 5 static unsigned int digIOBit[8] = { VACUUM_BIT, BULB_1_BIT, BULB_2_BIT, BULB_3_BIT, BULB_4_BIT, NITROGEN_BIT, MANIFOLD_INJECT_BIT, 7 }; void openValve(const int valveNum){ setDigIOBit(digIOAddr[valveNum],digIOBit[valveNum]); } void closeValve(const int valveNum){ clearDigIOBit(digIOAddr[valveNum],digIOBit[valveNum]); } static int prevBulb=-1; void selectBulb(const int bulbNum){ int bulbCount; unsigned int presAddr=0xC80; unsigned int vacuum; int pid; vacuum=(1.5/1000)*0xFFF; /* if we are already on the correct bulb, don't do anything at all */ if ( prevBulb == bulbNum ) return; /* close all of the reagent bulbs */ for (bulbCount = 1; bulbCount < 5; bulbCount++){ closeValve(bulbCount); } /* now is the time for all good processes to spawn */ pid=fork(); if ( pid == 0 ){ /* this is the child */ /* close the previous bulb */ closeValve(prevBulb); delay(1000); /* evacuate the manifold (make sure!!) */ openValve(VACUUM_VALVE_NUM); delay(15000); closeValve(VACUUM_VALVE_NUM); if ( (sbw(presAddr) >> 4) > vacuum ) exit(0); delay(1000); /* fill with nitrogen and wait for a little diffusion */ openValve(N2_VALVE_NUM); delay(2000); closeValve(N2_VALVE_NUM); delay(10000); /* evacuate again */ openValve(VACUUM_VALVE_NUM); delay(15000); closeValve(VACUUM_VALVE_NUM); if ( (sbw(presAddr) >> 4) > vacuum ) exit(0); delay(1000); /* fill with the new stuff */ openValve(bulbNum); delay(2000); closeValve(bulbNum); delay(5000); /* evacuate again */ openValve(VACUUM_VALVE_NUM); delay(15000); closeValve(VACUUM_VALVE_NUM); if ( (sbw(presAddr) >> 4) > vacuum ) exit(0); delay(1000); /* finally, really open the valve */ openValve(bulbNum); exit(0); } /* Adjust to the current bulb */ prevBulb = bulbNum; } /* selectBulb */ void selectFromFile(){ /* file format is Manifold Bulb Torr %d %d %f [repeat] */ FILE *IF; char workLine[128], line[128]; unsigned short manNum, bulbNum; float injSize; if ( (IF = fopen("run.schedule","r")) == NULL ) return; /* skip header line */ fgets(line,255,IF); fgets(workLine,255,IF); fclose(IF); /* Only proceed if data is found */ if ( sscanf(workLine,"%d %d %f",&manNum, &bulbNum, &injSize) != 3 ) return; /* Manifold 0 Will Indicate throughout a manual injection */ if ( manNum == 0 ) return; selectBulb(bulbNum); } /* selectFromFile */ void injectPresFromManifold(float injPres, unsigned short injectionChannel){ unsigned short presAddr; /* spawn a sub-process to look at the XS pressure and inject a given quantity of XS */ int pid; int count = 0; FILE* OF; unsigned short valNow, goal, toInject; /* Look at manifold number to decide what to do */ if ( injectionChannel == 0 ) return; /* Convert quantity to inject to an unsigned short */ /* 1000.0 torr = 0xFFF */ toInject = injPres / 1000.0 * 0xFFF; /* find the correct addresses */ presAddr = 0xC80; /* get the current pressure */ valNow = sbw(presAddr) >> 4; goal = valNow - toInject; pid = fork(); if ( pid == 0 ) { /* this is the child */ OF=fopen("test.fork","w"); /* open the valve! and set the Injection flag */ setDigIOBit(VALVE_ONOFF_ADDR_1,injectionChannel-1); setDigIOBit(HPF_STAT_ADDR,INJECTION_BIT); /* pause for about 1/2 second to allow any transients */ delay(500); /* wait for the phone to ring */ while ( (valNow=(sbw(presAddr) >> 4)) > goal && ++count < 3000){ fprintf(OF, "%u\n", valNow); delay(50); } /* close the valve */ clearDigIOBit(VALVE_ONOFF_ADDR_1, injectionChannel-1); /* infanticide time */ fprintf(OF, "%u\n", valNow); fclose(OF); exit(0); } /* child, what child ? */ } /* injectPresFromManifold */ void injectFromFile(){ /* file format is Manifold Bulb Torr %d %d %f [repeat] */ FILE *IF, *OF; char workLine[128], line[128], aChar; unsigned short manNum, bulbNum; float injSize; if ( (IF = fopen("run.schedule","r")) == NULL ) return; if ( (OF = fopen("run.tmp","w")) == NULL ){ fclose(IF); return; } /* copy over the header line */ fputs(fgets(line,255,IF),OF); fgets(workLine,255,IF); sscanf(workLine,"%d %d %f",&manNum, &bulbNum, &injSize); if ( injSize > 0 ) injectPresFromManifold(injSize, manNum); if ( fgets(line,255,IF) == NULL ){ fclose(IF); fclose(OF); return; } if ( strncmp(line,"repeat",6) == 0 ) fputs(workLine,OF); fputs(line,OF); while ( !feof(IF) ){ aChar = fgetc(IF); if ( !feof(IF) ) fputc(aChar,OF); } fclose(IF); fclose(OF); remove("run.schedule"); rename("run.tmp","run.schedule"); return; } /* injectFromFile */ %} &start : &commands Quit * { send_dascmd(DCT_QUIT, DCV_QUIT, 1); } : &commands Exit * ; &commands : : &commands &command ; &command : * : Run &run_cmd : Laser &laser_cmd : Telemetry &tm_cmd : XS Reagent &xs_cmd : Carrier Gas &carrier_cmd : OH Source &source_cmd : Pressure &pressure_cmd : &other_cmd ; &laser_cmd : Move %d Steps * { moveEtalon($2); } : Drive Etalon %d Steps at %d Steps per 2 Seconds * { SWData.etalonMove = $3; SWData.etalonRate = fabs($6); if ( fabs( SWData.etalonMove ) < SWData.etalonRate ) SWData.etalonRate = fabs( SWData.etalonMove ); if ( SWData.etalonMove < 0 ) SWData.etalonRate = -SWData.etalonRate; Col_send(colsend_id); } : Step * { moveEtalon(SWData.etalonRate); if ( fabs( SWData.etalonMove ) <= fabs(SWData.etalonRate) ) SWData.etalonMove = SWData.etalonRate = 0; else SWData.etalonMove -= SWData.etalonRate; Col_send(colsend_id); } : To %d * { moveEtalon($2 - SWData.etalonStep); } : Background * { clearDigIOBit(HPF_STAT_ADDR,SIGNAL_BIT); delay(500); moveEtalon(SWData.onlineStep - SWData.etalonStep + SWData.numStepsOffline); delay(500); setDigIOBit(HPF_STAT_ADDR,BACKGROUND_BIT); } : Online * { clearDigIOBit(HPF_STAT_ADDR,BACKGROUND_BIT); delay(500); moveEtalon(SWData.onlineStep - SWData.etalonStep); delay(500); setDigIOBit(HPF_STAT_ADDR,SIGNAL_BIT); } : Offline * { clearDigIOBit(HPF_STAT_ADDR,SIGNAL_BIT); } : Is Online * { clearDigIOBit(HPF_STAT_ADDR,BACKGROUND_BIT); setDigIOBit(HPF_STAT_ADDR,SIGNAL_BIT); SWData.onlineStep = SWData.etalonStep; Col_send(colsend_id); } : Set Nominal PRF %d * { SWData.nominalPRF = $4; Col_send(colsend_id); } : Set Offline Dither %d { SWData.numStepsOffline = $4; Col_send(colsend_id); } : Set Power Normalize %d * { SWData.powerNormalize = $4; Col_send(colsend_id); } : Set Width %d * { SWData.lineWidth = $3; Col_send(colsend_id); } ; &run_cmd : Begin * { FILE * IF; unsigned short manNum, bulbNum; char line[255]; /* IF = fopen("run.schedule","r"); fgets(line,255,IF); fgets(line,255,IF); fclose(IF); sscanf(line,"%d %d",&manNum,&bulbNum); if (manNum == 1 ) clearDigIOBit(HPF_STAT_ADDR,MANNUM_BIT); else setDigIOBit(HPF_STAT_ADDR,MANNUM_BIT); */ setDigIOBit(HPF_STAT_ADDR,RUN_BIT); clearDigIOBit(HPF_STAT_ADDR,INJECTION_BIT); clearDigIOBit(HPF_STAT_ADDR,ABORT_BIT); } : Zero * { setDigIOBit(HPF_STAT_ADDR,RUN_BIT); setDigIOBit(HPF_STAT_ADDR,ZERO_BIT); clearDigIOBit(HPF_STAT_ADDR,ABORT_BIT); } : Plume * { setDigIOBit(HPF_STAT_ADDR,RUN_BIT); setDigIOBit(HPF_STAT_ADDR,PLUME_BIT); clearDigIOBit(HPF_STAT_ADDR,ABORT_BIT); } : Laser Check * { setDigIOBit(HPF_STAT_ADDR,RUN_BIT); setDigIOBit(HPF_STAT_ADDR,LASER_BIT); clearDigIOBit(HPF_STAT_ADDR,ABORT_BIT); } : Steady State Products * { setDigIOBit(HPF_STAT_ADDR,RUN_BIT); setDigIOBit(HPF_STAT_ADDR,LASER_BIT); clearDigIOBit(HPF_STAT_ADDR,ABORT_BIT); } : End * { clearDigIOBit(HPF_STAT_ADDR,RUN_BIT); clearDigIOBit(HPF_STAT_ADDR,INJECTION_BIT); clearDigIOBit(HPF_STAT_ADDR,ZERO_BIT); clearDigIOBit(HPF_STAT_ADDR,PLUME_BIT); clearDigIOBit(HPF_STAT_ADDR,LASER_BIT); } : Abort * { clearDigIOBit(HPF_STAT_ADDR,RUN_BIT); clearDigIOBit(HPF_STAT_ADDR,INJECTION_BIT); clearDigIOBit(HPF_STAT_ADDR,PLUME_BIT); clearDigIOBit(HPF_STAT_ADDR,ZERO_BIT); clearDigIOBit(HPF_STAT_ADDR,LASER_BIT); setDigIOBit(HPF_STAT_ADDR,ABORT_BIT); } ; &tm_cmd : Clear Data Reciever Message * { SWData.dataRecieverMessage=0; Col_send(colsend_id); } : Start * { send_dascmd(DCT_TM, DCV_TM_START, 1); if ( ! colsend_id ) colsend_id = Col_send_init( "SWData", &SWData, sizeof( SWData ) ); SWData.numStepsOffline = 2000; SWData.nominalPRF = 2500; SWData.powerNormalize = 1; SWData.dataRecieverMessage = 0; SWData.scanningCycle=0; Col_send(colsend_id); } : End * { send_dascmd(DCT_TM, DCV_TM_END, 1); } : Clear Errors * { send_dascmd(DCT_TM, DCV_TM_CLEAR, 1); } : Logging Suspend * { send_dascmd(DCT_TM, DCV_TM_SUSLOG, 1); } : Logging Resume * { send_dascmd(DCT_TM, DCV_TM_RESLOG, 1); } : Message Data Reciever %s * { FILE* MF; MF = fopen("dr.msg","w"); fprintf(MF,"%s\n",$4); fclose(MF); SWData.dataRecieverMessage=1; Col_send(colsend_id); } ; &carrier_cmd : Low Flow Set &flow_pct * {sbwr(0xE42, $4);} : Low Flow On * { setDigIOBit(FLOW_ONOFF_ADDR, LOW_FLOW_BIT); } : Low Flow Off * { clearDigIOBit(FLOW_ONOFF_ADDR, LOW_FLOW_BIT); } : High Flow Set &flow_pct * { sbwr(0xE46, $4); } : High Flow On * { setDigIOBit(FLOW_ONOFF_ADDR, HIGH_FLOW_BIT); } : High Flow Off * { clearDigIOBit(FLOW_ONOFF_ADDR, HIGH_FLOW_BIT); } : White Cell Flow Set &flow_pct * { sbwr(0xE40, $5); } : White Cell Flow On * { setDigIOBit(FLOW_ONOFF_ADDR, WHITE_CELL_FLOW_BIT); } : White Cell Flow Off * { clearDigIOBit(FLOW_ONOFF_ADDR, WHITE_CELL_FLOW_BIT); } ; &source_cmd : Carrier Flow Set &flow_pct * { sbwr(0xE44, $4); } : Carrier Flow On * { setDigIOBit(FLOW_ONOFF_ADDR, HE_FLOW_BIT); } : Carrier Flow Off * { clearDigIOBit(FLOW_ONOFF_ADDR, HE_FLOW_BIT); } : H2 Flow Set &flow_pct * { sbwr(0xE56, $4); } : H2 Flow On * { setDigIOBit(FLOW_ONOFF_ADDR, H2_FLOW_BIT); } : H2 Flow Off * { clearDigIOBit(FLOW_ONOFF_ADDR, H2_FLOW_BIT); } : Makeup Flow Set &flow_pct * { sbwr(0xE52, $4); } : Makeup Flow On * { setDigIOBit(FLOW_ONOFF_ADDR, MAKEUP_FLOW_BIT); } : Makeup Flow Off * { clearDigIOBit(FLOW_ONOFF_ADDR, MAKEUP_FLOW_BIT); } : NO2 Flow Set &flow_pct * { sbwr(0xE54, $4); } : NO2 Flow On * { setDigIOBit(FLOW_ONOFF_ADDR, NO2_FLOW_BIT); } : NO2 Flow Off * { clearDigIOBit(FLOW_ONOFF_ADDR, NO2_FLOW_BIT); } ; &xs_cmd : Auto Inject * { injectFromFile(); } : Advance Run Schedule * { injectFromFile(); } : Flow Set &flow_pct * { sbwr(0xE50, $3); } : Flow On * { setDigIOBit(FLOW_ONOFF_ADDR, XS_FLOW_BIT); } : Flow Off * { clearDigIOBit(FLOW_ONOFF_ADDR, XS_FLOW_BIT); } : Inject %f Torr with &valve_num * { injectPresFromManifold($2,$5); } : Kinetics Mode %d * { SWData.kineticsMode = $3; Col_send(colsend_id); } : Manifold &manifold_cmd : Raise Injection Flag * { setDigIOBit(HPF_STAT_ADDR,INJECTION_BIT); } : Select From File * { selectFromFile(); } : Set Scan Cycle %d * { SWData.scanningCycle = $4; Col_send(colsend_id); } ; &manifold_cmd : Open Bulb %d * { openValve($3); } : Close Bulb %d * { closeValve($3); } : Nitrogen Open * { openValve(N2_VALVE_NUM); } : Nitrogen Close * { closeValve(N2_VALVE_NUM); } : Preselect Bulb %d * { prevBulb = $3; } : Select Bulb %d * {selectBulb($3);} : Vacuum Open * { openValve(VACUUM_VALVE_NUM); } : Vacuum Close * { closeValve(VACUUM_VALVE_NUM); } ; &pressure_cmd : Setpoint %d * { SWData.pressureSetpoint = $2; Col_send(colsend_id); } : Gain %d * { SWData.pressureGain = $2; Col_send(colsend_id); } : Phase %d * { SWData.pressurePhase = $2; Col_send(colsend_id); } : FCFullScale %d * { SWData.pressureFCFullScale = $2; Col_send(colsend_id); } : FCMaximum %d * { SWData.pressureFCMax = $2; Col_send(colsend_id); } : FCMinimum %d * { SWData.pressureFCMin = $2; Col_send(colsend_id); } ; &other_cmd : Enqueue %d FTIR Scans %d at %s * { ScanInfo scanInfo; initScanInfo(&scanInfo); scanInfo.numberOfScans = $2; scanInfo.scanNumber = $5; strcpy(scanInfo.resolutionStr,$7); enqueueFTIRScan(&scanInfo); SWData.scanningCycle = $5; Col_send(colsend_id); } : Log %s * {;} : Valve &channel_num Begin * { setDigIOBit(VALVE_ONOFF_ADDR_1,$2); } : Valve &channel_num End * { clearDigIOBit(VALVE_ONOFF_ADDR_1,$2); } : Sol &channel_num Begin * { setDigIOBit(VALVE_ONOFF_ADDR_2,$2); } : Sol &channel_num End * { clearDigIOBit(VALVE_ONOFF_ADDR_2,$2); } ; &channel_num : 0 { $0 = 0; } : 1 { $0 = 1; } : 2 { $0 = 2; } : 3 { $0 = 3; } : 4 { $0 = 4; } : 5 { $0 = 5; } : 6 { $0 = 6; } : 7 { $0 = 7; } ; &valve_num : 1 { $0 = 1; } : 2 { $0 = 2; } ; &flow_pct : %f (% fs) { $0 = (unsigned short)(($1<0) ? 0 : (($1>100) ? 2048 : $1*20.48)); } ;