Merge remote-tracking branch 'origin/1.7' into design_tools

# Conflicts:
#	StaticData/Translations/Master.txt
This commit is contained in:
Lars Brubaker 2017-04-11 13:25:42 -07:00
commit aa7445b618
5 changed files with 75 additions and 59 deletions

View file

@ -59,12 +59,19 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
{
}
public void Add(string line)
public void Add(string line, bool forceTopOfQueue = false)
{
// lock queue
lock (locker)
{
commandQueue.Add(line);
if (forceTopOfQueue)
{
commandQueue.Insert(0, line);
}
else
{
commandQueue.Add(line);
}
}
}

View file

@ -44,7 +44,8 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
public override string ReadLine()
{
if (nextReadTimeMs < UiThread.CurrentTimerMs
if (!PrinterConnectionAndCommunication.Instance.WatingForPositionRead
&& nextReadTimeMs < UiThread.CurrentTimerMs
&& PrinterConnectionAndCommunication.Instance.PrinterIsConnected)
{
nextReadTimeMs = UiThread.CurrentTimerMs + 1000;

View file

@ -27,14 +27,6 @@ of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Gaming.Game;
using MatterHackers.Agg;
using MatterHackers.Agg.UI;
@ -50,6 +42,14 @@ using MatterHackers.SerialPortCommunication;
using MatterHackers.SerialPortCommunication.FrostedSerial;
using MatterHackers.VectorMath;
using Microsoft.Win32.SafeHandles;
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
namespace MatterHackers.MatterControl.PrinterCommunication
{
@ -113,6 +113,8 @@ namespace MatterHackers.MatterControl.PrinterCommunication
public RootedObjectEventHandler WroteLine = new RootedObjectEventHandler();
public bool WatingForPositionRead { get { return waitingForPosition.IsRunning || PositionReadQueued; } }
public RootedObjectEventHandler AtxPowerStateChanged = new RootedObjectEventHandler();
private bool atxPowerIsOn = false;
@ -123,7 +125,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication
private static PrinterConnectionAndCommunication globalInstance;
object locker = new object();
private object locker = new object();
private readonly int JoinThreadTimeoutMs = 5000;
@ -175,7 +177,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication
private PrinterMove lastReportedPosition;
DataViewGraph sendTimeAfterOkGraph;
private DataViewGraph sendTimeAfterOkGraph;
private GCodeFile loadedGCode = new GCodeFileLoaded();
@ -227,6 +229,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication
private double totalSdBytes = 0;
private bool PositionReadQueued { get; set; } = false;
private Stopwatch waitingForPosition = new Stopwatch();
private FoundStringContainsCallbacks WriteLineContainsCallBacks = new FoundStringContainsCallbacks();
@ -272,6 +275,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication
ReadLineStartCallBacks.AddCallbackToKey("EXTENSIONS:", PrinterStatesExtensions);
#region hardware failure callbacks
// smoothie temperature failures
ReadLineContainsCallBacks.AddCallbackToKey("T:inf", PrinterReportsError);
ReadLineContainsCallBacks.AddCallbackToKey("B:inf", PrinterReportsError);
@ -292,7 +296,8 @@ namespace MatterHackers.MatterControl.PrinterCommunication
// s3g temperature failures
ReadLineContainsCallBacks.AddCallbackToKey("Bot is Shutdown due to Overheat", PrinterReportsError);
#endregion
#endregion hardware failure callbacks
WriteLineStartCallBacks.AddCallbackToKey("M104", ExtruderTemperatureWasWritenToPrinter);
WriteLineStartCallBacks.AddCallbackToKey("M109", ExtruderTemperatureWasWritenToPrinter);
@ -321,7 +326,6 @@ namespace MatterHackers.MatterControl.PrinterCommunication
feedRateRatio = ActiveSliceSettings.Instance.GetValue<double>(SettingsKey.feedrate_ratio);
}
}, ref unregisterEvents);
}
private void ExtruderIndexSet(object sender, EventArgs e)
@ -451,7 +455,6 @@ namespace MatterHackers.MatterControl.PrinterCommunication
TurnOffBedAndExtruders();
for (int extruderIndex = 0; extruderIndex < MAX_EXTRUDERS; extruderIndex++)
{
actualExtruderTemperature[extruderIndex] = 0;
OnExtruderTemperatureRead(new TemperatureEventArgs(extruderIndex, GetActualExtruderTemperature(extruderIndex)));
}
@ -993,8 +996,8 @@ namespace MatterHackers.MatterControl.PrinterCommunication
if (ActivePrinter != null)
{
// Start the process of requesting permission and exit if permission is not currently granted
if (!ActiveSliceSettings.Instance.GetValue<bool>(SettingsKey.enable_network_printing)
&& !FrostedSerialPort.EnsureDeviceAccess())
if (!ActiveSliceSettings.Instance.GetValue<bool>(SettingsKey.enable_network_printing)
&& !FrostedSerialPort.EnsureDeviceAccess())
{
CommunicationState = CommunicationStates.FailedToConnect;
return;
@ -1162,7 +1165,6 @@ namespace MatterHackers.MatterControl.PrinterCommunication
return actualExtruderTemperature[extruderIndex0Based];
}
public double GetTargetExtruderTemperature(int extruderIndex0Based)
{
extruderIndex0Based = Math.Min(extruderIndex0Based, MAX_EXTRUDERS - 1);
@ -1248,16 +1250,15 @@ namespace MatterHackers.MatterControl.PrinterCommunication
public void OnCommunicationStateChanged(EventArgs e)
{
CommunicationStateChanged.CallEvents(this, e);
#if __ANDROID__
//Path to the printer output file
//Path to the printer output file
string pathToPrintOutputFile = Path.Combine(ApplicationDataStorage.Instance.PublicDataStoragePath, "print_output.txt");
if (CommunicationState == CommunicationStates.FinishedPrint)
{
//Only write to the text file if file exists
//Only write to the text file if file exists
if (File.Exists(pathToPrintOutputFile))
{
Task.Run(() =>
@ -1420,7 +1421,8 @@ namespace MatterHackers.MatterControl.PrinterCommunication
}
}
bool haveReportedError = false;
private bool haveReportedError = false;
public void PrinterReportsError(object sender, EventArgs e)
{
if (!haveReportedError)
@ -1510,7 +1512,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication
public void ArduinoDtrReset()
{
// TODO: Ideally we would shutdown the printer connection when this method is called and we're connected. The
// current approach results in unpredictable behavior if the caller fails to close the connection
// current approach results in unpredictable behavior if the caller fails to close the connection
if (serialPort == null && this.ActivePrinter != null)
{
IFrostedSerialPort resetSerialPort = FrostedSerialPortFactory.GetAppropriateFactory(this.DriverType).Create(this.ComPort);
@ -1685,7 +1687,8 @@ namespace MatterHackers.MatterControl.PrinterCommunication
public void ReadPosition()
{
SendLineToPrinterNow("M114");
SendLineToPrinterNow("M114", true);
PositionReadQueued = true;
}
public void ReadSdProgress(object sender, EventArgs e)
@ -1728,6 +1731,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication
waitingForPosition.Stop();
waitingForPosition.Reset();
PositionReadQueued = false;
}
public static void ParseTemperatureString(string temperatureString,
@ -1924,7 +1928,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication
}
}
public void SendLineToPrinterNow(string lineToWrite)
public void SendLineToPrinterNow(string lineToWrite, bool forceTopOfQueue = false)
{
lock (locker)
{
@ -1956,7 +1960,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication
if (lineToWrite.Trim().Length > 0)
{
// insert the command into the printing queue at the head
InjectGCode(lineToWrite);
InjectGCode(lineToWrite, forceTopOfQueue);
}
}
}
@ -1965,7 +1969,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication
public bool SerialPortIsAvailable(string portName)
//Check is serial port is in the list of available serial ports
{
if(IsNetworkPrinting())
if (IsNetworkPrinting())
{
return true;
}
@ -2017,6 +2021,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication
PrintWasCanceled = false;
waitingForPosition.Reset();
PositionReadQueued = false;
ClearQueuedGCode();
activePrintTask = printTaskToUse;
@ -2144,7 +2149,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication
}
}
public void SuppressEcho(object sender, EventArgs e)
public void SuppressEcho(object sender, EventArgs e)
{
FoundStringEventArgs foundStringEventArgs = e as FoundStringEventArgs;
foundStringEventArgs.SendToDelegateFunctions = false;
@ -2327,14 +2332,14 @@ namespace MatterHackers.MatterControl.PrinterCommunication
PrintingCanContinue(this, null);
}
private void InjectGCode(string codeToInject)
private void InjectGCode(string codeToInject, bool forceTopOfQueue = false)
{
codeToInject = codeToInject.Replace("\\n", "\n");
string[] lines = codeToInject.Split('\n');
for (int i = 0; i < lines.Length; i++)
{
queuedCommandStream2?.Add(lines[i]);
queuedCommandStream2?.Add(lines[i], forceTopOfQueue);
}
}
@ -2371,7 +2376,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication
}
}
void CreateStreamProcessors(string gcodeFilename, bool recoveryEnabled)
private void CreateStreamProcessors(string gcodeFilename, bool recoveryEnabled)
{
totalGCodeStream?.Dispose();
@ -2635,12 +2640,23 @@ namespace MatterHackers.MatterControl.PrinterCommunication
}
}
string currentSentLine;
string previousSentLine;
private string currentSentLine;
private string previousSentLine;
private int ExpectedWaitSeconds(string lastInstruction)
{
if (lastInstruction.Contains("G0 ") || lastInstruction.Contains("G1 "))
{
// for moves we wait only as much as 2 seconds
return 2;
}
return 10;
}
private void TryWriteNextLineFromGCodeFile()
{
if(totalGCodeStream == null)
if (totalGCodeStream == null)
{
// don't try to write until we are initialized
return;
@ -2654,21 +2670,11 @@ namespace MatterHackers.MatterControl.PrinterCommunication
// we are still sending commands
if (currentSentLine != null)
{
// the last instruction was a move
string lastInstruction = previousSentLine;
double epectedSecondsToWait = 2;
double maxSecondsToWait = 10;
bool wasMoveAndNoOK = lastInstruction != null
&& (lastInstruction.Contains("G0 ") || lastInstruction.Contains("G1 "))
&& timeHaveBeenWaitingForOK.Elapsed.TotalSeconds > epectedSecondsToWait;
bool waitedTooLongForOK = timeHaveBeenWaitingForOK.Elapsed.TotalSeconds > maxSecondsToWait;
// This code is to try and make sure the printer does not stop on transmission errors.
// If it has been more than 10 seconds since the printer responded anything
// and it was not ok, and it's been more than 30 second since we sent the command.
if ((timeSinceLastReadAnything.Elapsed.TotalSeconds > 10 && timeSinceLastWrite.Elapsed.TotalSeconds > 30)
|| wasMoveAndNoOK
|| waitedTooLongForOK)
|| timeHaveBeenWaitingForOK.Elapsed.TotalSeconds > ExpectedWaitSeconds(currentSentLine))
{
// Basically we got some response but it did not contain an OK.
// The theory is that we may have received a transmission error (like 'OP' rather than 'OK')
@ -2693,7 +2699,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication
else
{
int waitTimeInMs = 60000; // 60 seconds
if (waitingForPosition.IsRunning
if (waitingForPosition.IsRunning
&& waitingForPosition.ElapsedMilliseconds < waitTimeInMs
&& PrinterIsConnected)
{
@ -2709,7 +2715,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication
string[] splitOnSemicolon = currentSentLine.Split(';');
string trimedLine = splitOnSemicolon[0].Trim().ToUpper();
if (currentSentLine.Contains("M114")
if (trimedLine.Contains("M114")
&& PrinterIsConnected)
{
waitingForPosition.Restart();
@ -2757,7 +2763,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication
TurnOffBedAndExtruders();
this.PrintWasCanceled = false;
}
else if(communicationState == CommunicationStates.Printing)// we finished printing normally
else if (communicationState == CommunicationStates.Printing)// we finished printing normally
{
CommunicationState = CommunicationStates.FinishedPrint;
@ -2808,11 +2814,11 @@ namespace MatterHackers.MatterControl.PrinterCommunication
}
string lineWithChecksum = lineWithCount + "*" + GCodeFile.CalculateChecksum(lineWithCount).ToString();
allCheckSumLinesSent.Add(lineWithChecksum);
//if ((checkSumCount++ % 11) == 0)
//lineWithChecksum = lineWithCount + "*" + (GCodeFile.CalculateChecksum(lineWithCount) + checkSumCount).ToString();
//lineWithChecksum = lineWithCount + "*" + (GCodeFile.CalculateChecksum(lineWithCount) + checkSumCount).ToString();
WriteRawToPrinter(lineWithChecksum + "\n", lineToWrite);
}
@ -2938,14 +2944,15 @@ namespace MatterHackers.MatterControl.PrinterCommunication
queuedCommandStream2?.Continue();
}
bool haveHookedDrawing = false;
private bool haveHookedDrawing = false;
public class ReadThread
{
private static int currentReadThreadIndex = 0;
private int creationIndex;
static int numRunning = 0;
private static int numRunning = 0;
public static int NumRunning
{
get
@ -2954,7 +2961,6 @@ namespace MatterHackers.MatterControl.PrinterCommunication
}
}
private ReadThread()
{
numRunning++;
@ -2985,6 +2991,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication
{
new ReadThread();
}
internal bool IsCurrentThread()
{
return currentReadThreadIndex == creationIndex;
@ -3049,4 +3056,4 @@ namespace MatterHackers.MatterControl.PrinterCommunication
public int Index0Based { get; }
public double Temperature { get; }
}
}
}

@ -1 +1 @@
Subproject commit e6553f9bf75a3441f1dead52d9e0bd8a86721d64
Subproject commit fe9c5f482ab86e3833d9da0f57059c15542449a5

View file

@ -522,16 +522,17 @@ namespace MatterHackers.MatterControl.Tests.Automation
// Click Library Item Print Button
testRunner.ClickByName("Row Item Calibration - Box Print Button");
testRunner.Delay(.5);
testRunner.Delay(2);
Assert.AreEqual(initialQueueCount + 1, QueueData.Instance.ItemCount, "Queue count should increment by one after clicking 'Print'");
Assert.AreEqual("Calibration - Box", QueueData.Instance.PrintItems[0].Name, "Library item should be inserted at queue index 0");
Assert.AreEqual("Calibration - Box", QueueData.Instance.SelectedPrintItem.Name, "Library item should be the selected item");
Assert.AreEqual("Calibration - Box", PrinterConnectionAndCommunication.Instance.ActivePrintItem.Name, "PrinterConnectionCommunication item should be the expected item");
testRunner.ClickByName("Cancel Print Button");
testRunner.CancelPrint();
testRunner.Delay(1);
testRunner.WaitForName("Start Print Button", 5);
testRunner.NameExists("Start Print Button");
}
return Task.FromResult(0);