public virtual IFrostedSerialPort Create(string serialPortName)
        {
#if __ANDROID__
            //Create an instance of a FrostedSerialPort
            IFrostedSerialPort newPort = null;
            newPort = new FrostedSerialPort(serialPortName);
            return(newPort);
#else
            IFrostedSerialPort newPort = null;
            // if we can find a mac helper class (to get us 250k)
            string appBundle = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
            if (File.Exists(Path.Combine(appBundle, "libFrostedSerialHelper.dylib")))
            {
                // use it
                newPort = new FrostedSerialPort(serialPortName);
            }
            else             // use the c# native serial port
            {
#if USE_STANDARD_SERIAL
                newPort = new CSharpSerialPortWrapper(serialPortName);
#endif
            }

            return(newPort);
#endif // ANDROID
        }
示例#2
0
        public virtual IFrostedSerialPort CreateAndOpen(string serialPortName, int baudRate, bool DtrEnableOnConnect)
        {
#if __ANDROID__
            //Create an instance of a FrostedSerialPort and open it
            IFrostedSerialPort newPort = Create(serialPortName);

            newPort.BaudRate = baudRate;
            if (DtrEnableOnConnect)
            {
                newPort.DtrEnable = true;
            }

            // Set the read/write timeouts
            newPort.ReadTimeout  = 500;
            newPort.WriteTimeout = 500;
            newPort.Open();

            return(newPort);
#else
            IFrostedSerialPort newPort = Create(serialPortName);

            bool isLinux = !(newPort is FrostedSerialPort) && !IsWindows;
            bool customBaudAssignment = isLinux && baudRate > 115200;

            // Only set serial port .BaudRate when not using Linux workaround
            if (!customBaudAssignment)
            {
                newPort.BaudRate = baudRate;
            }

            if (DtrEnableOnConnect)
            {
                newPort.DtrEnable = true;
            }

            // Set the read/write timeouts
            newPort.ReadTimeout  = 500;
            newPort.WriteTimeout = 500;

            newPort.Open();

            if (customBaudAssignment)
            {
                // Once mono has enforced its ANSI baud rate policy(in SerialPort.Open), reset the baud rate to the user specified
                // value by calling set_baud in libSetSerial.so
                set_baud(serialPortName, baudRate);
            }

            return(newPort);
#endif // ANDROID
        }
        public virtual IFrostedSerialPort CreateAndOpen(string serialPortName, int baudRate, bool DtrEnableOnConnect)
        {
#if __ANDROID__
            //Create an instance of a FrostedSerialPort and open it
            IFrostedSerialPort newPort = Create(serialPortName);

            newPort.BaudRate = baudRate;
            if (DtrEnableOnConnect)
            {
                newPort.DtrEnable = true;
            }

            // Set the read/write timeouts
            newPort.ReadTimeout  = 500;
            newPort.WriteTimeout = 500;
            newPort.Open();

            return(newPort);
#else
            IFrostedSerialPort newPort = Create(serialPortName);

            bool isLinux = !(newPort is FrostedSerialPort) && !IsWindows;

            // Skip BaudRate assignment on Linux to avoid Invalid Baud exception - defaults to 9600
            if (!isLinux)
            {
                newPort.BaudRate = baudRate;
            }

            if (DtrEnableOnConnect)
            {
                newPort.DtrEnable = true;
            }

            // Set the read/write timeouts
            newPort.ReadTimeout  = 500;
            newPort.WriteTimeout = 500;

            newPort.Open();

            if (isLinux)
            {
                // Once mono has enforced its ANSI baud rate policy(in SerialPort.Open), reset the baud rate to the user specified
                // value by calling set_baud in libSetSerial.so
                set_baud(serialPortName, baudRate);
            }

            return(newPort);
#endif // ANDROID
        }
 public X3GSerialPortWrapper(string serialPortName)
 {
     port                     = FrostedSerialPortFactory.GetAppropriateFactory("raw").Create(serialPortName);
     printerDetails           = new X3GPrinterDetails();
     writer                   = new X3GWriter(printerDetails);
     reader                   = new X3GReader(printerDetails);
     timeSinceLastCommandSent = new Stopwatch();
     timeSinceLastOK          = new Stopwatch();
     sentCommandQueue         = new Queue <string>();
     lastStr                  = "";
     readBuffer               = new StringBuilder();
     readPacket               = new List <byte>();
     outboundOverflowPackets  = new Queue <byte[]>();
     waitForResponse          = false;
 }
		/// <summary>
		/// Abort an ongoing attempt to establish communication with a printer due to the specified problem. This is a specialized
		/// version of the functionality that's previously been in .Disable but focused specifically on the task of aborting an
		/// ongoing connection. Ideally we should unify all abort invocations to use this implementation rather than the mix
		/// of occasional OnConnectionFailed calls, .Disable and .stopTryingToConnect
		/// </summary>
		/// <param name="abortReason">The concise message which will be used to describe the connection failure</param>
		/// <param name="shutdownReadLoop">Shutdown/join the readFromPrinterThread</param>
		public void AbortConnectionAttempt(string abortReason, bool shutdownReadLoop = true)
		{
			// Set .Disconnecting to allow the read loop to exit gracefully before a forced thread join (and extended timeout)
			CommunicationState = CommunicationStates.Disconnecting;

			// Shutdown the connectionAttempt thread
			if (connectThread != null)
			{
				connectThread.Join(JoinThreadTimeoutMs); //Halt connection thread
			}

			// Shutdown the readFromPrinter thread
			if (shutdownReadLoop)
			{
				ReadThread.Join();
			}

			// Shutdown the serial port
			if (serialPort != null)
			{
				// Close and dispose the serial port
				serialPort.Close();
				serialPort.Dispose();
				serialPort = null;
			}

			// Set the final communication state
			CommunicationState = CommunicationStates.Disconnected;

			// Set the connection failure message and call OnConnectionFailed
			connectionFailureMessage = abortReason;

			// Notify
			OnConnectionFailed(null);
		}
		private void AttemptToConnect(string serialPortName, int baudRate)
		{
			connectionFailureMessage = LocalizedString.Get("Unknown Reason");

			if (PrinterIsConnected)
			{
				throw new Exception(LocalizedString.Get("You can only connect when not currently connected."));
			}

			bool serialPortIsAvailable = SerialPortIsAvailable(serialPortName);
			bool serialPortIsAlreadyOpen = FrostedSerialPortFactory.GetAppropriateFactory(ActivePrinterProfile.Instance.ActivePrinter.DriverType).SerialPortAlreadyOpen(serialPortName);

			if (serialPortIsAvailable && !serialPortIsAlreadyOpen)
			{
				if (!PrinterIsConnected)
				{
					try
					{
						serialPort = FrostedSerialPortFactory.GetAppropriateFactory(ActivePrinterProfile.Instance.ActivePrinter.DriverType).CreateAndOpen(serialPortName, baudRate, true);
#if __ANDROID__
						ToggleHighLowHeigh(serialPort);
#endif
						// wait a bit of time to let the firmware start up
						Thread.Sleep(500);
						CommunicationState = CommunicationStates.AttemptingToConnect;

						ReadThread.Join();

						Console.WriteLine("ReadFromPrinter thread created.");
						ReadThread.Start();

						// We have to send a line because some printers (like old print-r-bots) do not send anything when connecting and there is no other way to know they are there.
						SendLineToPrinterNow("M105");
						SendLineToPrinterNow("M115");
						SendLineToPrinterNow("M114");
					}
					catch (System.ArgumentOutOfRangeException e)
					{
						Debug.Print(e.Message);
						GuiWidget.BreakInDebugger();
						connectionFailureMessage = LocalizedString.Get("Unsupported Baud Rate");
						OnConnectionFailed(null);
					}
					catch (Exception ex)
					{
						Debug.Print(ex.Message);
						GuiWidget.BreakInDebugger();
						Debug.WriteLine("An unexpected exception occurred: " + ex.Message);
						OnConnectionFailed(null);
					}
				}
			}
			else
			{
				// If the serial port isn't available (i.e. the specified port name wasn't found in GetPortNames()) or the serial
				// port is already opened in another instance or process, then report the connection problem back to the user
				connectionFailureMessage = (serialPortIsAlreadyOpen ?
					string.Format("{0} in use", PrinterConnectionAndCommunication.Instance.ActivePrinter.ComPort) :
					LocalizedString.Get("Port not found"));

				OnConnectionFailed(null);
			}
		}
		public void Stop()
		{
			switch (CommunicationState)
			{
				case CommunicationStates.PrintingFromSd:
					CancelSDCardPrint();
					break;

				case CommunicationStates.Printing:
					{
						CancelPrint();
						MarkActivePrintCanceled();
					}

					break;

				case CommunicationStates.Paused:
					{
						if (prePauseCommunicationState == CommunicationStates.PrintingFromSd)
						{
							CancelSDCardPrint();
							CommunicationState = CommunicationStates.Connected;
						}
						else
						{
							CancelPrint();
							MarkActivePrintCanceled();
							// We have to continue printing the end gcode, so we set this to Printing.
							CommunicationState = CommunicationStates.Printing;
						}
					}
					break;

				case CommunicationStates.AttemptingToConnect:
					CommunicationState = CommunicationStates.FailedToConnect;
					connectThread.Join(JoinThreadTimeoutMs);
					CommunicationState = CommunicationStates.Disconnecting;
					ReadThread.Join();
					if (serialPort != null)
					{
						serialPort.Close();
						serialPort.Dispose();
						serialPort = null;
					}
					CommunicationState = CommunicationStates.Disconnected;
					break;

				case CommunicationStates.PreparingToPrint:
					SlicingQueue.Instance.CancelCurrentSlicing();
					CommunicationState = CommunicationStates.Connected;
					break;
			}
		}
		private void ToggleHighLowHeigh(IFrostedSerialPort serialPort)
		{
			serialPort.RtsEnable = true;
			serialPort.DtrEnable = true;
			Thread.Sleep(100);
			serialPort.RtsEnable = false;
			serialPort.DtrEnable = false;
			Thread.Sleep(100);
			serialPort.RtsEnable = true;
			serialPort.DtrEnable = true;
		}
		public void Disable()
		{
			if (PrinterIsConnected)
			{
				// Make sure we send this without waiting for the printer to respond. We want to try and turn off the heaters.
				// It may be possible in the future to make this go into the printer queue for assured sending but it means
				// the program has to be smart about closing an able to wait until the printer has agreed that it shut off
				// the motors and heaters (a good idea and something for the future).
				ForceImmediateWrites = true;
				ReleaseMotors();
				TurnOffBedAndExtruders();
				FanSpeed0To255 = 0;
				ForceImmediateWrites = false;

				CommunicationState = CommunicationStates.Disconnecting;
				ReadThread.Join();
				if (serialPort != null)
				{
					serialPort.Close();
					serialPort.Dispose();
				}
				serialPort = null;
				CommunicationState = CommunicationStates.Disconnected;
				LinesToWriteQueue.Clear();
			}
			else
			{
				//Need to reset UI - even if manual disconnect
				TurnOffBedAndExtruders();
				FanSpeed0To255 = 0;
			}
			OnEnabledChanged(null);
		}
		public void RebootBoard()
		{
			if (this.ActivePrinter != null
				&& serialPort != null)
			{
				bool wasConnected = PrinterIsConnected;
				// first make sure we are not printing if possible (cancel slicing)
				IFrostedSerialPort currentSerialPort = serialPort;
				Stop();
				serialPort = currentSerialPort;

				serialPort.RtsEnable = true;
				serialPort.DtrEnable = true;
				Thread.Sleep(100);
				serialPort.RtsEnable = false;
				serialPort.DtrEnable = false;
				Thread.Sleep(100);
				serialPort.RtsEnable = true;
				serialPort.DtrEnable = true;

				ClearQueuedGCode();

				if (wasConnected)
				{
					// let the process know we canceled not ended normaly.
					CommunicationState = CommunicationStates.Connected;
				}
			}
		}
		public void PulseRtsLow()
		{
			if (serialPort == null && this.ActivePrinter != null)
			{
				serialPort = FrostedSerialPortFactory.GetAppropriateFactory(ActivePrinterProfile.Instance.ActivePrinter.DriverType).Create(this.ActivePrinter.ComPort);
				serialPort.BaudRate = this.BaudRate;

				// Set the read/write timeouts
				serialPort.ReadTimeout = 500;
				serialPort.WriteTimeout = 500;
				serialPort.Open();

				serialPort.RtsEnable = true;
				serialPort.RtsEnable = false;
				try
				{
					Thread.Sleep(100);
				}
				catch(Exception e)
				{
					// Let's track this issue if possible.
					MatterControlApplication.Instance.ReportException(e, this.GetType().Name, MethodBase.GetCurrentMethod().Name);
				}
				serialPort.RtsEnable = true;
				serialPort.Close();
			}
		}
        public void Stop()
        {
            switch (CommunicationState)
            {
                case CommunicationStates.PrintingFromSd:
                    using (TimedLock.Lock(this, "CancelingPrint"))
                    {
                        // get rid of all the gcode we have left to print
                        ClearQueuedGCode();
                        // let the process know we canceled not ended normaly.
                        CommunicationState = CommunicationStates.Connected;
                        SendLineToPrinterNow("M25"); // : Pause SD print
                        SendLineToPrinterNow("M26"); // : Set SD position
                        // never leave the extruder and the bed hot
                        ReleaseMotors();
                        TargetExtruderTemperature = 0;
                        TargetBedTemperature = 0;
                    }
                    break;

                case CommunicationStates.PrintingToSd:
                    CommunicationState = CommunicationStates.Connected;
                    printWasCanceled = true;
                    break;

                case CommunicationStates.Printing:
                    {
                        using (TimedLock.Lock(this, "CancelingPrint"))
                        {
                            // get rid of all the gcode we have left to print
                            ClearQueuedGCode();
                            string cancelGCode = ActiveSliceSettings.Instance.GetActiveValue("cancel_gcode");
                            if (cancelGCode.Trim() != "")
                            {
                                // add any gcode we want to print while canceling
                                InjectGCode(cancelGCode, printerCommandQueueIndex);
                            }
                            // let the process know we canceled not ended normaly.
                            printWasCanceled = true;
                        }
                        if (activePrintTask != null)
                        {
                            TimeSpan printTimeSpan = DateTime.Now.Subtract(activePrintTask.PrintStart);

                            activePrintTask.PrintEnd = DateTime.Now;
                            activePrintTask.PrintComplete = false;
                            activePrintTask.Commit();
                        }
                    }
                    
                    break;

                case CommunicationStates.Paused:
                    {
                        CommunicationState = CommunicationStates.Connected;
                        if (sendGCodeToPrinterThread != null)
                        {
                            sendGCodeToPrinterThread.Join(JoinThreadTimeoutMs);
                            sendGCodeToPrinterThread = null;
                        }
                        if (activePrintTask != null)
                        {
                            TimeSpan printTimeSpan = DateTime.Now.Subtract(activePrintTask.PrintStart);

                            activePrintTask.PrintEnd = DateTime.Now;
                            activePrintTask.PrintComplete = false;
                            activePrintTask.Commit();
                        }
                    }                    
                    break;

                case CommunicationStates.AttemptingToConnect:
                    CommunicationState = CommunicationStates.FailedToConnect;
                    connectThread.Join(JoinThreadTimeoutMs);
                    CommunicationState = CommunicationStates.Disconnecting;
                    if (readFromPrinterThread != null)
                    {
                        readFromPrinterThread.Join(JoinThreadTimeoutMs);
                    }
                    if (serialPort != null)
                    {
                        serialPort.Close();
                        serialPort.Dispose();
                        serialPort = null;
                    }
                    CommunicationState = CommunicationStates.Disconnected;
                    break;

                case CommunicationStates.PreparingToPrint:
                    CommunicationState = CommunicationStates.Connected;
                    break;
            }
        }
        public void PulseRtsLow()
        {
            if (serialPort == null && this.ActivePrinter != null)
            {   
                serialPort = FrostedSerialPort.Create(this.ActivePrinter.ComPort);
                serialPort.BaudRate = this.BaudRate;
                if (PrinterConnectionAndCommunication.Instance.DtrEnableOnConnect)
                {
                    serialPort.DtrEnable = true;
                }

                // Set the read/write timeouts
                serialPort.ReadTimeout = 500;
                serialPort.WriteTimeout = 500;
                serialPort.Open();
                
                serialPort.RtsEnable = true;
                serialPort.RtsEnable = false;
                try
                {
                    Thread.Sleep(1);
                }
                catch
                {
                }
                serialPort.RtsEnable = true;
                serialPort.Close();
            }
        }
        void AttemptToConnect(string serialPortName, int baudRate)
        {
            connectionFailureMessage = "Unknown Reason";

            if (PrinterIsConnected)
            {
                throw new Exception("You can only connect when not currently connected.");
            }

            CommunicationState = CommunicationStates.AttemptingToConnect;
            bool serialPortIsAvailable = SerialPortIsAvailable(serialPortName);
            bool serialPortIsAlreadyOpen = SerialPortAlreadyOpen(serialPortName);

            if (serialPortIsAvailable && !serialPortIsAlreadyOpen)
            {
                if (CommunicationState == CommunicationStates.AttemptingToConnect)
                {
                    try
                    {
						serialPort = FrostedSerialPort.CreateAndOpen(serialPortName, baudRate, DtrEnableOnConnect);

						readFromPrinterThread = new Thread(ReadFromPrinter);
                        readFromPrinterThread.Name = "Read From Printer";
                        readFromPrinterThread.IsBackground = true;
                        readFromPrinterThread.Start();

                        // let's check if the printer will talk to us
                        ReadPosition();
                        SendLineToPrinterNow("M105");
                        SendLineToPrinterNow("M115");
                    }
                    catch (System.ArgumentOutOfRangeException)
                    {
                        connectionFailureMessage = "Unsupported Baud Rate";
                        OnConnectionFailed(null);
                    }

                    catch (Exception)
                    {
                        OnConnectionFailed(null);
                    }
                }
            }
        }