/// <summary> /// Finds the appropriate WritePrinthead method and returns the converted GCode output. /// </summary> /// <param name="printheadModel"></param> /// <returns></returns> public string SetWritePrinthead(PrintheadModel printheadModel) { string convertedGCode = ""; try { switch (printheadModel.PrintheadType) { case PrintheadType.Motorized: convertedGCode = _writeSetPrintheadModel.WriteSetMotorDrivenPrinthead(printheadModel); break; case PrintheadType.Valve: convertedGCode = _writeSetPrintheadModel.WriteSetValvePrinthead(printheadModel); break; case PrintheadType.Custom: //To Do: break; case PrintheadType.Unset: //To Do: Stop everything something's wrong break; default: //To Do: Stop everything something's wrong break; } } catch when(printheadModel == null) //Catch unset Printhead. { //This should have been caught earlier. convertedGCode = ""; }
/// <summary> /// Takes manual input parameters for a set of valve printhead command and outputs the command to the serial port. /// </summary> /// <param name="printheadName"></param> public void ProcessManualSetValvePrintheadCommand(string printheadName) { try { List <string> outgoingMessagesList = new List <string>(); PrintheadModel printheadModel = _printerModel.FindPrinthead(printheadName); ValvePrintheadTypeModel valvePrintheadTypeModel = (ValvePrintheadTypeModel)printheadModel.PrintheadTypeModel; string setPrintheadString = _writeSetPrintheadModel.WriteSetValvePrinthead(valvePrintheadTypeModel.AttachedValveGPIOPinModel.PinID); outgoingMessagesList.Add(setPrintheadString); //Send GCode for the Z Axis attached to the Printhead. AxisModel axisModel = printheadModel.AttachedZAxisModel; int zAxisLimitPinID = (axisModel.AttachedLimitSwitchGPIOPinModel == null) ? GlobalValues.PinIDNull : axisModel.AttachedLimitSwitchGPIOPinModel.PinID; string setAxisString = _writeSetAxisModel.WriteSetAxis(axisModel.AxisID, axisModel.AttachedMotorStepGPIOPinModel.PinID, axisModel.AttachedMotorDirectionGPIOPinModel.PinID, axisModel.StepPulseTime, zAxisLimitPinID, axisModel.MaxSpeed, axisModel.MaxAcceleration, axisModel.MmPerStep); outgoingMessagesList.Add(SerialMessageCharacters.SerialCommandSetCharacter + "RetractZ"); outgoingMessagesList.Add(setAxisString); _serialCommunicationOutgoingMessagesModel.QueueNextProspectiveOutgoingMessage(outgoingMessagesList); } catch (NullReferenceException e) { _errorListViewModel.AddError("", "Printhead or z actuator needs to be set in Printer Settings before setting printhead in Control Menu."); } catch { _errorListViewModel.AddError("", "Unknown error while setting valve printhead."); } }
/// <summary> /// Takes manual input parameters for a set of commands for motorized printhead droplet printing and outputs the commands to the serial port. /// </summary> /// <param name="xDistance"></param> /// <param name="yDistance"></param> /// <param name="zDistance"></param> /// <param name="interpolateDistance"></param> /// <param name="eDispensePerDroplet"></param> public void ProcessManualMotorDropletPrintCommand(double xDistance, double yDistance, double zDistance, double interpolateDistance, double eDispensePerDroplet) { PrintheadModel printheadModel = _printerModel.FindPrinthead(_realTimeStatusDataModel.ActivePrintheadModel.Name); MotorizedPrintheadTypeModel motorizedPrintheadTypeModel = (MotorizedPrintheadTypeModel)printheadModel.PrintheadTypeModel; double emmPerStep = motorizedPrintheadTypeModel.MmPerStep; RealTimeStatusMotorizedPrintheadModel realTimeStatusMotorizedPrintheadModel = (RealTimeStatusMotorizedPrintheadModel)_realTimeStatusDataModel.ActivePrintheadModel; double eMaxSpeed = realTimeStatusMotorizedPrintheadModel.MaxSpeed; double eAcceleration = realTimeStatusMotorizedPrintheadModel.Acceleration; double xmmPerStep = (xDistance != 0) ? _printerModel.AxisModelList[0].MmPerStep : double.MaxValue; double ymmPerStep = (yDistance != 0) ? _printerModel.AxisModelList[1].MmPerStep : double.MaxValue; AxisModel zAxisModel = _printerModel.FindAxis(_realTimeStatusDataModel.ZRealTimeStatusAxisModel.Name); double zmmPerStep = (zDistance != 0) ? _printerModel.FindAxis(zAxisModel.Name).MmPerStep : double.MaxValue; bool zDirectionInverted = (zAxisModel != null) ? zAxisModel.IsDirectionInverted : false; double unused = 0; string printString = GCodeLinesConverter.GCodeLinesListToString( WriteG00.WriteMotorizedDropletPrint( emmPerStep, xmmPerStep, ymmPerStep, zmmPerStep, eDispensePerDroplet, 0, xDistance, 0, yDistance, 0, zDistance, _printerModel.AxisModelList[0].IsDirectionInverted, _printerModel.AxisModelList[1].IsDirectionInverted, zDirectionInverted, motorizedPrintheadTypeModel.IsDirectionInverted, ref unused, ref unused, ref unused, ref unused, null, new DropletModel(interpolateDistance))); _serialCommunicationOutgoingMessagesModel.QueueNextProspectiveOutgoingMessage(printString); }
/// <summary> /// Sends outgoing commands that mark the position of the currently active Printhead's point to printing (centered and closest to the print surface). /// Should only be called after Z actuators have hit their top limit switches this session. /// All Printheads should be calibrated within a single session as X and Y Offset positions are relative. /// Z Offset is simply the zero position of the Z actuator. /// </summary> public void CalibratePrintheadOffset() { try { //Set Offset values for the current Printhead. PrintheadModel printheadModel = _printerModel.FindPrinthead(_realTimeStatusDataModel.ActivePrintheadModel.Name); printheadModel.XOffset = _realTimeStatusDataModel.XRealTimeStatusAxisModel.Position; printheadModel.YOffset = _realTimeStatusDataModel.YRealTimeStatusAxisModel.Position; //Set current Z Axis MinPosition to 0. string setZMin = SerialMessageCharacters.SerialCommandSetCharacter + "SetMinMaxPos ZN0"; _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(setZMin); //Maximize Z Axis speeds. string setZMaxSpeed = _writeSetAxisModel.WriteSetAxis(printheadModel.AttachedZAxisModel); _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(setZMaxSpeed); //The next Z Limit Switch hit will calibrate minmax positions. _realTimeStatusDataModel.ShouldZCalibrate = true; //Retracts the Z Axis up to a short distance away from the Limit Switch (does not hit the Limit Switch). string retractZ = SerialMessageCharacters.SerialCommandSetCharacter + "RetractZLimit"; _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(retractZ); OnCalibrationBegun(); } catch when(_realTimeStatusDataModel.ActivePrintheadModel == null) { _errorListViewModel.AddError("", "No printhead is set. Printhead must be set before calibrating printhead offset."); }
/// <summary> /// Adds one Printhead to the Printer. /// </summary> public void AddPrinthead() { string newPrintheadName = "Printhead " + ++_printheadsCreatedCount; PrintheadModel newPrinthead = new PrintheadModel(newPrintheadName); _printheadModelList.Add(newPrinthead); }
/// <summary> /// Returns a set of commands for Axis movement that compensates for a new Printhead's offsets. /// Print speeds will be maximized before moving to offset. /// </summary> /// <param name="newPrinthead"></param> /// <param name="currentPrinthead"></param> /// <param name="zPosition">Relative position of the Z Axis before and after switching.</param> /// <param name="pauseBeforeActivating">Pauses the print sequence before lowering the Z actuator.</param> /// <returns></returns> private List <string> WriteMoveToOffset(PrintheadModel newPrinthead, PrintheadModel currentPrinthead, double zPosition, bool pauseBeforeActivating) { List <string> returnCommands = new List <string>(); AxisModel xAxisModel = _printerModel.AxisModelList[0]; AxisModel yAxisModel = _printerModel.AxisModelList[1]; AxisModel zAxisModel = newPrinthead.AttachedZAxisModel; double xMove = newPrinthead.XOffset - currentPrinthead.XOffset; double yMove = newPrinthead.YOffset - currentPrinthead.YOffset; double zMove = 0; if (newPrinthead.AttachedZAxisModel.Name != _realTimeStatusDataModel.ZRealTimeStatusAxisModel.Name) { //If a new Z actuator is requried. zMove = -1 * (newPrinthead.AttachedZAxisModel.MaxPosition - GlobalValues.LimitBuffer) + zPosition; } //Move to the X and Y offsets first to prevent bumping of print container walls. double unused = 0; if ((xMove != 0) || (yMove != 0)) { //Maximize movement speeds before moving to offset. returnCommands.Add(_writeSetAxisModel.WriteSetAxis(_printerModel.AxisModelList[0])); returnCommands.Add(_writeSetAxisModel.WriteSetAxis(_printerModel.AxisModelList[1])); returnCommands.Add(GCodeLinesConverter.GCodeLinesListToString( WriteG00.WriteAxesMovement(xAxisModel.MmPerStep, yAxisModel.MmPerStep, 0, xMove, yMove, 0, xAxisModel.IsDirectionInverted, yAxisModel.IsDirectionInverted, false, ref unused, ref unused, ref unused))); } //Pause before activating. if (pauseBeforeActivating == true) { returnCommands.Add(SerialMessageCharacters.SerialPrintPauseCharacter.ToString()); } //Move the Z offset after the X and Y positions are set. if (zMove != 0) { returnCommands.Add(_writeSetAxisModel.WriteSetAxis(newPrinthead.AttachedZAxisModel)); returnCommands.Add(GCodeLinesConverter.GCodeLinesListToString( WriteG00.WriteAxesMovement(0, 0, zAxisModel.MmPerStep, 0, 0, zMove, false, false, zAxisModel.IsDirectionInverted, ref unused, ref unused, ref unused))); } return(returnCommands); }
/// <summary> /// Returns an index for eModiPrintCoordList which contains the eModiPrintCoord associated with the current eRepRapCoord. /// </summary> /// <param name="currentMaterial"></param> /// <returns></returns> public int FindEModiPrintCoordIndex(PrintheadModel printheadModel) { //The List index of eModiPrintCoordList. //This same index in the Printer's PrintheadModelList has the CoordinateModel's associated Printhead. int eModiPrintCoordIndex = 0; for (eModiPrintCoordIndex = 0; eModiPrintCoordIndex < (_printerModel.PrintheadModelList.Count - 1); eModiPrintCoordIndex++) { if (printheadModel == _printerModel.PrintheadModelList[eModiPrintCoordIndex]) { break; } } return(eModiPrintCoordIndex); }
/// <summary> /// Returns converted GCode for the setting of Motor-Driven Printheads. /// </summary> /// <param name="printheadModel"></param> /// <returns></returns> public string WriteSetMotorDrivenPrinthead(PrintheadModel printheadModel) { string convertedGCode = ""; if (printheadModel.PrintheadType == PrintheadType.Motorized) { MotorizedPrintheadTypeModel motorizedPrinthead = (MotorizedPrintheadTypeModel)printheadModel.PrintheadTypeModel; try { int limitPin = GlobalValues.PinIDNull; if (motorizedPrinthead.AttachedLimitSwitchGPIOPinModel != null) { limitPin = motorizedPrinthead.AttachedLimitSwitchGPIOPinModel.PinID; } convertedGCode = WriteSetMotorDrivenPrinthead(motorizedPrinthead.AttachedMotorStepGPIOPinModel.PinID, motorizedPrinthead.AttachedMotorDirectionGPIOPinModel.PinID, motorizedPrinthead.StepPulseTime, limitPin, motorizedPrinthead.MaxSpeed, motorizedPrinthead.MaxAcceleration, motorizedPrinthead.MmPerStep); } catch when(printheadModel == null) { _parametersModel.ErrorReporterViewModel.ReportError("GCode Converter: Printer Unset", "Printhead Not Found"); convertedGCode = ""; }
/// <summary> /// Interpret a switch material command set and return an array of commands. /// </summary> /// <param name="commandSet"></param> /// <returns></returns> private List <string> InterpretSwitchMaterial(string commandSet) { //Remove "*SwitchMaterial" from the beginning of the command set. commandSet = commandSet.Substring(14); //Potentially pause before deactivating the current printhead. bool pauseBeforeDeactivating = false; if (commandSet.Contains('D')) { pauseBeforeDeactivating = true; } //Potentially pause after activating the next printhead. bool pauseBeforeActivating = false; if (commandSet.Contains('A')) { pauseBeforeActivating = true; } //Set of commands to be returned at the end of this method. List <string> returnCommands = new List <string>(); //The name of the Material which will be switched to will be between quote characters. int firstNameIndex = commandSet.IndexOf('"'); int nameLength = commandSet.Substring(firstNameIndex + 1).IndexOf('"'); string materialName = commandSet.Substring(firstNameIndex + 1, nameLength); MaterialModel materialModel = _printModel.FindMaterialByName(materialName); if (materialModel == null) { _errorListViewModel.AddError("Command Set Invalid", materialName + " Not Set"); return(null); } //References to the current and new Printheads. PrintheadModel currentPrintheadModel = _printerModel.FindPrinthead(_realTimeStatusDataModel.ActivePrintheadModel.Name); PrintheadModel newPrintheadModel = materialModel.PrintheadModel; //References to the Z Axis on the current Printhead. AxisModel currentZAxisModel = _printerModel.FindAxis(currentPrintheadModel.AttachedZAxisModel.Name); int currentZLimitPinID = (currentZAxisModel.AttachedLimitSwitchGPIOPinModel != null) ? currentZAxisModel.AttachedLimitSwitchGPIOPinModel.PinID : GlobalValues.PinIDNull; //References to the XY Axes and new Z Axis. AxisModel xAxisModel = _printerModel.AxisModelList[0]; int xLimitPinID = (xAxisModel.AttachedLimitSwitchGPIOPinModel != null) ? xAxisModel.AttachedLimitSwitchGPIOPinModel.PinID : GlobalValues.PinIDNull; AxisModel yAxisModel = _printerModel.AxisModelList[1]; int yLimitPinID = (yAxisModel.AttachedLimitSwitchGPIOPinModel != null) ? yAxisModel.AttachedLimitSwitchGPIOPinModel.PinID : GlobalValues.PinIDNull; AxisModel zAxisModel = _printerModel.FindAxis(newPrintheadModel.AttachedZAxisModel.Name); int zLimitPinID = (zAxisModel.AttachedLimitSwitchGPIOPinModel != null) ? zAxisModel.AttachedLimitSwitchGPIOPinModel.PinID : GlobalValues.PinIDNull; //If a new Printhead is required... if (newPrintheadModel.Name != currentPrintheadModel.Name) { //1. Set previous Z Axis at max speeds. //2. Retract the previous Printhead / Z Axis. returnCommands.Add(_writeSetAxisModel.WriteSetAxis('Z', currentZAxisModel.AttachedMotorStepGPIOPinModel.PinID, currentZAxisModel.AttachedMotorDirectionGPIOPinModel.PinID, currentZAxisModel.StepPulseTime, currentZLimitPinID, currentZAxisModel.MaxSpeed, currentZAxisModel.MaxAcceleration, currentZAxisModel.MmPerStep)); List <string> retractZ = RetractZ("", currentPrintheadModel.AttachedZAxisModel); foreach (string command in retractZ) { if (!String.IsNullOrWhiteSpace(command)) { returnCommands.Add(command); } } //Pause before deactivating. if (pauseBeforeDeactivating == true) { returnCommands.Add(SerialMessageCharacters.SerialPrintPauseCharacter.ToString()); } //3. Set new XYZ to max speeds and move to the new Offset. //Set associated X Axis at max speeds. returnCommands.Add(_writeSetAxisModel.WriteSetAxis('X', xAxisModel.AttachedMotorStepGPIOPinModel.PinID, xAxisModel.AttachedMotorDirectionGPIOPinModel.PinID, xAxisModel.StepPulseTime, xLimitPinID, xAxisModel.MaxSpeed, xAxisModel.MaxAcceleration, xAxisModel.MmPerStep)); //Set associated Y Axis at max speeds. returnCommands.Add(_writeSetAxisModel.WriteSetAxis('Y', yAxisModel.AttachedMotorStepGPIOPinModel.PinID, yAxisModel.AttachedMotorDirectionGPIOPinModel.PinID, yAxisModel.StepPulseTime, yLimitPinID, yAxisModel.MaxSpeed, yAxisModel.MaxAcceleration, yAxisModel.MmPerStep)); //Set associated Z Axis at max speeds. returnCommands.Add(_writeSetAxisModel.WriteSetAxis('Z', zAxisModel.AttachedMotorStepGPIOPinModel.PinID, zAxisModel.AttachedMotorDirectionGPIOPinModel.PinID, zAxisModel.StepPulseTime, zLimitPinID, zAxisModel.MaxSpeed, zAxisModel.MaxAcceleration, zAxisModel.MmPerStep)); //4.Move to the new Offset at max speeds. double zPosition = _realTimeStatusDataModel.ZRealTimeStatusAxisModel.Position; List <string> moveToOffset = WriteMoveToOffset(newPrintheadModel, currentPrintheadModel, zPosition, pauseBeforeActivating); foreach (string command in moveToOffset) { if (!String.IsNullOrWhiteSpace(command)) { returnCommands.Add(command); } } } //5.Set the print speed parameters for the new Material. //Set associated X Axis at print speeds. returnCommands.Add(_writeSetAxisModel.WriteSetAxis('X', xAxisModel.AttachedMotorStepGPIOPinModel.PinID, xAxisModel.AttachedMotorDirectionGPIOPinModel.PinID, xAxisModel.StepPulseTime, xLimitPinID, materialModel.XYPrintSpeed, materialModel.XYPrintAcceleration, xAxisModel.MmPerStep)); //Set associated Y Axis at print speeds. returnCommands.Add(_writeSetAxisModel.WriteSetAxis('Y', yAxisModel.AttachedMotorStepGPIOPinModel.PinID, yAxisModel.AttachedMotorDirectionGPIOPinModel.PinID, yAxisModel.StepPulseTime, yLimitPinID, materialModel.XYPrintSpeed, materialModel.XYPrintAcceleration, yAxisModel.MmPerStep)); //Set associated Z Axis at print speeds. returnCommands.Add(_writeSetAxisModel.WriteSetAxis('Z', zAxisModel.AttachedMotorStepGPIOPinModel.PinID, zAxisModel.AttachedMotorDirectionGPIOPinModel.PinID, zAxisModel.StepPulseTime, zLimitPinID, materialModel.ZPrintSpeed, materialModel.ZPrintAcceleration, zAxisModel.MmPerStep)); //6. Set the new Printhead at print speeds. string setNewPrinthead = _setWritePrintheadModel.SetWritePrinthead(newPrintheadModel); returnCommands.Add(setNewPrinthead); return(returnCommands); }
public PrintheadViewModel(PrintheadModel PrintheadModel, GPIOPinListsViewModel GPIOPinListsViewModel) { _printheadModel = PrintheadModel; _gPIOPinListsViewModel = GPIOPinListsViewModel; }
/// <summary> /// Adds one Printhead with a Name to the Printer. /// </summary> /// <param Name="printheadName"></param> /// <remarks> /// This method was created for the XML Serializers. /// </remarks> public void AddPrinthead(string printheadName) { PrintheadModel newPrinthead = new PrintheadModel(printheadName); _printheadModelList.Add(newPrinthead); }
/// <summary> /// Create a new Coordinate Model for a Motorized Printhead. /// Typically used when switching Printheads. /// </summary> /// <param name="printheadModel"></param> /// <param name="position"></param> /// <param name="minPosition"></param> /// <param name="maxPosition"></param> public void SetNewECoord(PrintheadModel printheadModel, double position, double minPosition, double maxPosition) { _eModiPrintCoordList[FindEModiPrintCoordIndex(printheadModel)] = new CoordinateModel(CoordinateType.E, true, this, position, minPosition, maxPosition); }