diff --git a/ClankTest.cps b/ClankTest.cps
new file mode 100644
index 0000000000000000000000000000000000000000..d67a0b7d87efb2f02244cd3b91a243d8de371b53
--- /dev/null
+++ b/ClankTest.cps
@@ -0,0 +1,984 @@
+/**
+  Copyright (C) 2012-2018 by Autodesk, Inc.
+  All rights reserved.
+
+  Othermill/Otherplan post processor configuration.
+
+  $Revision: 42473 905303e8374380273c82d214b32b7e80091ba92e $
+  $Date: 2019-09-04 00:46:02 $
+  
+  FORKID {D636014A-7BBF-4072-86B9-0FCC8F2D8D86}
+
+  Edited by Anthony Pennes to run on Clank on 1
+*/
+
+description = "Clank post processor";
+vendor = "Anthony Pennes";
+vendorUrl = "0";
+legal = "0";
+//certificationLevel = ;
+//minimumRevision = 40783;
+
+longDescription = "Post Processor for Clank edited by Anthony Pennes";
+
+extension = "gcode";
+setCodePage("ascii");
+
+capabilities = CAPABILITY_MILLING;
+tolerance = spatial(0.002, MM);
+
+minimumChordLength = spatial(0.25, MM);
+minimumCircularRadius = spatial(0, MM); // default 0.01 changed to prevent I J commands
+maximumCircularRadius = spatial(0, MM);// default 1000 changed to prevent I J commands
+minimumCircularSweep = toRad(0.01);
+maximumCircularSweep = toRad(180);
+allowHelicalMoves = false; //deafult true
+allowedCircularPlanes = undefined; // allow any circular motion
+
+// user-defined properties
+properties = {
+  writeMachine: false, // write machine
+  writeTools: false, // writes the tools
+  showSequenceNumbers: false, // show sequence numbers
+  sequenceNumberStart: 10, // first sequence number
+  sequenceNumberIncrement: 5, // increment for sequence numbers
+  optionalStop: true, // optional stop
+  separateWordsWithSpace: true, // specifies that the words should be separated with a white space
+  useActiveSpindle: true, // enable to use spindle S, M3, M4, ...
+  useToolChanger: false, // specifies if the machine is able to handle M6 commands for a tool change
+  useRadius: false // specifies that arcs should be output using the radius (R word) instead of the I, J, and K words.
+};
+
+// user-defined property definitions
+propertyDefinitions = {
+  writeMachine: {title:"Write machine", description:"Output the machine settings in the header of the code.", group:0, type:"boolean"},
+  writeTools: {title:"Write tool list", description:"Output a tool list in the header of the code.", group:0, type:"boolean"},
+  showSequenceNumbers: {title:"Use sequence numbers", description:"Use sequence numbers for each block of outputted code.", group:1, type:"boolean"},
+  sequenceNumberStart: {title:"Start sequence number", description:"The number at which to start the sequence numbers.", group:1, type:"integer"},
+  sequenceNumberIncrement: {title:"Sequence number increment", description:"The amount by which the sequence number is incremented by in each block.", group:1, type:"integer"},
+  optionalStop: {title:"Optional stop", description:"Outputs optional stop code during when necessary in the code.", type:"boolean"},
+  separateWordsWithSpace: {title:"Separate words with space", description:"Adds spaces between words if 'yes' is selected.", type:"boolean"},
+  useActiveSpindle: {title:"Use active spindle", description:"Enable to use spindle commands (S, M3, M4, ...).", type:"boolean"},
+  useToolChanger: {title:"Use tool changer", description:"Specifies that a tool changer is available.", type:"boolean"},
+  useRadius: {title:"Radius arcs", description:"If yes is selected, arcs are outputted using radius values rather than IJK.", type:"boolean"}
+};
+
+var permittedCommentChars = " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,=_-";
+
+var singleLineCoolant = false; // specifies to output multiple coolant codes in one line rather than in separate lines
+// samples:
+// {id: COOLANT_THROUGH_TOOL, on: 88, off: 89}
+// {id: COOLANT_THROUGH_TOOL, on: [8, 88], off: [9, 89]}
+var coolants = [
+  {id: COOLANT_FLOOD, on: 8},
+  {id: COOLANT_MIST, on: 7},
+  {id: COOLANT_THROUGH_TOOL},
+  {id: COOLANT_AIR},
+  {id: COOLANT_AIR_THROUGH_TOOL},
+  {id: COOLANT_SUCTION},
+  {id: COOLANT_FLOOD_MIST},
+  {id: COOLANT_FLOOD_THROUGH_TOOL},
+  {id: COOLANT_OFF, off: 9}
+];
+
+var nFormat = createFormat({prefix:"N", decimals:0});
+var gFormat = createFormat({prefix:"G", decimals:0});
+var mFormat = createFormat({prefix:"M", decimals:0});
+var hFormat = createFormat({prefix:"H", decimals:0}); // not supported at the moment
+var dFormat = createFormat({prefix:"D", decimals:0}); // not supported at the moment
+
+var xyzFormat = createFormat({decimals:(unit == MM ? 3 : 4), forceDecimal:true});
+var rFormat = xyzFormat; // radius
+var abcFormat = createFormat({decimals:3, forceDecimal:true, scale:DEG});
+var feedFormat = createFormat({decimals:(unit == MM ? 0 : 1), forceDecimal:true});
+var toolFormat = createFormat({decimals:0});
+var rpmFormat = createFormat({decimals:0});
+var secFormat = createFormat({decimals:3, forceDecimal:true}); // seconds - range 0.001-99999.999
+var milliFormat = createFormat({decimals:0}); // milliseconds // range 1-9999
+var taperFormat = createFormat({decimals:1, scale:DEG});
+
+var xOutput = createVariable({prefix:"X"}, xyzFormat);
+var yOutput = createVariable({prefix:"Y"}, xyzFormat);
+var zOutput = createVariable({onchange:function () {retracted = false;}, prefix:"Z"}, xyzFormat);
+var aOutput = createVariable({prefix:"A"}, abcFormat);
+var bOutput = createVariable({prefix:"B"}, abcFormat);
+var cOutput = createVariable({prefix:"C"}, abcFormat);
+var feedOutput = createVariable({prefix:"F"}, feedFormat);
+var sOutput = createVariable({prefix:"S", force:true}, rpmFormat);
+var dOutput = createVariable({}, dFormat);
+
+// circular output
+var iOutput = createReferenceVariable({prefix:"I", force:true}, xyzFormat);
+var jOutput = createReferenceVariable({prefix:"J", force:true}, xyzFormat);
+var kOutput = createReferenceVariable({prefix:"K", force:true}, xyzFormat);
+
+var gMotionModal = createModal({}, gFormat); // modal group 1 // G0-G3, ...
+var gPlaneModal = createModal({onchange:function () {gMotionModal.reset();}}, gFormat); // modal group 2 // G17-19
+var gAbsIncModal = createModal({}, gFormat); // modal group 3 // G90-91
+var gFeedModeModal = createModal({}, gFormat); // modal group 5 // G93-94
+var gUnitModal = createModal({}, gFormat); // modal group 6 // G20-21
+var gRetractModal = createModal({}, gFormat); // modal group 10 // G98-99
+
+var WARNING_WORK_OFFSET = 0;
+
+// collected state
+var sequenceNumber;
+var currentWorkOffset;
+var retracted = false; // specifies that the tool has been retracted to the safe plane
+
+/**
+  Writes the specified block.
+*/
+function writeBlock() {
+  if (!formatWords(arguments)) {
+    return;
+  }
+  if (properties.showSequenceNumbers) {
+    writeWords2(nFormat.format(sequenceNumber % 100000), arguments);
+    sequenceNumber += properties.sequenceNumberIncrement;
+  } else {
+    writeWords(arguments);
+  }
+}
+
+/**
+  Output a comment.
+*/
+function writeComment(text) {
+  //writeln("(" + filterText(String(text).toUpperCase(), permittedCommentChars) + ")");  // disabling comments
+}
+
+function onOpen() {
+  if (properties.useRadius) {
+    maximumCircularSweep = toRad(90); // avoid potential center calculation errors for CNC
+  }
+
+  if (!machineConfiguration.isMachineCoordinate(0)) {
+    aOutput.disable();
+  }
+  if (!machineConfiguration.isMachineCoordinate(1)) {
+    bOutput.disable();
+  }
+  if (!machineConfiguration.isMachineCoordinate(2)) {
+    cOutput.disable();
+  }
+  
+  if (!properties.separateWordsWithSpace) {
+    setWordSeparator("");
+  }
+
+  sequenceNumber = properties.sequenceNumberStart;
+
+  if (programName) {
+    writeComment(programName);
+  }
+  if (programComment) {
+    writeComment(programComment);
+  }
+
+  // dump machine configuration
+  var vendor = machineConfiguration.getVendor();
+  var model = machineConfiguration.getModel();
+  var description = machineConfiguration.getDescription();
+
+  if (properties.writeMachine && (vendor || model || description)) {
+    writeComment(localize("Machine"));
+    if (vendor) {
+      writeComment("  " + localize("vendor") + ": " + vendor);
+    }
+    if (model) {
+      writeComment("  " + localize("model") + ": " + model);
+    }
+    if (description) {
+      writeComment("  " + localize("description") + ": "  + description);
+    }
+  }
+
+  // dump tool information
+  if (properties.writeTools) {
+    var zRanges = {};
+    if (is3D()) {
+      var numberOfSections = getNumberOfSections();
+      for (var i = 0; i < numberOfSections; ++i) {
+        var section = getSection(i);
+        var zRange = section.getGlobalZRange();
+        var tool = section.getTool();
+        if (zRanges[tool.number]) {
+          zRanges[tool.number].expandToRange(zRange);
+        } else {
+          zRanges[tool.number] = zRange;
+        }
+      }
+    }
+
+    var tools = getToolTable();
+    if (tools.getNumberOfTools() > 0) {
+      for (var i = 0; i < tools.getNumberOfTools(); ++i) {
+        var tool = tools.getTool(i);
+        var comment = "T" + toolFormat.format(tool.number) + "  " +
+          "D=" + xyzFormat.format(tool.diameter) + " " +
+          localize("CR") + "=" + xyzFormat.format(tool.cornerRadius);
+        if ((tool.taperAngle > 0) && (tool.taperAngle < Math.PI)) {
+          comment += " " + localize("TAPER") + "=" + taperFormat.format(tool.taperAngle) + localize("deg");
+        }
+        if (zRanges[tool.number]) {
+          comment += " - " + localize("ZMIN") + "=" + xyzFormat.format(zRanges[tool.number].getMinimum());
+        }
+        comment += " - " + getToolTypeName(tool.type);
+        //writeComment(comment);
+      }
+    }
+  }
+  
+  if (false) {
+    // check for duplicate tool number
+    for (var i = 0; i < getNumberOfSections(); ++i) {
+      var sectioni = getSection(i);
+      var tooli = sectioni.getTool();
+      for (var j = i + 1; j < getNumberOfSections(); ++j) {
+        var sectionj = getSection(j);
+        var toolj = sectionj.getTool();
+        if (tooli.number == toolj.number) {
+          if (xyzFormat.areDifferent(tooli.diameter, toolj.diameter) ||
+              xyzFormat.areDifferent(tooli.cornerRadius, toolj.cornerRadius) ||
+              abcFormat.areDifferent(tooli.taperAngle, toolj.taperAngle) ||
+              (tooli.numberOfFlutes != toolj.numberOfFlutes)) {
+            error(
+              subst(
+                localize("Using the same tool number for different cutter geometry for operation '%1' and '%2'."),
+                sectioni.hasParameter("operation-comment") ? sectioni.getParameter("operation-comment") : ("#" + (i + 1)),
+                sectionj.hasParameter("operation-comment") ? sectionj.getParameter("operation-comment") : ("#" + (j + 1))
+              )
+            );
+            return;
+          }
+        }
+      }
+    }
+  }
+
+  // absolute coordinates and feed per min
+  writeBlock(gFormat.format(20));
+  writeBlock(gAbsIncModal.format(90));
+  writeBlock(gFeedModeModal.format(94));
+
+  // switch (unit) { // probably want to wake this back up to handle mm but killing for now
+  // case IN:
+  //   writeBlock(gUnitModal.format(20));
+  //   break;
+  // case MM:
+  //   writeBlock(gUnitModal.format(21));
+  //   break;
+  // }
+}
+
+function onComment(message) {
+  var comments = String(message).split(";");
+  for (comment in comments) {
+    writeComment(comments[comment]);
+  }
+}
+
+/** Force output of X, Y, and Z. */
+function forceXYZ() {
+  xOutput.reset();
+  yOutput.reset();
+  zOutput.reset();
+}
+
+/** Force output of A, B, and C. */
+function forceABC() {
+  aOutput.reset();
+  bOutput.reset();
+  cOutput.reset();
+}
+
+/** Force output of X, Y, Z, A, B, C, and F on next output. */
+function forceAny() {
+  forceXYZ();
+  forceABC();
+  feedOutput.reset();
+}
+
+var currentWorkPlaneABC = undefined;
+
+function forceWorkPlane() {
+  currentWorkPlaneABC = undefined;
+}
+
+function setWorkPlane(abc) {
+  if (!machineConfiguration.isMultiAxisConfiguration()) {
+    return; // ignore
+  }
+
+  if (!((currentWorkPlaneABC == undefined) ||
+        abcFormat.areDifferent(abc.x, currentWorkPlaneABC.x) ||
+        abcFormat.areDifferent(abc.y, currentWorkPlaneABC.y) ||
+        abcFormat.areDifferent(abc.z, currentWorkPlaneABC.z))) {
+    return; // no change
+  }
+
+  onCommand(COMMAND_UNLOCK_MULTI_AXIS);
+
+  if (!retracted) {
+    writeRetract(Z);
+  }
+
+  writeBlock(
+    gMotionModal.format(0),
+    conditional(machineConfiguration.isMachineCoordinate(0), "A" + abcFormat.format(abc.x)),
+    conditional(machineConfiguration.isMachineCoordinate(1), "B" + abcFormat.format(abc.y)),
+    conditional(machineConfiguration.isMachineCoordinate(2), "C" + abcFormat.format(abc.z))
+  );
+  
+  onCommand(COMMAND_LOCK_MULTI_AXIS);
+
+  currentWorkPlaneABC = abc;
+}
+
+var closestABC = false; // choose closest machine angles
+var currentMachineABC;
+
+function getWorkPlaneMachineABC(workPlane) {
+  var W = workPlane; // map to global frame
+
+  var abc = machineConfiguration.getABC(W);
+  if (closestABC) {
+    if (currentMachineABC) {
+      abc = machineConfiguration.remapToABC(abc, currentMachineABC);
+    } else {
+      abc = machineConfiguration.getPreferredABC(abc);
+    }
+  } else {
+    abc = machineConfiguration.getPreferredABC(abc);
+  }
+  
+  try {
+    abc = machineConfiguration.remapABC(abc);
+    currentMachineABC = abc;
+  } catch (e) {
+    error(
+      localize("Machine angles not supported") + ":"
+      + conditional(machineConfiguration.isMachineCoordinate(0), " A" + abcFormat.format(abc.x))
+      + conditional(machineConfiguration.isMachineCoordinate(1), " B" + abcFormat.format(abc.y))
+      + conditional(machineConfiguration.isMachineCoordinate(2), " C" + abcFormat.format(abc.z))
+    );
+  }
+  
+  var direction = machineConfiguration.getDirection(abc);
+  if (!isSameDirection(direction, W.forward)) {
+    error(localize("Orientation not supported."));
+  }
+  
+  if (!machineConfiguration.isABCSupported(abc)) {
+    error(
+      localize("Work plane is not supported") + ":"
+      + conditional(machineConfiguration.isMachineCoordinate(0), " A" + abcFormat.format(abc.x))
+      + conditional(machineConfiguration.isMachineCoordinate(1), " B" + abcFormat.format(abc.y))
+      + conditional(machineConfiguration.isMachineCoordinate(2), " C" + abcFormat.format(abc.z))
+    );
+  }
+
+  var tcp = true;
+  if (tcp) {
+    setRotation(W); // TCP mode
+  } else {
+    var O = machineConfiguration.getOrientation(abc);
+    var R = machineConfiguration.getRemainingOrientation(abc, W);
+    setRotation(R);
+  }
+  
+  return abc;
+}
+
+function isProbeOperation() {
+  return hasParameter("operation-strategy") && (getParameter("operation-strategy") == "probe");
+}
+
+function onSection() {
+  var insertToolCall = isFirstSection() ||
+    currentSection.getForceToolChange && currentSection.getForceToolChange() ||
+    (tool.number != getPreviousSection().getTool().number);
+  
+  retracted = false;
+  var newWorkOffset = isFirstSection() ||
+    (getPreviousSection().workOffset != currentSection.workOffset); // work offset changes
+  var newWorkPlane = isFirstSection() ||
+    !isSameDirection(getPreviousSection().getGlobalFinalToolAxis(), currentSection.getGlobalInitialToolAxis()) ||
+    (currentSection.isOptimizedForMachine() && getPreviousSection().isOptimizedForMachine() &&
+      Vector.diff(getPreviousSection().getFinalToolAxisABC(), currentSection.getInitialToolAxisABC()).length > 1e-4) ||
+    (!machineConfiguration.isMultiAxisConfiguration() && currentSection.isMultiAxis()) ||
+    (!getPreviousSection().isMultiAxis() && currentSection.isMultiAxis() ||
+      getPreviousSection().isMultiAxis() && !currentSection.isMultiAxis()); // force newWorkPlane between indexing and simultaneous operations
+  if (insertToolCall || newWorkOffset || newWorkPlane) {
+    
+    // retract to safe plane
+    writeRetract(Z);
+  }
+
+  writeln("");
+
+  if (hasParameter("operation-comment")) {
+    var comment = getParameter("operation-comment");
+    if (comment) {
+      writeComment(comment);
+    }
+  }
+
+  var wait = false;
+  if (!properties.useToolChanger) {
+    var nextTool = getNextTool(tool.number);
+    if (nextTool) {
+      error(localize("Only one tool allowed per program."));
+      return;
+    }
+  }
+
+  if (insertToolCall) {
+    forceWorkPlane();
+    
+    onCommand(COMMAND_STOP_SPINDLE);
+    setCoolant(COOLANT_OFF);
+  
+    if (!isFirstSection() && properties.optionalStop) {
+      onCommand(COMMAND_OPTIONAL_STOP);
+    }
+
+    if (tool.number > 99) {
+      warning(localize("Tool number exceeds maximum value."));
+    }
+
+    //writeBlock("T" + toolFormat.format(tool.number), conditional(properties.useToolChanger, mFormat.format(6)));
+    if (tool.comment) {
+      //writeComment(tool.comment);
+    }
+    var showToolZMin = false;
+    if (showToolZMin) {
+      if (is3D()) {
+        var numberOfSections = getNumberOfSections();
+        var zRange = currentSection.getGlobalZRange();
+        var number = tool.number;
+        for (var i = currentSection.getId() + 1; i < numberOfSections; ++i) {
+          var section = getSection(i);
+          if (section.getTool().number != number) {
+            break;
+          }
+          zRange.expandToRange(section.getGlobalZRange());
+        }
+        writeComment(localize("ZMIN") + "=" + zRange.getMinimum());
+      }
+    }
+
+    if (!properties.useActiveSpindle) {
+      wait = true;
+    }
+
+  }
+  
+  if (insertToolCall ||
+      isFirstSection() ||
+      (rpmFormat.areDifferent(spindleSpeed, sOutput.getCurrent())) ||
+      (tool.clockwise != getPreviousSection().getTool().clockwise)) {
+    if (spindleSpeed < 1) {
+      error(localize("Spindle speed out of range."));
+      return;
+    }
+    if (spindleSpeed > 99999) {
+      warning(localize("Spindle speed exceeds maximum value."));
+    }
+    if (properties.useActiveSpindle) {
+      writeBlock(
+        sOutput.format(spindleSpeed), mFormat.format(tool.clockwise ? 3 : 4)
+      );
+      onDwell(4);
+    } else {
+      sOutput.format(spindleSpeed);
+      writeComment(
+        "S" + rpmFormat.format(spindleSpeed) + " " + mFormat.format(tool.clockwise ? 3 : 4)
+      );
+      wait = true;
+    }
+  }
+
+  if (wait) {
+    onCommand(COMMAND_STOP);
+  }
+
+  // wcs - Otherplan only uses G55
+  //writeBlock(gFormat.format(55));
+
+  /*
+  if (insertToolCall) { // force work offset when changing tool
+    currentWorkOffset = undefined;
+  }
+  var workOffset = currentSection.workOffset;
+  if (workOffset == 0) {
+    warningOnce(localize("Work offset has not been specified. Using G54 as WCS."), WARNING_WORK_OFFSET);
+    workOffset = 1;
+  }
+  if (workOffset > 0) {
+    if (workOffset > 6) {
+      error(localize("Work offset out of range."));
+    } else {
+      if (workOffset != currentWorkOffset) {
+        writeBlock(gFormat.format(53 + workOffset)); // G54->G59
+        currentWorkOffset = workOffset;
+      }
+    }
+  }
+*/
+
+  forceXYZ();
+
+  if (machineConfiguration.isMultiAxisConfiguration()) { // use 5-axis indexing for multi-axis mode
+    // set working plane after datum shift
+
+    var abc = new Vector(0, 0, 0);
+    if (currentSection.isMultiAxis()) {
+      forceWorkPlane();
+      cancelTransformation();
+    } else {
+      abc = getWorkPlaneMachineABC(currentSection.workPlane);
+    }
+    setWorkPlane(abc);
+  } else { // pure 3D
+    var remaining = currentSection.workPlane;
+    if (!isSameDirection(remaining.forward, new Vector(0, 0, 1))) {
+      error(localize("Tool orientation is not supported."));
+      return;
+    }
+    setRotation(remaining);
+  }
+
+  // set coolant after we have positioned at Z
+  setCoolant(tool.coolant);
+
+  forceAny();
+  gMotionModal.reset();
+
+  var initialPosition = getFramePosition(currentSection.getInitialPosition());
+  if (!retracted && !insertToolCall) {
+    if (getCurrentPosition().z < initialPosition.z) {
+      gMotionModal.reset();
+      writeBlock(gMotionModal.format(0), zOutput.format(initialPosition.z));
+    }
+  }
+
+  if (insertToolCall || retracted) {
+    var lengthOffset = tool.lengthOffset;
+    if (lengthOffset > 99) {
+      error(localize("Length offset out of range."));
+      return;
+    }
+
+    gMotionModal.reset();
+    //writeBlock(gPlaneModal.format(17));
+    
+    if (!machineConfiguration.isHeadConfiguration()) {
+      gMotionModal.reset();
+      writeBlock(gMotionModal.format(0), /*gFormat.format(43),*/ zOutput.format(initialPosition.z) /*, hFormat.format(lengthOffset)*/);
+      gMotionModal.reset();
+      writeBlock(
+        gAbsIncModal.format(90),
+        gMotionModal.format(0), xOutput.format(initialPosition.x), yOutput.format(initialPosition.y)
+      );
+      
+    } else {
+      gMotionModal.reset();
+      writeBlock(
+        gAbsIncModal.format(90),
+        gMotionModal.format(0),
+        /*gFormat.format(43),*/ xOutput.format(initialPosition.x),
+        yOutput.format(initialPosition.y),
+        zOutput.format(initialPosition.z) //, hFormat.format(lengthOffset)
+      );
+    }
+  } else {
+    gMotionModal.reset();
+    writeBlock(
+      gAbsIncModal.format(90),
+      gMotionModal.format(0),
+      xOutput.format(initialPosition.x),
+      yOutput.format(initialPosition.y)
+    );
+  }
+}
+
+function onDwell(seconds) {
+  if (seconds > 99999.999) {
+    warning(localize("Dwelling time is out of range."));
+  }
+  //writeBlock(gFormat.format(4), "P" + secFormat.format(seconds)); // don't have dwell implemented so killing it
+
+}
+
+function onSpindleSpeed(spindleSpeed) {
+  if (properties.useActiveSpindle) {
+    writeBlock(sOutput.format(spindleSpeed));
+  } else {
+    writeComment(sOutput.format(spindleSpeed));
+    onCommand(COMMAND_STOP);
+  }
+}
+
+var pendingRadiusCompensation = -1;
+
+function onRadiusCompensation() {
+  pendingRadiusCompensation = radiusCompensation;
+}
+
+function onRapid(_x, _y, _z) {
+  var x = xOutput.format(_x);
+  var y = yOutput.format(_y);
+  var z = zOutput.format(_z);
+  if (x || y || z) {
+    if (pendingRadiusCompensation >= 0) {
+      error(localize("Radius compensation mode cannot be changed at rapid traversal."));
+      return;
+    }
+    gMotionModal.reset();
+    writeBlock(gMotionModal.format(0), x, y, z);
+    feedOutput.reset();
+  }
+}
+
+function onLinear(_x, _y, _z, feed) {
+  var x = xOutput.format(_x);
+  var y = yOutput.format(_y);
+  var z = zOutput.format(_z);
+  var f = feedOutput.format(feed/60); // dividing by 60 b/c min/sec
+  if (x || y || z) {
+    if (pendingRadiusCompensation >= 0) {
+      pendingRadiusCompensation = -1;
+      var d = tool.diameterOffset;
+      if (d > 99) {
+        warning(localize("The diameter offset exceeds the maximum value."));
+      }
+      writeBlock(gPlaneModal.format(17));
+      switch (radiusCompensation) {
+      case RADIUS_COMPENSATION_LEFT:
+        error(localize("Cutter compensation with G41 is not supported by CNC control."));
+        return;
+        // dOutput.reset();
+        // writeBlock(gMotionModal.format(1), gFormat.format(41), x, y, z, dOutput.format(d), f);
+        // break;
+      case RADIUS_COMPENSATION_RIGHT:
+        error(localize("Cutter compensation with G42 is not supported by CNC control."));
+        return;
+        // dOutput.reset();
+        // writeBlock(gMotionModal.format(1), gFormat.format(42), x, y, z, dOutput.format(d), f);
+        // break;
+      default:
+        //forceXYZ();
+        gMotionModal.reset();
+        writeBlock(gMotionModal.format(1), gFormat.format(40), x, y, z, f);
+      }
+    } else {
+      //forceXYZ();
+      gMotionModal.reset();
+      writeBlock(gMotionModal.format(1), x, y, z, f);
+    }
+  } else if (f) {
+    feedOutput.reset(); // F requires at least one axis
+  }
+}
+
+function onRapid5D(_x, _y, _z, _a, _b, _c) {
+  if (!currentSection.isOptimizedForMachine()) {
+    error(localize("This post configuration has not been customized for 5-axis simultaneous toolpath."));
+    return;
+  }
+  
+  if (pendingRadiusCompensation >= 0) {
+    error(localize("Radius compensation mode cannot be changed at rapid traversal."));
+    return;
+  }
+  var x = xOutput.format(_x);
+  var y = yOutput.format(_y);
+  var z = zOutput.format(_z);
+  var a = aOutput.format(_a);
+  var b = bOutput.format(_b);
+  var c = cOutput.format(_c);
+  gMotionModal.reset();
+  writeBlock(gMotionModal.format(0), x, y, z, a, b, c);
+  feedOutput.reset();
+}
+
+function onLinear5D(_x, _y, _z, _a, _b, _c, feed) {
+  if (!currentSection.isOptimizedForMachine()) {
+    error(localize("This post configuration has not been customized for 5-axis simultaneous toolpath."));
+    return;
+  }
+  
+  if (pendingRadiusCompensation >= 0) {
+    error(localize("Radius compensation cannot be activated/deactivated for 5-axis move."));
+    return;
+  }
+  var x = xOutput.format(_x);
+  var y = yOutput.format(_y);
+  var z = zOutput.format(_z);
+  var a = aOutput.format(_a);
+  var b = bOutput.format(_b);
+  var c = cOutput.format(_c);
+  var f = feedOutput.format(feed/60); // b/c min/sec
+  if (x || y || z || a || b || c) {
+    writeBlock(gMotionModal.format(1), x, y, z, a, b, c, f);
+  } else if (f) {
+    feedOutput.reset(); // F requires at least one axis
+  }
+}
+
+function onCircular(clockwise, cx, cy, cz, x, y, z, feed) {
+  if (pendingRadiusCompensation >= 0) {
+    error(localize("Radius compensation cannot be activated/deactivated for a circular move."));
+    return;
+  }
+
+  var start = getCurrentPosition();
+
+  if (isFullCircle()) {
+    if (properties.useRadius || isHelical()) { // radius mode does not support full arcs
+      linearize(tolerance);
+      return;
+    }
+    switch (getCircularPlane()) {
+    case PLANE_XY:
+      writeBlock(gAbsIncModal.format(90), gPlaneModal.format(17), gMotionModal.format(clockwise ? 2 : 3), iOutput.format(cx - start.x, 0), jOutput.format(cy - start.y, 0), feedOutput.format(feed/60));
+      break;
+    case PLANE_ZX:
+      writeBlock(gAbsIncModal.format(90), gPlaneModal.format(18), gMotionModal.format(clockwise ? 2 : 3), iOutput.format(cx - start.x, 0), kOutput.format(cz - start.z, 0), feedOutput.format(feed/60));
+      break;
+    case PLANE_YZ:
+      writeBlock(gAbsIncModal.format(90), gPlaneModal.format(19), gMotionModal.format(clockwise ? 2 : 3), jOutput.format(cy - start.y, 0), kOutput.format(cz - start.z, 0), feedOutput.format(feed/60));
+      break;
+    default:
+      linearize(tolerance);
+    }
+  } else if (!properties.useRadius) {
+    switch (getCircularPlane()) {
+    case PLANE_XY:
+      writeBlock(gAbsIncModal.format(90), gPlaneModal.format(17), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), iOutput.format(cx - start.x, 0), jOutput.format(cy - start.y, 0), feedOutput.format(feed));
+      break;
+    case PLANE_ZX:
+      writeBlock(gAbsIncModal.format(90), gPlaneModal.format(18), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), iOutput.format(cx - start.x, 0), kOutput.format(cz - start.z, 0), feedOutput.format(feed));
+      break;
+    case PLANE_YZ:
+      writeBlock(gAbsIncModal.format(90), gPlaneModal.format(19), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), jOutput.format(cy - start.y, 0), kOutput.format(cz - start.z, 0), feedOutput.format(feed));
+      break;
+    default:
+      linearize(tolerance);
+    }
+  } else { // use radius mode
+    var r = getCircularRadius();
+    if (toDeg(getCircularSweep()) > 180) {
+      r = -r; // allow up to <360 deg arcs
+    }
+    switch (getCircularPlane()) {
+    case PLANE_XY:
+      writeBlock(gPlaneModal.format(17), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), "R" + rFormat.format(r), feedOutput.format(feed/60));
+      break;
+    case PLANE_ZX:
+      writeBlock(gPlaneModal.format(18), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), "R" + rFormat.format(r), feedOutput.format(feed/60));
+      break;
+    case PLANE_YZ:
+      writeBlock(gPlaneModal.format(19), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), "R" + rFormat.format(r), feedOutput.format(feed/60));
+      break;
+    default:
+      linearize(tolerance);
+    }
+  }
+}
+
+var currentCoolantMode = COOLANT_OFF;
+var coolantOff = undefined;
+
+function setCoolant(coolant) {
+  var coolantCodes = getCoolantCodes(coolant);
+  if (Array.isArray(coolantCodes)) {
+    if (singleLineCoolant) {
+      //writeBlock(coolantCodes.join(getWordSeparator()));
+    } else {
+      for (var c in coolantCodes) {
+        //writeBlock(coolantCodes[c]);
+      }
+    }
+    return undefined;
+  }
+  return coolantCodes;
+}
+
+function getCoolantCodes(coolant) {
+  var multipleCoolantBlocks = new Array(); // create a formatted array to be passed into the outputted line
+  if (!coolants) {
+    error(localize("Coolants have not been defined."));
+  }
+  if (isProbeOperation()) { // avoid coolant output for probing
+    coolant = COOLANT_OFF;
+  }
+  if (coolant == currentCoolantMode) {
+    return undefined; // coolant is already active
+  }
+  if ((coolant != COOLANT_OFF) && (currentCoolantMode != COOLANT_OFF) && (coolantOff != undefined)) {
+    if (Array.isArray(coolantOff)) {
+      for (var i in coolantOff) {
+        //multipleCoolantBlocks.push(mFormat.format(coolantOff[i]));
+      }
+    } else {
+     // multipleCoolantBlocks.push(mFormat.format(coolantOff));
+    }
+  }
+
+  var m;
+  var coolantCodes = {};
+  for (var c in coolants) { // find required coolant codes into the coolants array
+    if (coolants[c].id == coolant) {
+      coolantCodes.on = coolants[c].on;
+      if (coolants[c].off != undefined) {
+        coolantCodes.off = coolants[c].off;
+        break;
+      } else {
+        for (var i in coolants) {
+          if (coolants[i].id == COOLANT_OFF) {
+            coolantCodes.off = coolants[i].off;
+            break;
+          }
+        }
+      }
+    }
+  }
+  if (coolant == COOLANT_OFF) {
+    m = !coolantOff ? coolantCodes.off : coolantOff; // use the default coolant off command when an 'off' value is not specified
+  } else {
+    coolantOff = coolantCodes.off;
+    m = coolantCodes.on;
+  }
+
+  if (!m) {
+    onUnsupportedCoolant(coolant);
+    m = 9;
+  } else {
+    if (Array.isArray(m)) {
+      for (var i in m) {
+        multipleCoolantBlocks.push(mFormat.format(m[i]));
+      }
+    } else {
+      multipleCoolantBlocks.push(mFormat.format(m));
+    }
+    currentCoolantMode = coolant;
+    return multipleCoolantBlocks; // return the single formatted coolant value
+  }
+  return undefined;
+}
+
+var mapCommand = {
+  COMMAND_STOP:0,
+  COMMAND_OPTIONAL_STOP:1,
+  COMMAND_END:2,
+  COMMAND_SPINDLE_CLOCKWISE:3,
+  COMMAND_SPINDLE_COUNTERCLOCKWISE:4,
+  COMMAND_STOP_SPINDLE:5,
+  COMMAND_LOAD_TOOL:6
+};
+
+function onCommand(command) {
+  switch (command) {
+  case COMMAND_SPINDLE_CLOCKWISE:
+  case COMMAND_SPINDLE_COUNTERCLOCKWISE:
+  case COMMAND_STOP_SPINDLE:
+    if (!properties.useActiveSpindle) {
+      return;
+    }
+    break;
+  case COMMAND_START_SPINDLE:
+    onCommand(tool.clockwise ? COMMAND_SPINDLE_CLOCKWISE : COMMAND_SPINDLE_COUNTERCLOCKWISE);
+    return;
+  case COMMAND_LOCK_MULTI_AXIS:
+    return;
+  case COMMAND_UNLOCK_MULTI_AXIS:
+    return;
+  case COMMAND_BREAK_CONTROL:
+    return;
+  case COMMAND_TOOL_MEASURE:
+    return;
+  }
+  
+  var stringId = getCommandStringId(command);
+  var mcode = mapCommand[stringId];
+  if (mcode != undefined) {
+    writeBlock(mFormat.format(mcode));
+  } else {
+    onUnsupportedCommand(command);
+  }
+}
+
+function onSectionEnd() {
+  writeBlock(gPlaneModal.format(17));
+  if (!isLastSection() && (getNextSection().getTool().coolant != tool.coolant)) {
+    setCoolant(COOLANT_OFF);
+  }
+  if (((getCurrentSectionId() + 1) >= getNumberOfSections()) ||
+      (tool.number != getNextSection().getTool().number)) {
+    onCommand(COMMAND_BREAK_CONTROL);
+  }
+
+  forceAny();
+}
+
+/** Output block to do safe retract and/or move to home position. */
+function writeRetract() {
+  if (arguments.length == 0) {
+    error(localize("No axis specified for writeRetract()."));
+    return;
+  }
+  var words = []; // store all retracted axes in an array
+  for (var i = 0; i < arguments.length; ++i) {
+    let instances = 0; // checks for duplicate retract calls
+    for (var j = 0; j < arguments.length; ++j) {
+      if (arguments[i] == arguments[j]) {
+        ++instances;
+      }
+    }
+    if (instances > 1) { // error if there are multiple retract calls for the same axis
+      error(localize("Cannot retract the same axis twice in one line"));
+      return;
+    }
+    switch (arguments[i]) {
+    case X:
+      words.push("X" + xyzFormat.format(machineConfiguration.hasHomePositionX() ? machineConfiguration.getHomePositionX() : 0));
+      break;
+    case Y:
+      words.push("Y" + xyzFormat.format(machineConfiguration.hasHomePositionY() ? machineConfiguration.getHomePositionY() : 0));
+      break;
+    case Z:
+      words.push("Z" + xyzFormat.format(machineConfiguration.getRetractPlane()));
+      retracted = true; // specifies that the tool has been retracted to the safe plane
+      break;
+    default:
+      error(localize("Bad axis specified for writeRetract()."));
+      return;
+    }
+  }
+  if (words.length > 0) {
+    //writeBlock(gAbsIncModal.format(90), gFormat.format(53), gMotionModal.format(0), words); // retract
+  }
+  zOutput.reset();
+}
+
+function onClose() {
+  writeln("");
+
+  setCoolant(COOLANT_OFF);
+
+  writeRetract(Z);
+
+  setWorkPlane(new Vector(0, 0, 0)); // reset working plane
+
+  if (machineConfiguration.hasHomePositionX() || machineConfiguration.hasHomePositionY()) {
+    writeRetract(X, Y);
+  }
+
+  onImpliedCommand(COMMAND_END);
+  onImpliedCommand(COMMAND_STOP_SPINDLE);
+  writeBlock(mFormat.format(5)); // stop program, spindle stop, coolant off
+  writeBlock(mFormat.format(30)); // stop program, spindle stop, coolant off
+}
diff --git a/README.md b/README.md
index 016633fc6afa2d614036a6e9193832689bb5ac2b..91a2457f8e97e14ca2b95b92a57a984510dff7b9 100644
--- a/README.md
+++ b/README.md
@@ -28,6 +28,8 @@ You should be able to do `platformio: build` from VSCode's little internal comma
 
 Build also works with `ctrl + alt + b`  
 
+#### Configuring Motor Firmware
+
 In `src/main.cpp` for the stepper motor firmware, you'll find this little snippet:
 
 ```cpp
@@ -41,6 +43,15 @@ In `src/main.cpp` for the stepper motor firmware, you'll find this little snippe
 
 These are motor-specific settings. The selection above is for an updated Z motor with less current scaling than what was originally flashed in the kits (the C_SCALE value). You'll need to swap these around when you flash different motors. 
 
+#### Configuring PSU Breakout (Bus Head) Firmware
+
+In 'src/config.h' for the psu-breakout (osape-smoothieroll-head) firmware, you need to do the following:
+
+- if the circuit module (https://gitlab.cba.mit.edu/jakeread/ucbus-module) on the psu-breakout (https://gitlab.cba.mit.edu/jakeread/ucbus-psu-breakout) **has a surface mount JTAG connctor** - leave the file as is, like this:
+    - `#define IS_OG_CLANK`
+- if the module **has a through-hole JTAG connector**, comment this line out
+    - `//#define IS_OG_CLANK`
+
 #### Build Errors 
 
 Platformio does not like long project directories: if you get errors for missing files, try moving the project folder higher up the path tree. 
diff --git a/firmware/osape-smoothieroll-drop-esc/src/drivers/ucbus_drop.h b/firmware/osape-smoothieroll-drop-esc/src/drivers/ucbus_drop.h
index de1d55eae2f771880b5f140450cf6033fa0d001c..7443288b1b113a42cbb9f0742f30bead20f6c90e 100644
--- a/firmware/osape-smoothieroll-drop-esc/src/drivers/ucbus_drop.h
+++ b/firmware/osape-smoothieroll-drop-esc/src/drivers/ucbus_drop.h
@@ -15,7 +15,7 @@ is; no warranty is provided, and users accept all liability.
 #ifndef UCBUS_DROP_H_
 #define UCBUS_DROP_H_
 
-#include <arduino.h>
+#include <Arduino.h>
 
 #include "indicators.h"
 #include "dip_ucbus_config.h"
diff --git a/firmware/osape-smoothieroll-drop-esc/src/osap/osap.h b/firmware/osape-smoothieroll-drop-esc/src/osap/osap.h
index 5242ba0ae6cdc77538ef57f119a6691fb46188fa..5d7608120938757d43d9f376bf1c0198acc5e5bb 100644
--- a/firmware/osape-smoothieroll-drop-esc/src/osap/osap.h
+++ b/firmware/osape-smoothieroll-drop-esc/src/osap/osap.h
@@ -15,7 +15,7 @@ no warranty is provided, and users accept all liability.
 #ifndef OSAP_H_
 #define OSAP_H_
 
-#include <arduino.h>
+#include <Arduino.h>
 #include "ts.h"
 #include "vport.h"
 #include "./drivers/indicators.h"
diff --git a/firmware/osape-smoothieroll-drop-esc/src/osap/ts.h b/firmware/osape-smoothieroll-drop-esc/src/osap/ts.h
index 1029171322097efa534c83d8db9c2ee835024ffc..e2723fc129cf7d89c7d335cbcb914aa2e47f3cfa 100644
--- a/firmware/osape-smoothieroll-drop-esc/src/osap/ts.h
+++ b/firmware/osape-smoothieroll-drop-esc/src/osap/ts.h
@@ -12,7 +12,7 @@ Copyright is retained and must be preserved. The work is provided as is;
 no warranty is provided, and users accept all liability.
 */
 
-#include <arduino.h>
+#include <Arduino.h>
 
 // -------------------------------------------------------- Routing (Packet) Keys
 
diff --git a/firmware/osape-smoothieroll-drop-esc/src/osap/vport.h b/firmware/osape-smoothieroll-drop-esc/src/osap/vport.h
index b705e91a150ff544b2efa0ceba17f4f6b3b515eb..cb9c90944e9b082c716adaa794b2f74d7390f880 100644
--- a/firmware/osape-smoothieroll-drop-esc/src/osap/vport.h
+++ b/firmware/osape-smoothieroll-drop-esc/src/osap/vport.h
@@ -15,7 +15,7 @@ no warranty is provided, and users accept all liability.
 #ifndef VPORT_H_
 #define VPORT_H_
 
-#include <arduino.h>
+#include <Arduino.h>
 #include "./utils/syserror.h"
 
 class VPort {
diff --git a/firmware/osape-smoothieroll-drop-esc/src/osap/vport_usbserial.h b/firmware/osape-smoothieroll-drop-esc/src/osap/vport_usbserial.h
index 4a72d1ce9462ca8bf4ee76992d56c62a8a54a0cf..31434b738950150349a63847e829b6376733e961 100644
--- a/firmware/osape-smoothieroll-drop-esc/src/osap/vport_usbserial.h
+++ b/firmware/osape-smoothieroll-drop-esc/src/osap/vport_usbserial.h
@@ -15,7 +15,7 @@ no warranty is provided, and users accept all liability.
 #ifndef VPORT_USBSERIAL_H_
 #define VPORT_USBSERIAL_H_
 
-#include <arduino.h>
+#include <Arduino.h>
 #include "vport.h"
 #include "./utils/cobs.h"
 #include "./drivers/indicators.h"
diff --git a/firmware/osape-smoothieroll-drop-esc/src/utils/cobs.h b/firmware/osape-smoothieroll-drop-esc/src/utils/cobs.h
index a9e587463dc4cfc6f8175d0ff48b53174970133c..92208c31312b414d5938026d2e40551f4703819c 100644
--- a/firmware/osape-smoothieroll-drop-esc/src/utils/cobs.h
+++ b/firmware/osape-smoothieroll-drop-esc/src/utils/cobs.h
@@ -15,7 +15,7 @@ no warranty is provided, and users accept all liability.
 #ifndef UTIL_COBS_H_
 #define UTIL_COBS_H_
 
-#include <arduino.h>
+#include <Arduino.h>
 
 size_t cobsEncode(uint8_t *src, size_t len, uint8_t *dest);
 
diff --git a/firmware/osape-smoothieroll-drop-esc/src/utils/syserror.h b/firmware/osape-smoothieroll-drop-esc/src/utils/syserror.h
index b421cc2a08eb1d482a9f298ed9dbefaa90531f9d..9c53e37a23122e8021b7a7ac1175eb2e54c8e200 100644
--- a/firmware/osape-smoothieroll-drop-esc/src/utils/syserror.h
+++ b/firmware/osape-smoothieroll-drop-esc/src/utils/syserror.h
@@ -1,7 +1,7 @@
 #ifndef SYSERROR_H_
 #define SYSERROR_H_
 
-#include <arduino.h>
+#include <Arduino.h>
 #include "./drivers/indicators.h"
 #include "./utils/cobs.h"
 #include "./osap/ts.h"
diff --git a/firmware/osape-smoothieroll-drop-stepper/src/drivers/dacs.h b/firmware/osape-smoothieroll-drop-stepper/src/drivers/dacs.h
index 6d095390582c08027f0bd3777136fed0e05edbf4..47678d32f66e3b915f88d56296ecf7aa6421d1dd 100644
--- a/firmware/osape-smoothieroll-drop-stepper/src/drivers/dacs.h
+++ b/firmware/osape-smoothieroll-drop-stepper/src/drivers/dacs.h
@@ -15,7 +15,7 @@ is; no warranty is provided, and users accept all liability.
 #ifndef DACS_H_
 #define DACS_H_
 
-#include <arduino.h>
+#include <Arduino.h>
 
 #include "indicators.h"
 #include "utils/syserror.h"
diff --git a/firmware/osape-smoothieroll-drop-stepper/src/drivers/step_a4950.h b/firmware/osape-smoothieroll-drop-stepper/src/drivers/step_a4950.h
index 4b4286892b6795fba07de2a4e63d9dba53059b4f..dd76f7c8ee6fb588be6a5649ecd1410d87df0976 100644
--- a/firmware/osape-smoothieroll-drop-stepper/src/drivers/step_a4950.h
+++ b/firmware/osape-smoothieroll-drop-stepper/src/drivers/step_a4950.h
@@ -15,7 +15,7 @@ is; no warranty is provided, and users accept all liability.
 #ifndef STEP_A4950_H_
 #define STEP_A4950_H_
 
-#include <arduino.h>
+#include <Arduino.h>
 
 #include "dacs.h"
 #include "indicators.h"
diff --git a/firmware/osape-smoothieroll-drop-stepper/src/drivers/ucbus_drop.h b/firmware/osape-smoothieroll-drop-stepper/src/drivers/ucbus_drop.h
index de1d55eae2f771880b5f140450cf6033fa0d001c..7443288b1b113a42cbb9f0742f30bead20f6c90e 100644
--- a/firmware/osape-smoothieroll-drop-stepper/src/drivers/ucbus_drop.h
+++ b/firmware/osape-smoothieroll-drop-stepper/src/drivers/ucbus_drop.h
@@ -15,7 +15,7 @@ is; no warranty is provided, and users accept all liability.
 #ifndef UCBUS_DROP_H_
 #define UCBUS_DROP_H_
 
-#include <arduino.h>
+#include <Arduino.h>
 
 #include "indicators.h"
 #include "dip_ucbus_config.h"
diff --git a/firmware/osape-smoothieroll-drop-stepper/src/main.cpp b/firmware/osape-smoothieroll-drop-stepper/src/main.cpp
index a8d84c723b663d977d00c59dafdbbaf8aa2f6b2a..9b8d350af79d41f482f9193aca0f6c00bc294132 100644
--- a/firmware/osape-smoothieroll-drop-stepper/src/main.cpp
+++ b/firmware/osape-smoothieroll-drop-stepper/src/main.cpp
@@ -19,11 +19,11 @@ union chunk_float64 {
   double f;
 };
 
-#define BUS_DROP 1    // Z: 1, YL: 2, X: 3, YR: 4
-#define AXIS_PICK 2   // Z: 2, Y: 1, X: 0
+#define BUS_DROP 4    // Z: 1, YL: 2, X: 3, YR: 4
+#define AXIS_PICK 1   // Z: 2, Y: 1, X: 0
 #define AXIS_INVERT false  // Z: false, YL: true, YR: false, X: false
-#define SPU 3200.0F // always positive! Z: 3200, XY: 400 
-#define C_SCALE 0.1F // 0-1, floating: initial holding current to motor, 0-2.5A 
+#define SPU 400.0F // always positive! Z: 3200, XY: 400 
+#define C_SCALE 0.2F // 0-1, floating: initial holding current to motor, 0-2.5A 
 #define TICKS_PER_PACKET 20.0F // always 20.0F
 
 void setup() {
diff --git a/firmware/osape-smoothieroll-drop-stepper/src/osap/osap.h b/firmware/osape-smoothieroll-drop-stepper/src/osap/osap.h
index 5242ba0ae6cdc77538ef57f119a6691fb46188fa..5d7608120938757d43d9f376bf1c0198acc5e5bb 100644
--- a/firmware/osape-smoothieroll-drop-stepper/src/osap/osap.h
+++ b/firmware/osape-smoothieroll-drop-stepper/src/osap/osap.h
@@ -15,7 +15,7 @@ no warranty is provided, and users accept all liability.
 #ifndef OSAP_H_
 #define OSAP_H_
 
-#include <arduino.h>
+#include <Arduino.h>
 #include "ts.h"
 #include "vport.h"
 #include "./drivers/indicators.h"
diff --git a/firmware/osape-smoothieroll-drop-stepper/src/osap/ts.h b/firmware/osape-smoothieroll-drop-stepper/src/osap/ts.h
index 1029171322097efa534c83d8db9c2ee835024ffc..e2723fc129cf7d89c7d335cbcb914aa2e47f3cfa 100644
--- a/firmware/osape-smoothieroll-drop-stepper/src/osap/ts.h
+++ b/firmware/osape-smoothieroll-drop-stepper/src/osap/ts.h
@@ -12,7 +12,7 @@ Copyright is retained and must be preserved. The work is provided as is;
 no warranty is provided, and users accept all liability.
 */
 
-#include <arduino.h>
+#include <Arduino.h>
 
 // -------------------------------------------------------- Routing (Packet) Keys
 
diff --git a/firmware/osape-smoothieroll-drop-stepper/src/osap/vport.h b/firmware/osape-smoothieroll-drop-stepper/src/osap/vport.h
index b705e91a150ff544b2efa0ceba17f4f6b3b515eb..cb9c90944e9b082c716adaa794b2f74d7390f880 100644
--- a/firmware/osape-smoothieroll-drop-stepper/src/osap/vport.h
+++ b/firmware/osape-smoothieroll-drop-stepper/src/osap/vport.h
@@ -15,7 +15,7 @@ no warranty is provided, and users accept all liability.
 #ifndef VPORT_H_
 #define VPORT_H_
 
-#include <arduino.h>
+#include <Arduino.h>
 #include "./utils/syserror.h"
 
 class VPort {
diff --git a/firmware/osape-smoothieroll-drop-stepper/src/osap/vport_usbserial.h b/firmware/osape-smoothieroll-drop-stepper/src/osap/vport_usbserial.h
index 4a72d1ce9462ca8bf4ee76992d56c62a8a54a0cf..31434b738950150349a63847e829b6376733e961 100644
--- a/firmware/osape-smoothieroll-drop-stepper/src/osap/vport_usbserial.h
+++ b/firmware/osape-smoothieroll-drop-stepper/src/osap/vport_usbserial.h
@@ -15,7 +15,7 @@ no warranty is provided, and users accept all liability.
 #ifndef VPORT_USBSERIAL_H_
 #define VPORT_USBSERIAL_H_
 
-#include <arduino.h>
+#include <Arduino.h>
 #include "vport.h"
 #include "./utils/cobs.h"
 #include "./drivers/indicators.h"
diff --git a/firmware/osape-smoothieroll-drop-stepper/src/utils/cobs.h b/firmware/osape-smoothieroll-drop-stepper/src/utils/cobs.h
index a9e587463dc4cfc6f8175d0ff48b53174970133c..92208c31312b414d5938026d2e40551f4703819c 100644
--- a/firmware/osape-smoothieroll-drop-stepper/src/utils/cobs.h
+++ b/firmware/osape-smoothieroll-drop-stepper/src/utils/cobs.h
@@ -15,7 +15,7 @@ no warranty is provided, and users accept all liability.
 #ifndef UTIL_COBS_H_
 #define UTIL_COBS_H_
 
-#include <arduino.h>
+#include <Arduino.h>
 
 size_t cobsEncode(uint8_t *src, size_t len, uint8_t *dest);
 
diff --git a/firmware/osape-smoothieroll-drop-stepper/src/utils/syserror.h b/firmware/osape-smoothieroll-drop-stepper/src/utils/syserror.h
index b421cc2a08eb1d482a9f298ed9dbefaa90531f9d..9c53e37a23122e8021b7a7ac1175eb2e54c8e200 100644
--- a/firmware/osape-smoothieroll-drop-stepper/src/utils/syserror.h
+++ b/firmware/osape-smoothieroll-drop-stepper/src/utils/syserror.h
@@ -1,7 +1,7 @@
 #ifndef SYSERROR_H_
 #define SYSERROR_H_
 
-#include <arduino.h>
+#include <Arduino.h>
 #include "./drivers/indicators.h"
 #include "./utils/cobs.h"
 #include "./osap/ts.h"
diff --git a/firmware/osape-smoothieroll-head/src/config.h b/firmware/osape-smoothieroll-head/src/config.h
new file mode 100644
index 0000000000000000000000000000000000000000..54b7933a39a877ffa6bb1e4f5a140a1abef31e4a
--- /dev/null
+++ b/firmware/osape-smoothieroll-head/src/config.h
@@ -0,0 +1,6 @@
+#ifndef CONFIG_H_
+#define CONFIG_H_
+
+#define IS_OG_CLANK
+
+#endif 
\ No newline at end of file
diff --git a/firmware/osape-smoothieroll-head/src/drivers/ucbus_head.cpp b/firmware/osape-smoothieroll-head/src/drivers/ucbus_head.cpp
index 8b6126d291820a3ce14225882a676f1fb6d11a82..c447b3a751d6ee00062d7f1f7b38cbbd32594396 100644
--- a/firmware/osape-smoothieroll-head/src/drivers/ucbus_head.cpp
+++ b/firmware/osape-smoothieroll-head/src/drivers/ucbus_head.cpp
@@ -14,6 +14,8 @@ is; no warranty is provided, and users accept all liability.
 
 #include "ucbus_head.h"
 
+#include "../config.h"
+
 UCBus_Head* UCBus_Head::instance = 0;
 
 UCBus_Head* UCBus_Head::getInstance(void){
@@ -36,7 +38,11 @@ void UCBus_Head::startupUART(void){
   UBH_DE_PORT.OUTSET.reg = UBH_DE_BM;
   // receive output is always on at head, set LO to enable
   UBH_RE_PORT.DIRSET.reg = UBH_RE_BM;
+  #ifdef IS_OG_CLANK
+  UBH_RE_PORT.OUTSET.reg = UBH_RE_BM;
+  #else 
   UBH_RE_PORT.OUTCLR.reg = UBH_RE_BM;
+  #endif 
   // termination resistor for receipt on bus head is on, set LO to enable 
   UBH_TE_PORT.DIRSET.reg = UBH_TE_BM;
   UBH_TE_PORT.OUTCLR.reg = UBH_TE_BM;
diff --git a/firmware/osape-smoothieroll-head/src/drivers/ucbus_head.h b/firmware/osape-smoothieroll-head/src/drivers/ucbus_head.h
index e171d1cff9c3df0201f7d050a5d6c78def310f79..c19df1e6a14b9209ab44af93c6bd57813dfb0bf2 100644
--- a/firmware/osape-smoothieroll-head/src/drivers/ucbus_head.h
+++ b/firmware/osape-smoothieroll-head/src/drivers/ucbus_head.h
@@ -15,7 +15,7 @@ is; no warranty is provided, and users accept all liability.
 #ifndef UCBUS_HEAD_H_
 #define UCBUS_HEAD_H_
 
-#include <arduino.h>
+#include <Arduino.h>
 
 #include "indicators.h"
 #include "peripheral_nums.h"
diff --git a/firmware/osape-smoothieroll-head/src/osap/osap.h b/firmware/osape-smoothieroll-head/src/osap/osap.h
index 5242ba0ae6cdc77538ef57f119a6691fb46188fa..5d7608120938757d43d9f376bf1c0198acc5e5bb 100644
--- a/firmware/osape-smoothieroll-head/src/osap/osap.h
+++ b/firmware/osape-smoothieroll-head/src/osap/osap.h
@@ -15,7 +15,7 @@ no warranty is provided, and users accept all liability.
 #ifndef OSAP_H_
 #define OSAP_H_
 
-#include <arduino.h>
+#include <Arduino.h>
 #include "ts.h"
 #include "vport.h"
 #include "./drivers/indicators.h"
diff --git a/firmware/osape-smoothieroll-head/src/osap/ts.h b/firmware/osape-smoothieroll-head/src/osap/ts.h
index 7cf3f01f0d9fecc27e0f6369d037fd5286d05743..29a3d6fa631a509157102902c651ab4cb25281ae 100644
--- a/firmware/osape-smoothieroll-head/src/osap/ts.h
+++ b/firmware/osape-smoothieroll-head/src/osap/ts.h
@@ -12,7 +12,7 @@ Copyright is retained and must be preserved. The work is provided as is;
 no warranty is provided, and users accept all liability.
 */
 
-#include <arduino.h>
+#include <Arduino.h>
 
 // -------------------------------------------------------- Routing (Packet) Keys
 
diff --git a/firmware/osape-smoothieroll-head/src/osap/vport.h b/firmware/osape-smoothieroll-head/src/osap/vport.h
index b705e91a150ff544b2efa0ceba17f4f6b3b515eb..cb9c90944e9b082c716adaa794b2f74d7390f880 100644
--- a/firmware/osape-smoothieroll-head/src/osap/vport.h
+++ b/firmware/osape-smoothieroll-head/src/osap/vport.h
@@ -15,7 +15,7 @@ no warranty is provided, and users accept all liability.
 #ifndef VPORT_H_
 #define VPORT_H_
 
-#include <arduino.h>
+#include <Arduino.h>
 #include "./utils/syserror.h"
 
 class VPort {
diff --git a/firmware/osape-smoothieroll-head/src/osap/vport_usbserial.h b/firmware/osape-smoothieroll-head/src/osap/vport_usbserial.h
index 4a72d1ce9462ca8bf4ee76992d56c62a8a54a0cf..31434b738950150349a63847e829b6376733e961 100644
--- a/firmware/osape-smoothieroll-head/src/osap/vport_usbserial.h
+++ b/firmware/osape-smoothieroll-head/src/osap/vport_usbserial.h
@@ -15,7 +15,7 @@ no warranty is provided, and users accept all liability.
 #ifndef VPORT_USBSERIAL_H_
 #define VPORT_USBSERIAL_H_
 
-#include <arduino.h>
+#include <Arduino.h>
 #include "vport.h"
 #include "./utils/cobs.h"
 #include "./drivers/indicators.h"
diff --git a/firmware/osape-smoothieroll-head/src/utils/cobs.h b/firmware/osape-smoothieroll-head/src/utils/cobs.h
index a9e587463dc4cfc6f8175d0ff48b53174970133c..92208c31312b414d5938026d2e40551f4703819c 100644
--- a/firmware/osape-smoothieroll-head/src/utils/cobs.h
+++ b/firmware/osape-smoothieroll-head/src/utils/cobs.h
@@ -15,7 +15,7 @@ no warranty is provided, and users accept all liability.
 #ifndef UTIL_COBS_H_
 #define UTIL_COBS_H_
 
-#include <arduino.h>
+#include <Arduino.h>
 
 size_t cobsEncode(uint8_t *src, size_t len, uint8_t *dest);
 
diff --git a/firmware/osape-smoothieroll-head/src/utils/syserror.h b/firmware/osape-smoothieroll-head/src/utils/syserror.h
index b421cc2a08eb1d482a9f298ed9dbefaa90531f9d..9c53e37a23122e8021b7a7ac1175eb2e54c8e200 100644
--- a/firmware/osape-smoothieroll-head/src/utils/syserror.h
+++ b/firmware/osape-smoothieroll-head/src/utils/syserror.h
@@ -1,7 +1,7 @@
 #ifndef SYSERROR_H_
 #define SYSERROR_H_
 
-#include <arduino.h>
+#include <Arduino.h>
 #include "./drivers/indicators.h"
 #include "./utils/cobs.h"
 #include "./osap/ts.h"