diff --git a/MatterControl.csproj b/MatterControl.csproj
index 1a83e6cda..d1076693c 100644
--- a/MatterControl.csproj
+++ b/MatterControl.csproj
@@ -194,6 +194,7 @@
+
Code
diff --git a/PrinterCommunication/PrinterConnectionAndCommunication.cs b/PrinterCommunication/PrinterConnectionAndCommunication.cs
index c6fb3a892..3f3924d60 100644
--- a/PrinterCommunication/PrinterConnectionAndCommunication.cs
+++ b/PrinterCommunication/PrinterConnectionAndCommunication.cs
@@ -102,6 +102,10 @@ namespace MatterHackers.MatterControl.PrinterCommunication
public RootedObjectEventHandler WroteLine = new RootedObjectEventHandler();
+ public RootedObjectEventHandler AtxPowerStateChanged = new RootedObjectEventHandler();
+
+ private bool atxPowerIsOn = false;
+
private const int MAX_EXTRUDERS = 16;
private const int MAX_INVALID_CONNECTION_CHARS = 3;
@@ -274,6 +278,10 @@ namespace MatterHackers.MatterControl.PrinterCommunication
WriteLineStartCallBacks.AddCallBackToKey("G90", MovementWasSetToAbsoluteMode);
WriteLineStartCallBacks.AddCallBackToKey("G91", MovementWasSetToRelativeMode);
+
+ WriteLineStartCallBacks.AddCallBackToKey("M80", AtxPowerUpWasWritenToPrinter);
+ WriteLineStartCallBacks.AddCallBackToKey("M81", AtxPowerDownWasWritenToPrinter);
+
}
private event EventHandler unregisterEvents;
@@ -482,6 +490,25 @@ namespace MatterHackers.MatterControl.PrinterCommunication
}
}
+ public bool AtxPowerEnabled
+ {
+ get
+ {
+ return atxPowerIsOn;
+ }
+ set
+ {
+ if (value)
+ {
+ PrinterConnectionAndCommunication.Instance.SendLineToPrinterNow("M80");
+ }
+ else
+ {
+ PrinterConnectionAndCommunication.Instance.SendLineToPrinterNow("M81");
+ }
+ }
+ }
+
public string ConnectionFailureMessage { get { return connectionFailureMessage; } }
public Vector3 CurrentDestination { get { return currentDestination; } }
@@ -2428,6 +2455,16 @@ namespace MatterHackers.MatterControl.PrinterCommunication
movementMode = PrinterMachineInstruction.MovementTypes.Relative;
}
+ private void AtxPowerUpWasWritenToPrinter(object sender, EventArgs e)
+ {
+ OnAtxPowerStateChanged(true);
+ }
+
+ private void AtxPowerDownWasWritenToPrinter(object sender, EventArgs e)
+ {
+ OnAtxPowerStateChanged(false);
+ }
+
private void OnActivePrintItemChanged(EventArgs e)
{
ActivePrintItemChanged.CallEvents(this, e);
@@ -2487,6 +2524,12 @@ namespace MatterHackers.MatterControl.PrinterCommunication
}
}
+ private void OnAtxPowerStateChanged(bool enableAtxPower)
+ {
+ atxPowerIsOn = enableAtxPower;
+ AtxPowerStateChanged.CallEvents(this, null);
+ }
+
private void partToPrint_SliceDone(object sender, EventArgs e)
{
PrintItemWrapper partToPrint = sender as PrintItemWrapper;
diff --git a/PrinterControls/ControlWidgets/PowerControls.cs b/PrinterControls/ControlWidgets/PowerControls.cs
new file mode 100644
index 000000000..224525868
--- /dev/null
+++ b/PrinterControls/ControlWidgets/PowerControls.cs
@@ -0,0 +1,118 @@
+/*
+Copyright (c) 2014, Kevin Pope
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+The views and conclusions contained in the software and documentation are those
+of the authors and should not be interpreted as representing official policies,
+either expressed or implied, of the FreeBSD Project.
+*/
+
+using MatterHackers.Agg;
+using MatterHackers.Agg.UI;
+using MatterHackers.Localizations;
+using MatterHackers.MatterControl.PrinterCommunication;
+using MatterHackers.MatterControl.SlicerConfiguration;
+using System;
+
+namespace MatterHackers.MatterControl.PrinterControls
+{
+ public class PowerControls : ControlWidgetBase
+ {
+ private event EventHandler unregisterEvents;
+
+ private CheckBox atxPowertoggleSwitch;
+
+ public PowerControls()
+ {
+ ActiveSliceSettings.Instance.SettingsChanged.RegisterEvent(this.UpdateControlVisibility, ref unregisterEvents);
+ PrinterConnectionAndCommunication.Instance.CommunicationStateChanged.RegisterEvent(this.UpdateControlVisibility, ref unregisterEvents);
+ PrinterConnectionAndCommunication.Instance.AtxPowerStateChanged.RegisterEvent(this.UpdatePowerSwitch, ref unregisterEvents);
+
+ this.HAnchor = Agg.UI.HAnchor.ParentLeftRight;
+ this.HAnchor = HAnchor.ParentLeftRight;
+ this.VAnchor = VAnchor.ParentBottomTop;
+ }
+
+ private void UpdateControlVisibility(object sender, EventArgs args)
+ {
+ this.Visible = ActiveSliceSettings.Instance.HasPowerControl;
+ this.SetEnableLevel(PrinterConnectionAndCommunication.Instance.PrinterIsConnected ? EnableLevel.Enabled : EnableLevel.Disabled);
+ }
+
+ private void UpdatePowerSwitch(object sender, EventArgs args)
+ {
+ this.atxPowertoggleSwitch.Checked = PrinterConnectionAndCommunication.Instance.AtxPowerEnabled;
+ }
+
+ protected override void AddChildElements()
+ {
+ AltGroupBox fanControlsGroupBox = new AltGroupBox(new TextWidget("ATX Power Control".Localize(), pointSize: 18, textColor: ActiveTheme.Instance.SecondaryAccentColor));
+ fanControlsGroupBox.Margin = new BorderDouble(0);
+ fanControlsGroupBox.BorderColor = ActiveTheme.Instance.PrimaryTextColor;
+ fanControlsGroupBox.HAnchor |= Agg.UI.HAnchor.ParentLeftRight;
+ this.AddChild(fanControlsGroupBox);
+
+ atxPowertoggleSwitch = ImageButtonFactory.CreateToggleSwitch(false);
+ atxPowertoggleSwitch.Margin = new BorderDouble(6, 0, 6, 6);
+ atxPowertoggleSwitch.CheckedStateChanged += (sender, e) =>
+ {
+ PrinterConnectionAndCommunication.Instance.AtxPowerEnabled = atxPowertoggleSwitch.Checked;
+ };
+
+ FlowLayoutWidget paddingContainer = new FlowLayoutWidget();
+ paddingContainer.Padding = new BorderDouble(3, 5, 3, 0) * TextWidget.GlobalPointSizeScaleRatio;
+ {
+ paddingContainer.AddChild(atxPowertoggleSwitch);
+ }
+ fanControlsGroupBox.AddChild(paddingContainer);
+
+ UpdateControlVisibility(null, null);
+ }
+
+ private void SetDisplayAttributes()
+ {
+ this.textImageButtonFactory.normalFillColor = RGBA_Bytes.Transparent;
+
+ this.textImageButtonFactory.FixedWidth = 38 * TextWidget.GlobalPointSizeScaleRatio;
+ this.textImageButtonFactory.FixedHeight = 20 * TextWidget.GlobalPointSizeScaleRatio;
+ this.textImageButtonFactory.fontSize = 10;
+ this.textImageButtonFactory.borderWidth = 1;
+ this.textImageButtonFactory.normalBorderColor = new RGBA_Bytes(ActiveTheme.Instance.PrimaryTextColor, 200);
+ this.textImageButtonFactory.hoverBorderColor = new RGBA_Bytes(ActiveTheme.Instance.PrimaryTextColor, 200);
+
+ this.textImageButtonFactory.disabledTextColor = RGBA_Bytes.Gray;
+ this.textImageButtonFactory.hoverTextColor = ActiveTheme.Instance.PrimaryTextColor;
+ this.textImageButtonFactory.normalTextColor = ActiveTheme.Instance.SecondaryTextColor;
+ this.textImageButtonFactory.pressedTextColor = ActiveTheme.Instance.PrimaryTextColor;
+ }
+
+ public override void OnClosed(EventArgs e)
+ {
+ if (unregisterEvents != null)
+ {
+ unregisterEvents(this, null);
+ }
+ base.OnClosed(e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/PrinterControls/ManualPrinterControls.cs b/PrinterControls/ManualPrinterControls.cs
index e4d138f19..e604e564c 100644
--- a/PrinterControls/ManualPrinterControls.cs
+++ b/PrinterControls/ManualPrinterControls.cs
@@ -78,7 +78,14 @@ namespace MatterHackers.MatterControl
AddTemperatureControls(controlsTopToBottomLayout);
AddMovementControls(controlsTopToBottomLayout);
- AddFanControls(controlsTopToBottomLayout);
+
+ FlowLayoutWidget linearPanel = new FlowLayoutWidget();
+ linearPanel.HAnchor = Agg.UI.HAnchor.ParentLeftRight;
+ controlsTopToBottomLayout.AddChild(linearPanel);
+
+ AddFanControls(linearPanel);
+ AddAtxPowerControls(linearPanel);
+
AddMacroControls(controlsTopToBottomLayout);
AddAdjustmentControls(controlsTopToBottomLayout);
@@ -125,6 +132,11 @@ namespace MatterHackers.MatterControl
}
}
+ private void AddAtxPowerControls(FlowLayoutWidget controlsTopToBottomLayout)
+ {
+ controlsTopToBottomLayout.AddChild(new PowerControls());
+ }
+
private void AddHandlers()
{
PrinterConnectionAndCommunication.Instance.CommunicationStateChanged.RegisterEvent(onPrinterStatusChanged, ref unregisterEvents);
diff --git a/SlicerConfiguration/ActiveSliceSettings.cs b/SlicerConfiguration/ActiveSliceSettings.cs
index 89cd3faa4..d5eb678dd 100644
--- a/SlicerConfiguration/ActiveSliceSettings.cs
+++ b/SlicerConfiguration/ActiveSliceSettings.cs
@@ -263,6 +263,17 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
}
}
+ ///
+ /// Control the PS_ON pin via M80/81 if enabled in firmware and printer settings, allowing the printer board to toggle off the ATX power supply
+ ///
+ public bool HasPowerControl
+ {
+ get
+ {
+ return GetActiveValue("has_power_control") == "1";
+ }
+ }
+
public bool HasHeatedBed()
{
return GetActiveValue("has_heated_bed") == "1";
diff --git a/SlicerConfiguration/SlicerMapping/EngineMappingCura.cs b/SlicerConfiguration/SlicerMapping/EngineMappingCura.cs
index 755627c2c..69f51103c 100644
--- a/SlicerConfiguration/SlicerMapping/EngineMappingCura.cs
+++ b/SlicerConfiguration/SlicerMapping/EngineMappingCura.cs
@@ -94,6 +94,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
new VisibleButNotMappedToEngine("", "bed_shape"),
new VisibleButNotMappedToEngine("", "has_fan"),
+ new VisibleButNotMappedToEngine("", "has_power_control"),
new VisibleButNotMappedToEngine("", "has_heated_bed"),
new VisibleButNotMappedToEngine("", "has_hardware_leveling"),
new VisibleButNotMappedToEngine("", "has_sd_card_reader"),
diff --git a/SlicerConfiguration/SlicerMapping/EngineMappingMatterSlice.cs b/SlicerConfiguration/SlicerMapping/EngineMappingMatterSlice.cs
index 30480c72f..4ce7cf7aa 100644
--- a/SlicerConfiguration/SlicerMapping/EngineMappingMatterSlice.cs
+++ b/SlicerConfiguration/SlicerMapping/EngineMappingMatterSlice.cs
@@ -209,6 +209,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
new VisibleButNotMappedToEngine("", "has_fan"),
new VisibleButNotMappedToEngine("", "has_hardware_leveling"),
+ new VisibleButNotMappedToEngine("", "has_power_control"),
new VisibleButNotMappedToEngine("", "has_heated_bed"),
new VisibleButNotMappedToEngine("", "has_sd_card_reader"),
new VisibleButNotMappedToEngine("", "z_can_be_negative"),
diff --git a/StaticData/PrinterSettings/config.ini b/StaticData/PrinterSettings/config.ini
index 558f42574..91cbac0c5 100644
--- a/StaticData/PrinterSettings/config.ini
+++ b/StaticData/PrinterSettings/config.ini
@@ -51,6 +51,7 @@ gcode_output_type = REPRAP
has_fan = 1
has_hardware_leveling = 0
has_heated_bed = 1
+has_power_control=0
has_sd_card_reader = 0
show_reset_connection = 0
heat_extruder_before_homing = 0
diff --git a/StaticData/SliceSettings/Layouts.txt b/StaticData/SliceSettings/Layouts.txt
index b3ec3e757..707ed706d 100644
--- a/StaticData/SliceSettings/Layouts.txt
+++ b/StaticData/SliceSettings/Layouts.txt
@@ -251,6 +251,7 @@ Advanced
has_hardware_leveling
has_heated_bed
has_sd_card_reader
+ has_power_control
show_reset_connection
extruder_count
heat_extruder_before_homing
diff --git a/StaticData/SliceSettings/Properties.json b/StaticData/SliceSettings/Properties.json
index 326d9e87b..ce45a855b 100644
--- a/StaticData/SliceSettings/Properties.json
+++ b/StaticData/SliceSettings/Properties.json
@@ -406,6 +406,13 @@
"DataEditType": "HARDWARE_PRESENT",
"ExtraSettings": ""
},
+ {
+ "SlicerConfigName": "has_power_control",
+ "PresentationName": "Has Power Control",
+ "HelpText": "Specify if your printer can control the power supply",
+ "DataEditType": "HARDWARE_PRESENT",
+ "ExtraSettings": ""
+ },
{
"SlicerConfigName": "has_sd_card_reader",
"PresentationName": "Has SD Card Reader",
diff --git a/StaticData/Translations/Master.txt b/StaticData/Translations/Master.txt
index c9ec42342..6c6f04fa9 100644
--- a/StaticData/Translations/Master.txt
+++ b/StaticData/Translations/Master.txt
@@ -3196,4 +3196,11 @@ Translated:This will cause the extruder to try to wipe itself after retracting t
English:Calculating Positions...
Translated:Calculating Positions...
+English:ATX Power Control
+Translated:ATX Power Control
+English:Specify if your printer can control the power supply
+Translated:Specify if your printer can control the power supply
+
+English:Has Power Control
+Translated:Has Power Control
\ No newline at end of file