/// <summary> /// Save Print-related elements to XML. /// </summary> private void SaveModiPrintSettings() { try { SaveFileDialog saveFileDialog = new SaveFileDialog(); saveFileDialog.AddExtension = true; saveFileDialog.DefaultExt = ".xml"; saveFileDialog.Filter = "XML Save Files (.xml)|*.xml|Text Files (.txt)|*.txt|All Files (*.*)|*.*"; if (saveFileDialog.ShowDialog() == true) { string serializedModiPrint = _modiPrintXMLSerializerModel.SerializeModiPrint(_printerViewModel, _printViewModel, _gCodeManagerViewModel); File.WriteAllText(saveFileDialog.FileName, serializedModiPrint); } } catch { _errorListViewModel.AddError("Print Settings Save", "Unable to Save Print Settings"); } }
/// <summary> /// Takes manual input parameters for a set axis command and outputs the command to the serial port. /// </summary> /// <param name="axisName"></param> /// <param name="maxSpeed"></param> /// <param name="acceleration"></param> public void ProcessManualSetAxisCommand(string axisName, double maxSpeed, double acceleration) { try { List <string> outgoingMessagesList = new List <string>(); AxisModel axisModel = _printerModel.FindAxis(axisName); int limitPinID = (axisModel.AttachedLimitSwitchGPIOPinModel == null) ? GlobalValues.PinIDNull : axisModel.AttachedLimitSwitchGPIOPinModel.PinID; string setAxisString = _writeSetAxisModel.WriteSetAxis(axisModel.AxisID, axisModel.AttachedMotorStepGPIOPinModel.PinID, axisModel.AttachedMotorDirectionGPIOPinModel.PinID, axisModel.StepPulseTime, limitPinID, maxSpeed, acceleration, axisModel.MmPerStep); //If switching Z Axes, then retract the current Z Axis first. if (axisModel.AxisID == 'Z') { outgoingMessagesList.Add(SerialMessageCharacters.SerialCommandSetCharacter + "RetractZ"); } outgoingMessagesList.Add(setAxisString); _serialCommunicationOutgoingMessagesModel.QueueNextProspectiveOutgoingMessage(outgoingMessagesList); } catch (NullReferenceException e) { _errorListViewModel.AddError("", "Actuator needs to be set in Printer Settings before setting the actuator in Control Menu."); } catch { _errorListViewModel.AddError("", "Unknown error while setting valve printhead."); } }
/// <summary> /// Loads a .gcode file into the program with OpenFileDialog. /// Determines which g-code file to load into depending on the file extension. /// Returns the name of the file. /// </summary> public string UploadGCodeFile() { try { //Open file. OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Filter = "G-code Files (.gcode, .mdpt)|*.gcode; *.mdpt|All files (*.*)|*.*"; //Reads file. if (openFileDialog.ShowDialog() == true) { string extenstion = Path.GetExtension(openFileDialog.FileName); if (extenstion == ".gcode") { _uploadedGCodeModel.GCodeStr = File.ReadAllText(openFileDialog.FileName); _uploadedGCodeType = GCodeType.RepRap; } else if (extenstion == ".mdpt") { _uploadedGCodeModel.GCodeStr = File.ReadAllText(openFileDialog.FileName); _uploadedGCodeType = GCodeType.ModiPrint; } else { _errorListViewModel.AddError("GCode File Manager", "Unrecognized file extension. File extension must be .gcode or .mdpt."); } return(Path.GetFileName(openFileDialog.FileName)); } } catch { _errorListViewModel.AddError("GCode File Manager", "Unknown error, unable to upload g-code file."); } return(""); }
/// <summary> /// Calls the OnPropertyChanged event and updates the Error Messages list. /// </summary> private void UpdateErrorMessages(string incomingMessage) { string errorMessage = ""; if (incomingMessage.Substring(0, 3) == "Syn") { errorMessage = "Syntax unrecognized"; } else if (incomingMessage.Substring(0, 3) == "Uns") { errorMessage = "Equipment unset"; } else if (incomingMessage.Substring(0, 3) == "Cyc") { errorMessage = "Maximum stepper speed exceeded"; } else if (incomingMessage.Substring(0, 3) == "Ext") { errorMessage = "Incorrect exit speed"; } _errorListViewModel.AddError("Microcontroller Error: ", errorMessage); }
/// <summary> /// Executes when a message has been received from serial communication. /// </summary> /// <param name="sender"></param> /// <param name="serialMessageEventArgs"></param> private void SerialCommunicationMessageReceived(object sender, SerialMessageEventArgs serialMessageEventArgs) { string incomingMessage = serialMessageEventArgs.Message; //Filter message by type. if (incomingMessage[0] == SerialMessageCharacters.SerialTaskQueuedCharacter) //Task queued. { InterpretTaskQueuedMessage(incomingMessage); } else if (incomingMessage[0] == SerialMessageCharacters.SerialTaskCompletedCharacter) //Task completed. { //Earliest queued tasks are completed first. if (_realTimeStatusDataModel.IsTaskQueuedEmpty() == false) { InterpretTaskCompletedMessage(_realTimeStatusDataModel.RetrieveNextTaskQueuedMessage()); _realTimeStatusDataModel.RecordTaskCompleted(); } else { _errorListViewModel.AddError("Serial communication out of sync: ", "Task completed return does not correspond to a task"); } } else if (incomingMessage[0] == SerialMessageCharacters.SerialStatusCharacter) //Status. { InterpretStatusMessage(incomingMessage); _realTimeStatusDataModel.RecordStatusMessage(incomingMessage.Substring(1)); } else if (incomingMessage[0] == SerialMessageCharacters.SerialErrorCharacter) //Error. { _realTimeStatusDataModel.RecordErrorMessage(incomingMessage.Substring(1)); } else //Also an error. { _realTimeStatusDataModel.RecordErrorMessage("Microcontroller return message unrecognized: " + incomingMessage); } }
/// <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); }
/// <summary> /// Output an error to the GUI containing information about the XML Reader. /// Outputs "Unrecognized Element" error message. /// </summary> /// <param name="xmlReader"></param> protected void ReportErrorUnrecognizedElement(XmlReader xmlReader) { IXmlLineInfo xmlInfo = xmlReader as IXmlLineInfo; _errorListViewModel.AddError("Improperly Loaded Save File: Unrecognized Element", "XML Line: " + xmlInfo.LineNumber); }
/// <summary> /// Sends outgoing commands that retracts all Z Axes and moves X and Y Axes to the limit switches. /// </summary> public void Home(double xCalibrationSpeed, double yCalibrationSpeed, double zCalibrationSpeed, double xDistanceFromCenter, double yDistanceFromCenter) { try { //Retract Z Axes. RetractAllZ(zCalibrationSpeed); //Z Axes should be in default positions. AxisModel zAxisModel = _printerModel.ZAxisModelList[_printerModel.ZAxisModelList.Count - 1]; double zPosition = zAxisModel.MaxPosition - GlobalValues.LimitBuffer; _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(SerialMessageCharacters.SerialCommandSetCharacter + "SetMinMaxPos " + "Z" + zPosition); //Set X Axis to calibration speeds. AxisModel xAxis = _printerModel.AxisModelList[0]; int xLimitPinID = (xAxis.AttachedLimitSwitchGPIOPinModel == null) ? GlobalValues.PinIDNull : xAxis.AttachedLimitSwitchGPIOPinModel.PinID; string switchX = _writeSetAxisModel.WriteSetAxis(xAxis.AxisID, xAxis.AttachedMotorStepGPIOPinModel.PinID, xAxis.AttachedMotorDirectionGPIOPinModel.PinID, xAxis.StepPulseTime, xLimitPinID, xCalibrationSpeed, xAxis.MaxAcceleration, xAxis.MmPerStep); _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(switchX); //Set Y Axis to max speeds. AxisModel yAxis = _printerModel.AxisModelList[1]; int yLimitPinID = (yAxis.AttachedLimitSwitchGPIOPinModel == null) ? GlobalValues.PinIDNull : yAxis.AttachedLimitSwitchGPIOPinModel.PinID; string switchY = _writeSetAxisModel.WriteSetAxis(yAxis.AxisID, yAxis.AttachedMotorStepGPIOPinModel.PinID, yAxis.AttachedMotorDirectionGPIOPinModel.PinID, yAxis.StepPulseTime, yLimitPinID, yCalibrationSpeed, yAxis.MaxAcceleration, yAxis.MmPerStep); _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(switchY); //Hit the min and max limit switches on X. double unused = 0; string xPositive = GCodeLinesConverter.GCodeLinesListToString( WriteG00.WriteAxesMovement( xAxis.MmPerStep, 0, 0, 5000, 0, 0, xAxis.IsDirectionInverted, false, false, ref unused, ref unused, ref unused)); string xNegative = GCodeLinesConverter.GCodeLinesListToString( WriteG00.WriteAxesMovement( xAxis.MmPerStep, 0, 0, -5000, 0, 0, xAxis.IsDirectionInverted, false, false, ref unused, ref unused, ref unused)); _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(xPositive); _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(xNegative); //Move away from the limit switch. string xMoveAwayFromLimit = GCodeLinesConverter.GCodeLinesListToString( WriteG00.WriteAxesMovement( xAxis.MmPerStep, 0, 0, GlobalValues.LimitBuffer, 0, 0, xAxis.IsDirectionInverted, false, false, ref unused, ref unused, ref unused)); _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(xMoveAwayFromLimit); //Hit the min and max limit switches on Y. string yPositive = GCodeLinesConverter.GCodeLinesListToString( WriteG00.WriteAxesMovement( 0, yAxis.MmPerStep, 0, 0, 5000, 0, yAxis.IsDirectionInverted, false, false, ref unused, ref unused, ref unused)); string yNegative = GCodeLinesConverter.GCodeLinesListToString( WriteG00.WriteAxesMovement( 0, yAxis.MmPerStep, 0, 0, -5000, 0, yAxis.IsDirectionInverted, false, false, ref unused, ref unused, ref unused)); _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(yPositive); _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(yNegative); //Move away from the limit switch. string yMoveAwayFromLimit = GCodeLinesConverter.GCodeLinesListToString( WriteG00.WriteAxesMovement( 0, yAxis.MmPerStep, 0, 0, GlobalValues.LimitBuffer, 0, yAxis.IsDirectionInverted, false, false, ref unused, ref unused, ref unused)); _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(yMoveAwayFromLimit); //Set X Axis to max speeds. string switchXMax = _writeSetAxisModel.WriteSetAxis(xAxis); _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(switchXMax); //Set Y Axis to max speeds. string switchYMax = _writeSetAxisModel.WriteSetAxis(yAxis); _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(switchYMax); //Center the X and Y actuators. _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(SerialMessageCharacters.SerialCommandSetCharacter + "Center X" + xDistanceFromCenter + " Y" + yDistanceFromCenter); _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(SerialMessageCharacters.SerialCommandSetCharacter + "OriginXY"); //At the end, switch the Z actuator to the Printhead used at the beginning of the print. if (_realTimeStatusDataModel.ZRealTimeStatusAxisModel.Name != "Unset") { AxisModel zAxisFinalModel = _printerModel.FindAxis(_realTimeStatusDataModel.ZRealTimeStatusAxisModel.Name); int zFinalLimitPinID = (zAxisFinalModel.AttachedLimitSwitchGPIOPinModel == null) ? GlobalValues.PinIDNull : zAxisFinalModel.AttachedLimitSwitchGPIOPinModel.PinID; string switchZFinal = _writeSetAxisModel.WriteSetAxis(zAxisFinalModel.AxisID, zAxisFinalModel.AttachedMotorStepGPIOPinModel.PinID, zAxisFinalModel.AttachedMotorDirectionGPIOPinModel.PinID, zAxisFinalModel.StepPulseTime, zFinalLimitPinID, zCalibrationSpeed, zAxisFinalModel.MaxAcceleration, zAxisFinalModel.MmPerStep); _serialCommunicationOutgoingMessagesModel.AppendProspectiveOutgoingMessage(switchZFinal); } OnCalibrationBegun(); } catch { _errorListViewModel.AddError("", "Unkown error when homing"); } }