// Generate a user-specified number of pulses with user-specified period and duration // upon receipt of a single rising edge trigger. The trigger here is the stage sync signal. // variables to be edited by user int numPulses = 25; // number of pulses to send double pulsePeriodMs = 10.0; // period of pulses in milliseconds double pulseHighMs = 1.0; // time in milliseconds that the pulse is high for, should be less than pulse period int addrOutputBNC1 = 33; // address 33 is BNC#1 on PLC front panel int addrStageSync = 46; // address 46 is TTL5 on Tiger backplane = stage sync signal // variables that should not need to be edited by user // would like to define these variables as final, but this is // not amenable to script which can run multiple times String plcName = "PLogic:E:36"; String propPosition = "PointerPosition"; String propCellType = "EditCellCellType"; String propCellConfig = "EditCellConfig"; String propCellInput1 = "EditCellInput1"; String propCellInput2 = "EditCellInput2"; String propCellInput3 = "EditCellInput3"; String propUpdates = "EditCellUpdateAutomatically"; String valNo = "No"; String valDFlop = "1 - D flop"; String valOneShotNRT = "14 - one shot (NRT)"; int addrZero = 0; int addrInvert = 64; int addrEdge = 128; double ticsPerMs = 4.0; int addrActive = 1; int addrPeriod = 2; int addrPulse = 3; int addrCounter = 4; // figure out the cycle period and high period in terms of PLC "tics" (4kHz) int pulsePeriodTics = (int) (ticsPerMs * pulsePeriodMs + 0.5); int pulseHighTics = (int) (ticsPerMs * pulseHighMs + 0.5); // turn off updates to speed communication String valUpdatesOriginal = mmc.getProperty(plcName, propUpdates); mmc.setProperty(plcName, propUpdates, valNo); // force BNC output to be low so no transients seen mmc.setProperty(plcName, propPosition, addrOutputBNC1); mmc.setProperty(plcName, propCellConfig, addrZero); // D-flop registers when master trigger signal (from stage) arrives // we reset this once we have output the desired number of pulses mmc.setProperty(plcName, propPosition, addrActive); mmc.setProperty(plcName, propCellType, valDFlop); mmc.setProperty(plcName, propCellInput1, addrInvert); // connect D input to logic 1 mmc.setProperty(plcName, propCellInput2, addrEdge + addrStageSync); // trigger/clock with stage mmc.setProperty(plcName, propCellInput3, addrEdge + addrInvert + addrCounter); // reset once counter is done // one-shot NRT to keep period, clocked every tic and immediately set // (but initially kept reset until D-flop captures pulse) mmc.setProperty(plcName, propPosition, addrPeriod); mmc.setProperty(plcName, propCellType, valOneShotNRT); mmc.setProperty(plcName, propCellConfig, pulsePeriodTics - 1); mmc.setProperty(plcName, propCellInput1, addrInvert + addrEdge); // trigger every time mmc.setProperty(plcName, propCellInput2, addrInvert + addrEdge); // clock at 4kHz mmc.setProperty(plcName, propCellInput3, addrInvert + addrActive); // keep reset unless we got triggered // output pulse of the desired duration mmc.setProperty(plcName, propPosition, addrPulse); mmc.setProperty(plcName, propCellType, valOneShotNRT); mmc.setProperty(plcName, propCellConfig, pulseHighTics); mmc.setProperty(plcName, propCellInput1, addrEdge + addrPeriod); mmc.setProperty(plcName, propCellInput2, addrInvert + addrEdge); // clock at 4kHz // one-shot to track how many pulses we have remaining mmc.setProperty(plcName, propPosition, addrCounter); mmc.setProperty(plcName, propCellType, valOneShotNRT); mmc.setProperty(plcName, propCellConfig, numPulses-1); // I don't fully understand why the -1 is needed ;-) mmc.setProperty(plcName, propCellInput1, addrStageSync); mmc.setProperty(plcName, propCellInput2, addrEdge + addrPulse); // connect to BNC output mmc.setProperty(plcName, propPosition, addrOutputBNC1); mmc.setProperty(plcName, propCellConfig, addrPulse); // restore updates mmc.setProperty(plcName, propUpdates, valUpdatesOriginal);