// output a timed pulse coincident with rising edge of input#1 if and only if input#2 has seen a rising edge since the last pulse // use to synchronize the output with input#1 // currently set to output BNC#3 with input#1 of BNC#1 and input#2 of backplane TTL1 // example use case: fire laser (output) when the camera trigger is just starting (input#1) if we are ready for it (input#2) // variables to be edited by user outputDurationInMs = 25; // can be no more than 16.3 seconds with normal 4kHz clock int addrOutput = 35; // 35 corresponds to BNC#3, change if want different output int addrInput1 = 33; // 33 corresponds to BNC#1, change if want different input int addrInput2 = 42; // 42 corresponds to TTL1 on backplane = laser shutter 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 valAND2 = "5 - 2-input AND"; String valOneShot = "14 - one shot (NRT)"; String valIOInput = "0 - input"; String valIOPushPull = "2 - output (push-pull)"; int ticsPerMs = 4; int addrInvert= 64; int addrEdge = 128; int addrInput2Capture = 1; int addrBothInputs = 2; int addrOneShotCell = 3; // figure out the high period in terms of PLC "tics" (4kHz) int outputDurationTics = (int) (outputDurationInMs*ticsPerMs + 0.5); // turn off updates to speed communication String valUpdatesOriginal = mmc.getProperty(plcName, propUpdates); mmc.setProperty(plcName, propUpdates, valNo); // use D-flops to latch rising edges of two inputs // (reset once output pulse starts) mmc.setProperty(plcName, propPosition, addrInput2Capture); mmc.setProperty(plcName, propCellType, valDFlop); mmc.setProperty(plcName, propCellInput1, addrInvert); // connect D input to logic 1 mmc.setProperty(plcName, propCellInput2, addrEdge + addrInput2); mmc.setProperty(plcName, propCellInput3, addrEdge + addrOneShotCell); // reset once output pulse starts // use AND to combine edge of input#1 with latched signal from input#2 mmc.setProperty(plcName, propPosition, addrBothInputs); mmc.setProperty(plcName, propCellType, valAND2); mmc.setProperty(plcName, propCellInput1, addrEdge + addrInput1); mmc.setProperty(plcName, propCellInput2, addrInput2Capture); // use non-retriggerable one-shot to output pulse mmc.setProperty(plcName, propPosition, addrOneShotCell); mmc.setProperty(plcName, propCellType, valOneShot); mmc.setProperty(plcName, propCellConfig, outputDurationTics); mmc.setProperty(plcName, propCellInput1, addrBothInputs); mmc.setProperty(plcName, propCellInput2, addrInvert + addrEdge); // clock on every tic // make sure inputs are set as inputs mmc.setProperty(plcName, propPosition, addrInput1); mmc.setProperty(plcName, propCellType, valIOInput); mmc.setProperty(plcName, propPosition, addrInput2); mmc.setProperty(plcName, propCellType, valIOInput); // connect one shot to output and set as output mmc.setProperty(plcName, propPosition, addrOutput); mmc.setProperty(plcName, propCellType, valIOPushPull); mmc.setProperty(plcName, propCellConfig, addrOneShotCell); // restore updates mmc.setProperty(plcName, propUpdates, valUpdatesOriginal);