python3: pep8 all files.

e.g. 4 spaces for identation
using black for this:
https://github.com/ambv/black
This commit is contained in:
Nico Tonnhofer 2018-12-28 20:07:51 +01:00
parent 9b49097ac3
commit bf72cb7f10
35 changed files with 6526 additions and 5803 deletions

View File

@ -14,10 +14,13 @@
from __future__ import print_function
import sys
import time
if sys.version_info.major >= 3:
print("You are currently running Python3. Python3 is not supported.\n"
print(
"You are currently running Python3. Python3 is not supported.\n"
"Please try running with Python2.\n\n"
"It often works to type \"python2 configtool.py\" in the command line.")
'It often works to type "python2 configtool.py" in the command line.'
)
time.sleep(10)
sys.exit(-1)
@ -29,14 +32,16 @@ from configtool.settings import Settings
from configtool.board import Board
from configtool.printer import Printer
cmdFolder = os.path.realpath(os.path.abspath(os.path.split(inspect.getfile(
inspect.currentframe()))[0]))
cmdFolder = os.path.realpath(
os.path.abspath(os.path.split(inspect.getfile(inspect.currentframe()))[0])
)
verbose = 0
settings = None
board = None
printer = None
def getSettings(arg=None):
global settings
if arg or not settings:
@ -44,6 +49,7 @@ def getSettings(arg = None):
settings.verbose = verbose
return settings
def cmdLoad(arg):
xx, ext = os.path.splitext(arg)
fn = os.path.basename(arg)
@ -77,6 +83,7 @@ def cmdLoad(arg):
print("Expected one of *.ini, board.*.h or printer.*.h.")
sys.exit(2)
def cmdSave(arg):
xx, ext = os.path.splitext(arg)
fn = os.path.basename(arg)
@ -105,6 +112,7 @@ def cmdSave(arg):
print("Expected one of *.ini, board.*.h or printer.*.h.")
sys.exit(2)
def cmdShowAll():
names = {"configtool": getSettings(), "board": board, "printer": printer}
for namespace in names:
@ -113,8 +121,10 @@ def cmdShowAll():
for k in sorted(values):
print("%s.%s: %s" % (namespace, k, str(values[k])))
def cmdHelp():
print("""Usage: %s [options]
print(
"""Usage: %s [options]
Running without any options starts the gui (normal operation).
Following options are available for command line automation:
@ -137,7 +147,10 @@ Following options are available for command line automation:
-a, --show-all Show all loaded variables and values.
-q, --quit Quit processing without launching the GUI.
""" % sys.argv[0])
"""
% sys.argv[0]
)
def CommandLine(argv):
""" Parse and act on command line arguments. All script automation commands
@ -147,12 +160,12 @@ def CommandLine(argv):
global settings, verbose
try:
opts, args = getopt.getopt(argv, "hvl:as:q", ["help", "verbose", "load=",
"show-all", "save=", "quit"])
opts, args = getopt.getopt(
argv, "hvl:as:q", ["help", "verbose", "load=", "show-all", "save=", "quit"]
)
except getopt.GetoptError as err:
print(err)
print("Use '%s --help' to get help with command line options." %
sys.argv[0])
print("Use '%s --help' to get help with command line options." % sys.argv[0])
sys.exit(2)
# Check for HELP first.
@ -179,8 +192,10 @@ def CommandLine(argv):
elif opt in ("-q", "--quit"):
sys.exit()
if __name__ == '__main__':
if __name__ == "__main__":
CommandLine(sys.argv[1:])
from configtool.gui import StartGui
StartGui(getSettings())

View File

@ -1,4 +1,3 @@
import wx
from configtool.page import Page
@ -10,17 +9,24 @@ class AccelerationPage(wx.Panel, Page):
self.parent = parent
self.id = idPg
self.accTypeKeys = ['ACCELERATION_REPRAP', 'ACCELERATION_RAMPING',
'ACCELERATION_TEMPORAL']
self.jerkKeys = ['MAX_JERK_X', 'MAX_JERK_Y', 'MAX_JERK_Z', 'MAX_JERK_E']
self.accTypeKeys = [
"ACCELERATION_REPRAP",
"ACCELERATION_RAMPING",
"ACCELERATION_TEMPORAL",
]
self.jerkKeys = ["MAX_JERK_X", "MAX_JERK_Y", "MAX_JERK_Z", "MAX_JERK_E"]
self.labels = {'ACCELERATION_REPRAP': "RepRap",
'ACCELERATION_RAMPING': "Ramping",
'ACCELERATION_TEMPORAL': "Temporal",
'ACCELERATION': "Acceleration:",
'LOOKAHEAD': "Look Ahead",
'MAX_JERK_X': "X:", 'MAX_JERK_Y': "Y:", 'MAX_JERK_Z': "Z:",
'MAX_JERK_E': "E:"}
self.labels = {
"ACCELERATION_REPRAP": "RepRap",
"ACCELERATION_RAMPING": "Ramping",
"ACCELERATION_TEMPORAL": "Temporal",
"ACCELERATION": "Acceleration:",
"LOOKAHEAD": "Look Ahead",
"MAX_JERK_X": "X:",
"MAX_JERK_Y": "Y:",
"MAX_JERK_Z": "Z:",
"MAX_JERK_E": "E:",
}
sz = wx.GridBagSizer()
sz.Add((20, 40), pos=(0, 0))
@ -49,14 +55,14 @@ class AccelerationPage(wx.Panel, Page):
sbox = wx.StaticBoxSizer(b, wx.VERTICAL)
sbox.Add((5, 5))
k = 'ACCELERATION'
k = "ACCELERATION"
tc = self.addTextCtrl(k, 80, self.onTextCtrlFloat)
self.textControls[k].Enable(False)
sbox.Add(tc)
sbox.Add((5, 5))
k = 'LOOKAHEAD'
k = "LOOKAHEAD"
cb = self.addCheckBox(k, self.onCheckBox)
self.checkBoxes[k].Enable(False)
@ -90,26 +96,26 @@ class AccelerationPage(wx.Panel, Page):
rb = evt.GetEventObject()
label = rb.GetLabel()
if label == self.labels['ACCELERATION_RAMPING']:
if label == self.labels["ACCELERATION_RAMPING"]:
ena = True
else:
ena = False
self.checkBoxes['LOOKAHEAD'].Enable(ena)
self.textControls['ACCELERATION'].Enable(ena)
self.checkBoxes["LOOKAHEAD"].Enable(ena)
self.textControls["ACCELERATION"].Enable(ena)
evt.Skip()
def insertValues(self, cfgValues):
Page.insertValues(self, cfgValues)
self.checkBoxes['LOOKAHEAD'].Enable(False)
self.textControls['ACCELERATION'].Enable(False)
self.checkBoxes["LOOKAHEAD"].Enable(False)
self.textControls["ACCELERATION"].Enable(False)
for tag in self.accTypeKeys:
if tag in cfgValues.keys() and cfgValues[tag]:
self.radioButtons[tag].SetValue(True)
if tag == 'ACCELERATION_RAMPING':
self.checkBoxes['LOOKAHEAD'].Enable(True)
self.textControls['ACCELERATION'].Enable(True)
if tag == "ACCELERATION_RAMPING":
self.checkBoxes["LOOKAHEAD"].Enable(True)
self.textControls["ACCELERATION"].Enable(True)
def getValues(self):
result = Page.getValues(self)

View File

@ -1,11 +1,20 @@
import wx
from configtool.data import BSIZESMALL, offsetChLabel, offsetTcLabel
class AddHeaterDlg(wx.Dialog):
def __init__(self, parent, names, pins, font,
name = "", pin = "", invert = "0", pwm = "1", max_pwm = "100"):
def __init__(
self,
parent,
names,
pins,
font,
name="",
pin="",
invert="0",
pwm="1",
max_pwm="100",
):
wx.Dialog.__init__(self, parent, wx.ID_ANY, "Add heater", size=(400, 204))
self.SetFont(font)
self.Bind(wx.EVT_CLOSE, self.onCancel)
@ -13,17 +22,18 @@ class AddHeaterDlg(wx.Dialog):
self.names = names
self.choices = pins
self.nameValid = (name != "")
self.maxPWMValid = (max_pwm != "")
self.pwmValid = (pwm != "")
self.nameValid = name != ""
self.maxPWMValid = max_pwm != ""
self.pwmValid = pwm != ""
sz = wx.BoxSizer(wx.VERTICAL)
gsz = wx.GridBagSizer()
gsz.Add((20, 20), pos=(0, 0))
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, "Heater Name:", size = (80, -1),
style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self, wx.ID_ANY, "Heater Name:", size=(80, -1), style=wx.ALIGN_RIGHT
)
st.SetFont(font)
lsz.Add(st, 1, wx.TOP, offsetTcLabel)
@ -38,8 +48,7 @@ class AddHeaterDlg(wx.Dialog):
gsz.Add(lsz, pos=(1, 1))
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, "Pin:", size = (80, -1),
style = wx.ALIGN_RIGHT)
st = wx.StaticText(self, wx.ID_ANY, "Pin:", size=(80, -1), style=wx.ALIGN_RIGHT)
st.SetFont(font)
lsz.Add(st, 1, wx.TOP, offsetChLabel)
@ -57,8 +66,9 @@ class AddHeaterDlg(wx.Dialog):
gsz.Add(lsz, pos=(3, 1))
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, "Max PWM:", size = (80, -1),
style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self, wx.ID_ANY, "Max PWM:", size=(80, -1), style=wx.ALIGN_RIGHT
)
st.SetFont(font)
lsz.Add(st, 1, wx.TOP, offsetChLabel)
@ -66,9 +76,11 @@ class AddHeaterDlg(wx.Dialog):
self.tcMaxPWM.SetFont(font)
self.tcMaxPWM.Bind(wx.EVT_TEXT, self.onMaxPWM)
lsz.Add(self.tcMaxPWM)
self.tcMaxPWM.SetToolTip("Enter max. PWM value in [%]. Typically \n"
self.tcMaxPWM.SetToolTip(
"Enter max. PWM value in [%]. Typically \n"
"between 40 and 100. Standard is 100.\n"
"Valid values 1 to 100.")
"Valid values 1 to 100."
)
gsz.Add(lsz, pos=(5, 1))
@ -80,8 +92,7 @@ class AddHeaterDlg(wx.Dialog):
gsz.Add(self.cbInv, pos=(3, 3))
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, "PWM:", size = (60, -1),
style = wx.ALIGN_RIGHT)
st = wx.StaticText(self, wx.ID_ANY, "PWM:", size=(60, -1), style=wx.ALIGN_RIGHT)
st.SetFont(font)
lsz.Add(st, 1, wx.TOP, offsetChLabel)
@ -89,11 +100,13 @@ class AddHeaterDlg(wx.Dialog):
self.tcPwm.SetFont(font)
self.tcPwm.Bind(wx.EVT_TEXT, self.onPWM)
lsz.Add(self.tcPwm)
self.tcPwm.SetToolTip("Use Pulse Width Modulation. "
self.tcPwm.SetToolTip(
"Use Pulse Width Modulation. "
"Hardware PWM if available or "
"Software PWM. When FORCE_SOFTWARE_PWM "
"is set, always software PWM for 1 and "
"hardware PWM for >= 2.")
"hardware PWM for >= 2."
)
gsz.Add((50, 15), pos=(1, 2))
gsz.Add(lsz, pos=(1, 3))
@ -189,7 +202,7 @@ class AddHeaterDlg(wx.Dialog):
evt.Skip()
def checkDlgValidity(self):
if (self.nameValid and self.maxPWMValid and self.pwmValid):
if self.nameValid and self.maxPWMValid and self.pwmValid:
self.bSave.Enable(True)
else:
self.bSave.Enable(False)

View File

@ -1,7 +1,13 @@
import wx
from configtool.data import (pinNames, BSIZESMALL, sensorTypes, offsetTcLabel,
offsetChLabel, reInteger, reFloat)
from configtool.data import (
pinNames,
BSIZESMALL,
sensorTypes,
offsetTcLabel,
offsetChLabel,
reInteger,
reFloat,
)
from configtool.thermistorpresets import thermistorPresets
MODE_NONTHERM = 0
@ -15,8 +21,19 @@ labelWidth = 160
class AddSensorDlg(wx.Dialog):
def __init__(self, parent, names, pins, heatersPage, font, name = "",
stype = "", pin = "", params = [], modify = False):
def __init__(
self,
parent,
names,
pins,
heatersPage,
font,
name="",
stype="",
pin="",
params=[],
modify=False,
):
if modify:
title = "Modify temperature sensor"
else:
@ -58,8 +75,9 @@ class AddSensorDlg(wx.Dialog):
csz.Add((10, 10))
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, "Heater Name:", size = (labelWidth, -1),
style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self, wx.ID_ANY, "Heater Name:", size=(labelWidth, -1), style=wx.ALIGN_RIGHT
)
st.SetFont(font)
lsz.Add(st, 1, wx.TOP, offsetTcLabel)
@ -82,17 +100,20 @@ class AddSensorDlg(wx.Dialog):
self.tcName.SetFont(font)
self.tcName.Bind(wx.EVT_CHOICE, self.onHeaterName)
lsz.Add(self.tcName)
self.tcName.SetToolTip("Choose the name of the corresponding heater. "
self.tcName.SetToolTip(
"Choose the name of the corresponding heater. "
"This may require to define that heater "
"first.")
"first."
)
self.tcName.SetSelection(0)
csz.Add(lsz)
csz.Add((10, 10))
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, "Sensor Type:", size = (labelWidth, -1),
style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self, wx.ID_ANY, "Sensor Type:", size=(labelWidth, -1), style=wx.ALIGN_RIGHT
)
st.SetFont(font)
lsz.Add(st, 1, wx.TOP, offsetChLabel)
@ -122,8 +143,9 @@ class AddSensorDlg(wx.Dialog):
csz.Add((10, 10))
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, "Pin:", size = (labelWidth, -1),
style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self, wx.ID_ANY, "Pin:", size=(labelWidth, -1), style=wx.ALIGN_RIGHT
)
st.SetFont(font)
lsz.Add(st, 1, wx.TOP, offsetChLabel)
@ -143,8 +165,9 @@ class AddSensorDlg(wx.Dialog):
csz.Add((10, 10))
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, "", size = (labelWidth, -1),
style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self, wx.ID_ANY, "", size=(labelWidth, -1), style=wx.ALIGN_RIGHT
)
st.SetFont(font)
lsz.Add(st, 1, wx.TOP, offsetTcLabel)
self.label0 = st
@ -159,8 +182,9 @@ class AddSensorDlg(wx.Dialog):
csz.Add((10, 10))
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, "", size = (labelWidth, -1),
style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self, wx.ID_ANY, "", size=(labelWidth, -1), style=wx.ALIGN_RIGHT
)
st.SetFont(font)
lsz.Add(st, 1, wx.TOP, offsetTcLabel)
self.label1 = st
@ -174,8 +198,9 @@ class AddSensorDlg(wx.Dialog):
csz.Add((10, 10))
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, "", size = (labelWidth, -1),
style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self, wx.ID_ANY, "", size=(labelWidth, -1), style=wx.ALIGN_RIGHT
)
st.SetFont(font)
lsz.Add(st, 1, wx.TOP, offsetTcLabel)
self.label2 = st
@ -189,8 +214,9 @@ class AddSensorDlg(wx.Dialog):
csz.Add((10, 10))
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, "", size = (labelWidth, -1),
style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self, wx.ID_ANY, "", size=(labelWidth, -1), style=wx.ALIGN_RIGHT
)
st.SetFont(font)
lsz.Add(st, 1, wx.TOP, offsetTcLabel)
self.label3 = st
@ -204,8 +230,9 @@ class AddSensorDlg(wx.Dialog):
csz.Add((10, 10))
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, "", size = (labelWidth, -1),
style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self, wx.ID_ANY, "", size=(labelWidth, -1), style=wx.ALIGN_RIGHT
)
st.SetFont(font)
lsz.Add(st, 1, wx.TOP, offsetTcLabel)
self.label4 = st
@ -219,8 +246,9 @@ class AddSensorDlg(wx.Dialog):
csz.Add((10, 10))
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, "", size = (labelWidth, -1),
style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self, wx.ID_ANY, "", size=(labelWidth, -1), style=wx.ALIGN_RIGHT
)
st.SetFont(font)
lsz.Add(st, 1, wx.TOP, offsetTcLabel)
self.label5 = st
@ -234,8 +262,9 @@ class AddSensorDlg(wx.Dialog):
csz.Add((10, 10))
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, "", size = (labelWidth, -1),
style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self, wx.ID_ANY, "", size=(labelWidth, -1), style=wx.ALIGN_RIGHT
)
st.SetFont(font)
lsz.Add(st, 1, wx.TOP, offsetTcLabel)
self.label6 = st
@ -257,8 +286,9 @@ class AddSensorDlg(wx.Dialog):
csz.Add((30, 45))
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, "Presets:",
size = (70, -1), style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self, wx.ID_ANY, "Presets:", size=(70, -1), style=wx.ALIGN_RIGHT
)
st.SetFont(font)
lsz.Add(st, 1, wx.TOP, offsetTcLabel)
@ -290,7 +320,7 @@ class AddSensorDlg(wx.Dialog):
sbox.Add(rb, 1, wx.LEFT + wx.RIGHT, 16)
sbox.Add((5, 5))
self.rbMethod[self.currentMethod].SetValue(True);
self.rbMethod[self.currentMethod].SetValue(True)
csz.Add(sbox)
hsz.Add(csz)
@ -343,9 +373,16 @@ class AddSensorDlg(wx.Dialog):
return
def checkDlgValidity(self):
if (self.nameValid and self.param0Valid and self.param1Valid and
self.param2Valid and self.param3Valid and self.param4Valid and
self.param5Valid and self.param6Valid):
if (
self.nameValid
and self.param0Valid
and self.param1Valid
and self.param2Valid
and self.param3Valid
and self.param4Valid
and self.param5Valid
and self.param6Valid
):
self.bSave.Enable(True)
else:
self.bSave.Enable(False)
@ -518,37 +555,51 @@ class AddSensorDlg(wx.Dialog):
def setDialogMode(self):
if self.currentMode == MODE_THERMISTOR:
if self.currentMethod == METHOD_BETA:
self.param0.SetToolTip("Nominal resistance of the thermistor. "
self.param0.SetToolTip(
"Nominal resistance of the thermistor. "
"Typically 10000 ( = 10k) or 100000 "
"( = 100k).")
"( = 100k)."
)
self.label0.SetLabel("R0:")
self.param1.SetToolTip("Thermistor beta value. Can be found in "
self.param1.SetToolTip(
"Thermistor beta value. Can be found in "
"the datasheet or measured like described "
"in http://reprap.org/wiki/"
"MeasuringThermistorBeta")
"MeasuringThermistorBeta"
)
self.label1.SetLabel("Beta:")
self.param2.SetToolTip("Resistance value of the secondary "
self.param2.SetToolTip(
"Resistance value of the secondary "
"resistor. This is not a property of the "
"thermistor, but one of the board. "
"Typical values are 4700 ( = 4k7 ohms) "
"or 1000 ( = 1k ohms).")
"or 1000 ( = 1k ohms)."
)
self.label2.SetLabel("R2:")
self.param3.SetToolTip("Comparison voltage used by the "
self.param3.SetToolTip(
"Comparison voltage used by the "
"controller. Usually the same as the "
"controller's supply voltage, 3.3 or 5.0 "
"(volts).")
"(volts)."
)
self.label3.SetLabel("Vadc:")
self.label4.SetLabel("")
self.param4.SetToolTip(None)
self.param4.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))
self.param4.SetBackgroundColour(
wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW)
)
self.param4.Refresh()
self.label5.SetLabel("")
self.param5.SetToolTip(None)
self.param5.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))
self.param5.SetBackgroundColour(
wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW)
)
self.param5.Refresh()
self.label6.SetLabel("")
self.param6.SetToolTip(None)
self.param6.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))
self.param6.SetBackgroundColour(
wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW)
)
self.param6.Refresh()
self.param4.Enable(False)
self.param5.Enable(False)
@ -556,18 +607,24 @@ class AddSensorDlg(wx.Dialog):
else:
self.param0.SetToolTip("Reference resistance value.")
self.label0.SetLabel("Rp:")
self.param1.SetToolTip("First data point, temperature at which "
"resistance is equal to R0.")
self.param1.SetToolTip(
"First data point, temperature at which "
"resistance is equal to R0."
)
self.label1.SetLabel("T0:")
self.param2.SetToolTip("Resistance when temperature is T0.")
self.label2.SetLabel("R0:")
self.param3.SetToolTip("Second data point, temperature at which "
"resistance is equal to R1.")
self.param3.SetToolTip(
"Second data point, temperature at which "
"resistance is equal to R1."
)
self.label3.SetLabel("T1:")
self.param4.SetToolTip("Resistance when temperature is T1.")
self.label4.SetLabel("R1:")
self.param5.SetToolTip("Third data point, temperature at which "
"resistance is equal to R2.")
self.param5.SetToolTip(
"Third data point, temperature at which "
"resistance is equal to R2."
)
self.label5.SetLabel("T2:")
self.param6.SetToolTip("Resistance when temperature is T2.")
self.label6.SetLabel("R2:")
@ -590,64 +647,71 @@ class AddSensorDlg(wx.Dialog):
self.label6.SetSize((labelWidth, -1))
self.label6.SetWindowStyle(wx.ALIGN_RIGHT)
self.param0.Enable(True);
self.param1.Enable(True);
self.param2.Enable(True);
self.param3.Enable(True);
self.chPresets.Enable(True);
self.param0.Enable(True)
self.param1.Enable(True)
self.param2.Enable(True)
self.param3.Enable(True)
self.chPresets.Enable(True)
for rb in self.rbMethod:
rb.Enable(True)
else:
self.param0.SetToolTip(None)
self.label0.SetLabel("")
self.param0.SetBackgroundColour(
wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))
wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW)
)
self.param0.Refresh()
self.param1.SetToolTip(None)
self.label1.SetLabel("")
self.param1.SetBackgroundColour(
wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))
wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW)
)
self.param1.Refresh()
self.param2.SetToolTip(None)
self.label2.SetLabel("")
self.param2.SetBackgroundColour(
wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))
wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW)
)
self.param2.Refresh()
self.param3.SetToolTip(None)
self.label3.SetLabel("")
self.param3.SetBackgroundColour(
wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))
wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW)
)
self.param3.Refresh()
self.param4.SetToolTip(None)
self.label4.SetLabel("")
self.param4.SetBackgroundColour(
wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))
wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW)
)
self.param4.Refresh()
self.param5.SetToolTip(None)
self.label5.SetLabel("")
self.param5.SetBackgroundColour(
wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))
wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW)
)
self.param5.Refresh()
self.param6.SetToolTip(None)
self.label6.SetLabel("")
self.param6.SetBackgroundColour(
wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))
wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW)
)
self.param6.Refresh()
self.param0.Enable(False);
self.param1.Enable(False);
self.param2.Enable(False);
self.param3.Enable(False);
self.param4.Enable(False);
self.param5.Enable(False);
self.param6.Enable(False);
self.chPresets.Enable(False);
self.param0.Enable(False)
self.param1.Enable(False)
self.param2.Enable(False)
self.param3.Enable(False)
self.param4.Enable(False)
self.param5.Enable(False)
self.param6.Enable(False)
self.chPresets.Enable(False)
for rb in self.rbMethod:
rb.Enable(False)
@ -700,18 +764,22 @@ class AddSensorDlg(wx.Dialog):
stype = self.chType.GetString(self.chType.GetSelection())
if self.currentMode == MODE_THERMISTOR:
if self.currentMethod == METHOD_BETA:
addtl = [str(self.param0.GetValue().strip()),
addtl = [
str(self.param0.GetValue().strip()),
str(self.param1.GetValue().strip()),
str(self.param2.GetValue().strip()),
str(self.param3.GetValue().strip())]
str(self.param3.GetValue().strip()),
]
else:
addtl = [str(self.param0.GetValue().strip()),
addtl = [
str(self.param0.GetValue().strip()),
str(self.param1.GetValue().strip()),
str(self.param2.GetValue().strip()),
str(self.param3.GetValue().strip()),
str(self.param4.GetValue().strip()),
str(self.param5.GetValue().strip()),
str(self.param6.GetValue().strip())]
str(self.param6.GetValue().strip()),
]
else:
addtl = None

View File

@ -4,16 +4,39 @@ import os
import re
from sys import platform
from configtool.data import (defineValueFormat,
defineBoolFormat, defineHeaterFormat,
reHelpTextStart, reHelpTextEnd,
reStartSensors, reEndSensors, reStartHeaters,
reEndHeaters, reCandHeatPins, reCandThermPins,
reCandProcessors, reCandCPUClocks, reFloatAttr,
reDefine, reDefineBL, reDefQS, reDefQSm,
reDefQSm2, reDefBool, reDefBoolBL, reDefHT,
reDefTS, reDefTT, reSensor, reHeater3, reHeater4,
reHeater5, reTempTable4, reTempTable7)
from configtool.data import (
defineValueFormat,
defineBoolFormat,
defineHeaterFormat,
reHelpTextStart,
reHelpTextEnd,
reStartSensors,
reEndSensors,
reStartHeaters,
reEndHeaters,
reCandHeatPins,
reCandThermPins,
reCandProcessors,
reCandCPUClocks,
reFloatAttr,
reDefine,
reDefineBL,
reDefQS,
reDefQSm,
reDefQSm2,
reDefBool,
reDefBoolBL,
reDefHT,
reDefTS,
reDefTT,
reSensor,
reHeater3,
reHeater4,
reHeater5,
reTempTable4,
reTempTable7,
)
class Board:
def __init__(self, settings):
@ -35,17 +58,17 @@ class Board:
def getCPUInfo(self):
vF_CPU = None
if 'F_CPU' in self.cfgValues.keys():
vF_CPU = self.cfgValues['F_CPU'][0]
if "F_CPU" in self.cfgValues.keys():
vF_CPU = self.cfgValues["F_CPU"][0]
vCPU = None
if 'CPU' in self.cfgValues.keys():
vCPU = self.cfgValues['CPU'][0]
if "CPU" in self.cfgValues.keys():
vCPU = self.cfgValues["CPU"][0]
return vF_CPU, vCPU
def hasData(self):
return (self.configFile != None)
return self.configFile != None
def getFileName(self):
return self.configFile
@ -244,9 +267,13 @@ class Board:
# Accept booleans, but not those for which a value exists already.
# Booleans already existing as values are most likely misconfigured
# manual edits (or result of a bug).
if len(t) == 1 and t[0] in self.cfgNames \
and not (t[0] in self.cfgValues \
and isinstance(self.cfgValues[t[0]], tuple)):
if (
len(t) == 1
and t[0] in self.cfgNames
and not (
t[0] in self.cfgValues and isinstance(self.cfgValues[t[0]], tuple)
)
):
if reDefBoolBL.search(ln):
self.cfgValues[t[0]] = True
else:
@ -315,7 +342,7 @@ class Board:
t = m.groups()
if len(t) == 4:
t = list(t)
t.insert(5, '100')
t.insert(5, "100")
return t
# reHeater3 deprecated, for compatibility with old config files only.
m = reHeater3.search(s)
@ -323,8 +350,8 @@ class Board:
t = m.groups()
if len(t) == 3:
t = list(t)
t.insert(2, '0')
t.insert(5, '100')
t.insert(2, "0")
t.insert(5, "100")
return t
# End of deprecated part.
return None
@ -351,7 +378,7 @@ class Board:
if self.settings.verbose >= 2:
print(values)
fp = file(path, 'w')
fp = file(path, "w")
self.configFile = path
skipToSensorEnd = False
@ -365,8 +392,9 @@ class Board:
m = reStartSensors.match(ln)
if m:
fp.write(ln)
fp.write("// name type pin "
"additional\n");
fp.write(
"// name type pin " "additional\n"
)
ttString = "\n"
ttString += "// Beta algorithm r0 beta r2 vadc\n"
ttString += "// Steinhart-Hart rp t0 r0 t1 "
@ -379,14 +407,27 @@ class Board:
sstr += "THERMISTOR_%s" % s[0].upper()
tt = s[3]
if len(tt) == 4:
ttString += "//TEMP_TABLE %-8s (%-8s%-6s%-6s%s)\n" % \
(s[0].upper(), (tt[0] + ","), (tt[1] + ","),
(tt[2] + ","), tt[3])
ttString += "//TEMP_TABLE %-8s (%-8s%-6s%-6s%s)\n" % (
s[0].upper(),
(tt[0] + ","),
(tt[1] + ","),
(tt[2] + ","),
tt[3],
)
else:
ttString += "//TEMP_TABLE %-8s (%-8s%-6s%-8s%-6s%-8s%-6s%s)\n" % \
(s[0].upper(), (tt[0] + ","), (tt[1] + ","),
(tt[2] + ","), (tt[3] + ","), (tt[4] + ","),
(tt[5] + ","), tt[6])
ttString += (
"//TEMP_TABLE %-8s (%-8s%-6s%-8s%-6s%-8s%-6s%s)\n"
% (
s[0].upper(),
(tt[0] + ","),
(tt[1] + ","),
(tt[2] + ","),
(tt[3] + ","),
(tt[4] + ","),
(tt[5] + ","),
tt[6],
)
)
fp.write("DEFINE_TEMP_SENSOR(%s)\n" % sstr)
fp.write(ttString)
skipToSensorEnd = True
@ -404,8 +445,13 @@ class Board:
fp.write(ln)
fp.write("// name pin invert pwm max_pwm\n")
for s in self.heaters:
sstr = "%-10s%-9s%-8s%-7s%s" % ((s[0] + ","), (s[1] + ","),
(s[2] + ","), s[3] + ",", s[4])
sstr = "%-10s%-9s%-8s%-7s%s" % (
(s[0] + ","),
(s[1] + ","),
(s[2] + ","),
s[3] + ",",
s[4],
)
fp.write("DEFINE_HEATER(%s)\n" % sstr)
fp.write("\n")
for s in self.heaters:
@ -458,7 +504,7 @@ class Board:
fp.write("//")
fp.write(defineValueFormat % (t[0], v[0]))
else:
if t[0] == 'RX_ENABLE_PIN' or t[0] == 'TX_ENABLE_PIN':
if t[0] == "RX_ENABLE_PIN" or t[0] == "TX_ENABLE_PIN":
# Known to be absent in the GUI, also won't be added anytime soon.
fp.write(ln)
else:
@ -476,7 +522,7 @@ class Board:
fp.write("//")
fp.write(defineBoolFormat % t[0])
else:
if t[0] == 'MOTHERBOARD':
if t[0] == "MOTHERBOARD":
# Known to be absent in the GUI, also won't be added anytime soon.
fp.write(ln)
else:

View File

@ -1,20 +1,40 @@
import os
import wx
import re
from sys import platform
from configtool.decoration import Decoration
from configtool.data import (defineValueFormat,
defineBoolFormat, defineHeaterFormat,
reHelpTextStart, reHelpTextEnd,
reStartSensors, reEndSensors, reStartHeaters,
reEndHeaters, reCandHeatPins, reCandThermPins,
reCandProcessors, reCandCPUClocks, reFloatAttr,
reDefine, reDefineBL, reDefQS, reDefQSm,
reDefQSm2, reDefBool, reDefBoolBL, reDefHT,
reDefTS, reDefTT, reSensor, reHeater3, reHeater4,
reTempTable4, reTempTable7)
from configtool.data import (
defineValueFormat,
defineBoolFormat,
defineHeaterFormat,
reHelpTextStart,
reHelpTextEnd,
reStartSensors,
reEndSensors,
reStartHeaters,
reEndHeaters,
reCandHeatPins,
reCandThermPins,
reCandProcessors,
reCandCPUClocks,
reFloatAttr,
reDefine,
reDefineBL,
reDefQS,
reDefQSm,
reDefQSm2,
reDefBool,
reDefBoolBL,
reDefHT,
reDefTS,
reDefTT,
reSensor,
reHeater3,
reHeater4,
reTempTable4,
reTempTable7,
)
from configtool.pinoutspage import PinoutsPage
from configtool.displaypage import DisplayPage
from configtool.sensorpage import SensorsPage
@ -26,6 +46,7 @@ from configtool.thermistortablefile import generateTempTables
from configtool.board import Board
class BoardPanel(wx.Panel):
def __init__(self, parent, nb, settings):
wx.Panel.__init__(self, nb, wx.ID_ANY)
@ -44,8 +65,7 @@ class BoardPanel(wx.Panel):
self.Bind(wx.EVT_PAINT, self.deco.onPaintBackground)
sz = wx.BoxSizer(wx.HORIZONTAL)
self.nb = wx.Notebook(self, wx.ID_ANY, size = (21, 21),
style = wx.BK_DEFAULT)
self.nb = wx.Notebook(self, wx.ID_ANY, size=(21, 21), style=wx.BK_DEFAULT)
self.nb.SetBackgroundColour(self.deco.getBackgroundColour())
self.nb.SetFont(self.settings.font)
@ -58,10 +78,10 @@ class BoardPanel(wx.Panel):
self.pgPins = self.registerPage(PinoutsPage, "Pinouts")
self.pgDisplay = self.registerPage(DisplayPage, "Display")
self.pgHeaters = self.registerPage(HeatersPage, "Heaters")
self.pgSensors = self.registerPage(SensorsPage, "Temperature Sensors",
heatersPage = self.pgHeaters)
self.pgCommunications = self.registerPage(CommunicationsPage,
"Communications")
self.pgSensors = self.registerPage(
SensorsPage, "Temperature Sensors", heatersPage=self.pgHeaters
)
self.pgCommunications = self.registerPage(CommunicationsPage, "Communications")
sz.Add(self.nb, 1, wx.EXPAND + wx.ALL, 5)
@ -69,8 +89,9 @@ class BoardPanel(wx.Panel):
self.Fit()
def registerPage(self, klass, label, *args, **kwargs):
page = klass(self, self.nb, len(self.pages), *args,
font = self.settings.font, **kwargs)
page = klass(
self, self.nb, len(self.pages), *args, font=self.settings.font, **kwargs
)
self.nb.AddPage(page, label)
self.pages.append(page)
self.titles.append(label)
@ -86,7 +107,7 @@ class BoardPanel(wx.Panel):
self.modifyTab(pg)
def isModified(self):
return (True in self.pageModified)
return True in self.pageModified
def isValid(self):
return not (False in self.pageValid)
@ -140,11 +161,14 @@ class BoardPanel(wx.Panel):
if True not in self.pageModified:
return True
dlg = wx.MessageDialog(self, "Are you sure you want to " + msg + "?\n"
dlg = wx.MessageDialog(
self,
"Are you sure you want to " + msg + "?\n"
"There are changes to your board "
"configuration that will be lost.",
"Changes pending",
wx.YES_NO | wx.NO_DEFAULT | wx.ICON_INFORMATION)
wx.YES_NO | wx.NO_DEFAULT | wx.ICON_INFORMATION,
)
rc = dlg.ShowModal()
dlg.Destroy()
@ -163,9 +187,14 @@ class BoardPanel(wx.Panel):
else:
wildcard = "Board configuration (board.*.h)|board.*.h"
dlg = wx.FileDialog(self, message = "Choose a board config file",
defaultDir = self.dir, defaultFile = "",
wildcard = wildcard, style = wx.FD_OPEN | wx.FD_CHANGE_DIR)
dlg = wx.FileDialog(
self,
message="Choose a board config file",
defaultDir=self.dir,
defaultFile="",
wildcard=wildcard,
style=wx.FD_OPEN | wx.FD_CHANGE_DIR,
)
path = None
if dlg.ShowModal() == wx.ID_OK:
@ -179,8 +208,12 @@ class BoardPanel(wx.Panel):
rc, efn = self.loadConfigFile(path)
if not rc:
dlg = wx.MessageDialog(self, "Unable to process file %s." % efn,
"File error", wx.OK + wx.ICON_ERROR)
dlg = wx.MessageDialog(
self,
"Unable to process file %s." % efn,
"File error",
wx.OK + wx.ICON_ERROR,
)
dlg.ShowModal()
dlg.Destroy()
return
@ -223,9 +256,14 @@ class BoardPanel(wx.Panel):
else:
wildcard = "Board configuration (board.*.h)|board.*.h"
dlg = wx.FileDialog(self, message = "Save as ...", defaultDir = self.dir,
defaultFile = "", wildcard = wildcard,
style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
dlg = wx.FileDialog(
self,
message="Save as ...",
defaultDir=self.dir,
defaultFile="",
wildcard=wildcard,
style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT,
)
val = dlg.ShowModal()
@ -245,17 +283,24 @@ class BoardPanel(wx.Panel):
def saveConfigFile(self, path):
if os.path.basename(path) in protectedFiles:
dlg = wx.MessageDialog(self, "It's not allowed to overwrite files "
dlg = wx.MessageDialog(
self,
"It's not allowed to overwrite files "
"distributed by Teacup. Choose another name.",
"Protected file error", wx.OK + wx.ICON_ERROR)
"Protected file error",
wx.OK + wx.ICON_ERROR,
)
dlg.ShowModal()
dlg.Destroy()
return False
if not os.path.basename(path).startswith("board."):
dlg = wx.MessageDialog(self, "Illegal file name: %s.\n"
"File name must begin with \"board.\"" % path,
"Illegal file name", wx.OK + wx.ICON_ERROR)
dlg = wx.MessageDialog(
self,
"Illegal file name: %s.\n" 'File name must begin with "board."' % path,
"Illegal file name",
wx.OK + wx.ICON_ERROR,
)
dlg.ShowModal()
dlg.Destroy()
return False
@ -275,8 +320,12 @@ class BoardPanel(wx.Panel):
try:
self.board.saveConfigFile(path, values)
except:
dlg = wx.MessageDialog(self, "Unable to write to file %s." % path,
"File error", wx.OK + wx.ICON_ERROR)
dlg = wx.MessageDialog(
self,
"Unable to write to file %s." % path,
"File error",
wx.OK + wx.ICON_ERROR,
)
dlg.ShowModal()
dlg.Destroy()
return False
@ -285,8 +334,12 @@ class BoardPanel(wx.Panel):
def generateTempTables(self):
if not generateTempTables(self.board.sensors, self.settings):
dlg = wx.MessageDialog(self, "Error writing to file thermistortable.h.",
"File error", wx.OK + wx.ICON_ERROR)
dlg = wx.MessageDialog(
self,
"Error writing to file thermistortable.h.",
"File error",
wx.OK + wx.ICON_ERROR,
)
dlg.ShowModal()
dlg.Destroy()
return False

View File

@ -1,4 +1,3 @@
import wx.lib.newevent
import thread, shlex, subprocess
import os, re
@ -15,8 +14,8 @@ SCRIPT_CANCELLED = 3
TOOLPATHS_INSIDE_ARDUINO = [
"hardware/tools/avr/bin/",
"hardware/tools/" # avrdude in Arduino 1.0.x
]
"hardware/tools/",
] # avrdude in Arduino 1.0.x
if platform.startswith("darwin"):
# That's an OS property, the Applicaton Bundle hierarchy.
pathsCopy = TOOLPATHS_INSIDE_ARDUINO
@ -47,11 +46,11 @@ class ScriptTools:
cmdpathTry = os.path.join(cmdpathTry, dir)
cmdpathTry = os.path.join(cmdpathTry, baseCommand)
if os.path.exists(cmdpathTry):
cmdpath = "\"" + cmdpathTry + "\""
cmdpath = '"' + cmdpathTry + '"'
break
if findConf:
confpath = cmdpath.strip("\"")
confpath = cmdpath.strip('"')
exepos = confpath.rfind(".exe")
if exepos >= 0:
confpath = confpath[0:exepos]
@ -62,7 +61,7 @@ class ScriptTools:
confpath = os.path.join(confpath, "etc")
confpath = os.path.join(confpath, "avrdude.conf")
if os.path.exists(confpath):
cmdpath += " -C \"" + confpath + "\""
cmdpath += ' -C "' + confpath + '"'
else:
cmdpath = baseCommand
@ -100,27 +99,34 @@ class ScriptThread:
args = shlex.split(str(cmd))
try:
if platform.startswith("win"):
p = subprocess.Popen(args, stderr = subprocess.STDOUT,
p = subprocess.Popen(
args,
stderr=subprocess.STDOUT,
stdout=subprocess.PIPE,
startupinfo = startupinfo)
startupinfo=startupinfo,
)
else:
p = subprocess.Popen(args, stderr = subprocess.STDOUT,
stdout = subprocess.PIPE)
p = subprocess.Popen(
args, stderr=subprocess.STDOUT, stdout=subprocess.PIPE
)
except:
evt = scriptEvent(msg = "Exception occurred trying to run\n\n%s" % cmd,
state = SCRIPT_CANCELLED)
evt = scriptEvent(
msg="Exception occurred trying to run\n\n%s" % cmd,
state=SCRIPT_CANCELLED,
)
wx.PostEvent(self.win, evt)
self.running = False
return
obuf = ''
obuf = ""
while not self.cancelled:
o = p.stdout.read(1)
if o == '': break
if o == '\r' or o == '\n':
if o == "":
break
if o == "\r" or o == "\n":
if obuf.strip() != "":
evt = scriptEvent(msg=obuf, state=SCRIPT_RUNNING)
wx.PostEvent(self.win, evt)
obuf = ''
obuf = ""
elif ord(o) < 32:
pass
else:
@ -153,8 +159,13 @@ class ScriptThread:
class Build(wx.Dialog):
def __init__(self, parent, settings, f_cpu, cpu):
wx.Dialog.__init__(self, parent, wx.ID_ANY, "Build teacup",
style = wx.RESIZE_BORDER + wx.DEFAULT_DIALOG_STYLE)
wx.Dialog.__init__(
self,
parent,
wx.ID_ANY,
"Build teacup",
style=wx.RESIZE_BORDER + wx.DEFAULT_DIALOG_STYLE,
)
self.settings = settings
self.SetFont(self.settings.font)
self.root = self.settings.folder
@ -169,11 +180,11 @@ class Build(wx.Dialog):
sz = wx.BoxSizer(wx.VERTICAL)
sz.Add((10, 10))
tc = wx.TextCtrl(self, wx.ID_ANY, size = (900, 300),
style = wx.TE_READONLY + wx.TE_MULTILINE)
tc = wx.TextCtrl(
self, wx.ID_ANY, size=(900, 300), style=wx.TE_READONLY + wx.TE_MULTILINE
)
sz.Add(tc, 1, wx.EXPAND)
f = wx.Font(8, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL,
wx.FONTWEIGHT_BOLD)
f = wx.Font(8, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)
tc.SetFont(f)
self.log = tc
@ -217,7 +228,7 @@ class Build(wx.Dialog):
self.script = []
self.reportLines = []
cmdpath = ScriptTools(self.settings).figureCommandPath("avr-objdump")
elfpath = "\"" + join(self.root, "build", "teacup.elf") + "\""
elfpath = '"' + join(self.root, "build", "teacup.elf") + '"'
cmd = cmdpath + " -h " + elfpath
self.script.append(cmd)
self.Bind(EVT_SCRIPT_UPDATE, self.reportUpdate)
@ -229,15 +240,18 @@ class Build(wx.Dialog):
self.script = []
cmdpath = ScriptTools(self.settings).figureCommandPath("avr-gcc")
cfiles = [f for f in os.listdir(self.root)
if isfile(join(self.root,f)) and f.endswith(".c")]
cfiles = [
f
for f in os.listdir(self.root)
if isfile(join(self.root, f)) and f.endswith(".c")
]
for f in cfiles:
basename = f[:-2]
ofile = basename + ".o"
alfile = basename + ".al"
opath = "\"" + join(self.root, "build", ofile) + "\""
alpath = "\"" + join(self.root, "build", alfile) + "\""
cpath = "\"" + join(self.root, f) + "\""
opath = '"' + join(self.root, "build", ofile) + '"'
alpath = '"' + join(self.root, "build", alfile) + '"'
cpath = '"' + join(self.root, f) + '"'
opts = self.settings.cflags
opts = opts.replace("%ALNAME%", alpath)
@ -259,23 +273,34 @@ class Build(wx.Dialog):
if platform.startswith("win"):
cmdpath += " -Wl,-V"
ofiles = ["\"" + join(self.root, "build", f) + "\""
ofiles = [
'"' + join(self.root, "build", f) + '"'
for f in os.listdir(join(self.root, "build"))
if isfile(join(self.root, "build", f)) and f.endswith(".o")]
if isfile(join(self.root, "build", f)) and f.endswith(".o")
]
opath = " ".join(ofiles)
elfpath = "\"" + join(self.root, "build", "teacup.elf") + "\""
hexpath = "\"" + join(self.root, "teacup.hex") + "\""
elfpath = '"' + join(self.root, "build", "teacup.elf") + '"'
hexpath = '"' + join(self.root, "teacup.hex") + '"'
opts = self.settings.cflags
opts = opts.replace("%ALNAME%", "teacup.elf")
opts = opts.replace("%F_CPU%", self.f_cpu)
opts = opts.replace("%CPU%", self.cpu)
cmd = cmdpath + " " + self.settings.ldflags + " " + opts + " -o " + \
elfpath + " " + opath + " -lm"
cmd = (
cmdpath
+ " "
+ self.settings.ldflags
+ " "
+ opts
+ " -o "
+ elfpath
+ " "
+ opath
+ " -lm"
)
self.script.append(cmd)
cmdpath = ScriptTools(self.settings).figureCommandPath("avr-objcopy")
cmd = cmdpath + " " + self.settings.objcopyflags + " " + elfpath + \
" " + hexpath
cmd = cmdpath + " " + self.settings.objcopyflags + " " + elfpath + " " + hexpath
self.script.append(cmd)
def compileUpdate(self, evt):
@ -326,20 +351,26 @@ class Build(wx.Dialog):
def formatReportLine(self, m, name, v168, v328, v644, v1280):
t = m.groups()
v = int(t[0], 16)
self.log.AppendText(("%12s: %6d bytes %6.2f%% %6.2f%%"
" %6.2f%% %6.2f%%\n") %
(name, v, v / float(v168 * 1024) * 100.0,
self.log.AppendText(
("%12s: %6d bytes %6.2f%% %6.2f%%" " %6.2f%% %6.2f%%\n")
% (
name,
v,
v / float(v168 * 1024) * 100.0,
v / float(v328 * 1024) * 100.0,
v / float(v644 * 1024) * 100.0,
v / float(v1280 * 1024) * 100.0))
v / float(v1280 * 1024) * 100.0,
)
)
def formatReport(self):
reText = re.compile("\.text\s+([0-9a-f]+)")
reBss = re.compile("\.bss\s+([0-9a-f]+)")
reEEProm = re.compile("\.eeprom\s+([0-9a-f]+)")
self.log.AppendText("\n ATmega... '168 '328(P)"
" '644(P) '1280\n")
self.log.AppendText(
"\n ATmega... '168 '328(P)" " '644(P) '1280\n"
)
for l in self.reportLines:
m = reText.search(l)
if m:
@ -355,9 +386,12 @@ class Build(wx.Dialog):
def onExit(self, evt):
if self.active:
dlg = wx.MessageDialog(self, "Are you sure you want to cancel building?",
dlg = wx.MessageDialog(
self,
"Are you sure you want to cancel building?",
"Build active",
wx.YES_NO | wx.NO_DEFAULT | wx.ICON_INFORMATION)
wx.YES_NO | wx.NO_DEFAULT | wx.ICON_INFORMATION,
)
rc = dlg.ShowModal()
dlg.Destroy()
@ -372,8 +406,13 @@ class Build(wx.Dialog):
class Upload(wx.Dialog):
def __init__(self, parent, settings, f_cpu, cpu):
wx.Dialog.__init__(self, parent, wx.ID_ANY, "Upload teacup",
style = wx.RESIZE_BORDER + wx.DEFAULT_DIALOG_STYLE)
wx.Dialog.__init__(
self,
parent,
wx.ID_ANY,
"Upload teacup",
style=wx.RESIZE_BORDER + wx.DEFAULT_DIALOG_STYLE,
)
self.settings = settings
self.SetFont(self.settings.font)
self.root = self.settings.folder
@ -389,11 +428,11 @@ class Upload(wx.Dialog):
sz = wx.BoxSizer(wx.VERTICAL)
sz.Add((10, 10))
tc = wx.TextCtrl(self, wx.ID_ANY, size = (900, 300),
style = wx.TE_READONLY + wx.TE_MULTILINE)
tc = wx.TextCtrl(
self, wx.ID_ANY, size=(900, 300), style=wx.TE_READONLY + wx.TE_MULTILINE
)
sz.Add(tc, 1, wx.EXPAND)
f = wx.Font(8, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL,
wx.FONTWEIGHT_BOLD)
f = wx.Font(8, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)
tc.SetFont(f)
self.log = tc
@ -417,11 +456,16 @@ class Upload(wx.Dialog):
def generateUploadScript(self):
self.script = []
cmdpath = ScriptTools(self.settings).figureCommandPath("avrdude")
hexpath = "\"" + join(self.root, "teacup.hex") + "\""
hexpath = '"' + join(self.root, "teacup.hex") + '"'
cmd = cmdpath + " -c %s %s -b %s -p %s -P %s -U flash:w:%s:i" % \
(self.settings.programmer, self.settings.programflags, self.baud,
self.cpu, self.settings.port, hexpath)
cmd = cmdpath + " -c %s %s -b %s -p %s -P %s -U flash:w:%s:i" % (
self.settings.programmer,
self.settings.programflags,
self.baud,
self.cpu,
self.settings.port,
hexpath,
)
self.script.append(cmd)
def uploadUpdate(self, evt):
@ -445,9 +489,12 @@ class Upload(wx.Dialog):
def onExit(self, evt):
if self.active:
dlg = wx.MessageDialog(self, "Are you sure you want to cancel upload?",
dlg = wx.MessageDialog(
self,
"Are you sure you want to cancel upload?",
"Upload active",
wx.YES_NO | wx.NO_DEFAULT | wx.ICON_INFORMATION)
wx.YES_NO | wx.NO_DEFAULT | wx.ICON_INFORMATION,
)
rc = dlg.ShowModal()
dlg.Destroy()

View File

@ -1,14 +1,16 @@
import wx
from configtool.data import (BSIZESMALL, reFloat, reInteger, offsetChLabel,
offsetTcLabel)
from configtool.data import BSIZESMALL, reFloat, reInteger, offsetChLabel, offsetTcLabel
class CalcBelt(wx.Dialog):
def __init__(self, parent, font, cbUse):
wx.Dialog.__init__(self, parent, wx.ID_ANY,
wx.Dialog.__init__(
self,
parent,
wx.ID_ANY,
"Steps calculator for belt driven axes",
size = (360, 300))
size=(360, 300),
)
self.SetFont(font)
self.Bind(wx.EVT_CLOSE, self.onExit)
@ -22,14 +24,18 @@ class CalcBelt(wx.Dialog):
sz.Add((10, 10))
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, "Step Angle:", size = (labelWidth, -1),
style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self, wx.ID_ANY, "Step Angle:", size=(labelWidth, -1), style=wx.ALIGN_RIGHT
)
st.SetFont(font)
lsz.Add(st, 1, wx.TOP, offsetChLabel)
lsz.Add((5, 5))
stepAngles = ["1.8 (200 per revolution)", "0.9 (400 per revolution)",
"7.5 (48 per revolution)"]
stepAngles = [
"1.8 (200 per revolution)",
"0.9 (400 per revolution)",
"7.5 (48 per revolution)",
]
self.stepAngleValues = [200, 400, 48]
tc = wx.Choice(self, wx.ID_ANY, choices=stepAngles)
tc.SetFont(font)
@ -43,32 +49,52 @@ class CalcBelt(wx.Dialog):
sz.Add((10, 10))
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, "Microstepping:",
size = (labelWidth, -1), style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self,
wx.ID_ANY,
"Microstepping:",
size=(labelWidth, -1),
style=wx.ALIGN_RIGHT,
)
st.SetFont(font)
lsz.Add(st, 1, wx.TOP, offsetChLabel)
lsz.Add((5, 5))
microStepping = ["1 - full step", "1/2 - half step", "1/4 - quarter step",
"1/8", "1/16", "1/32", "1/64", "1/128"]
microStepping = [
"1 - full step",
"1/2 - half step",
"1/4 - quarter step",
"1/8",
"1/16",
"1/32",
"1/64",
"1/128",
]
self.microSteppingValues = [1, 2, 4, 8, 16, 32, 64, 128]
tc = wx.Choice(self, wx.ID_ANY, choices=microStepping)
tc.SetFont(font)
tc.Bind(wx.EVT_CHOICE, self.onChoice)
tc.SetSelection(4)
lsz.Add(tc)
tc.SetToolTip("Microstepping. Most boards allow to change this by "
tc.SetToolTip(
"Microstepping. Most boards allow to change this by "
"setting jumpers. The value here must match the "
"setting on the board in conjunction with the type "
"of stepper driver chip.")
"of stepper driver chip."
)
self.tcMicroStepping = tc
sz.Add(lsz)
sz.Add((10, 10))
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, "Belt Pitch (in mm):",
size = (labelWidth, -1), style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self,
wx.ID_ANY,
"Belt Pitch (in mm):",
size=(labelWidth, -1),
style=wx.ALIGN_RIGHT,
)
st.SetFont(font)
lsz.Add(st, 1, wx.TOP, offsetTcLabel)
lsz.Add((5, 5))
@ -82,9 +108,15 @@ class CalcBelt(wx.Dialog):
lsz.Add((5, 5))
beltPresets = ["-", "2mm Pitch (GT2)", "MXL Pitch (2.03mm)",
"T2.5 (2.5mm)", "3mm Pitch (GT2, HTD)",
"5mm Pitch (T5, GTD, HTD)", "0.2\" XL belt (5.08mm)"]
beltPresets = [
"-",
"2mm Pitch (GT2)",
"MXL Pitch (2.03mm)",
"T2.5 (2.5mm)",
"3mm Pitch (GT2, HTD)",
"5mm Pitch (T5, GTD, HTD)",
'0.2" XL belt (5.08mm)',
]
self.beltPresetValues = [-1, 2.0, 2.03, 2.5, 3.0, 5.0, 5.08]
tc = wx.Choice(self, wx.ID_ANY, choices=beltPresets)
tc.SetFont(font)
@ -98,8 +130,13 @@ class CalcBelt(wx.Dialog):
sz.Add((10, 10))
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, "Pulley Teeth Count:",
size = (labelWidth, -1), style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self,
wx.ID_ANY,
"Pulley Teeth Count:",
size=(labelWidth, -1),
style=wx.ALIGN_RIGHT,
)
st.SetFont(font)
lsz.Add(st, 1, wx.TOP, offsetTcLabel)
lsz.Add((5, 5))
@ -115,28 +152,28 @@ class CalcBelt(wx.Dialog):
sz.Add((30, 30))
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, "Result:", size = (labelWidth, -1),
style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self, wx.ID_ANY, "Result:", size=(labelWidth, -1), style=wx.ALIGN_RIGHT
)
st.SetFont(font)
lsz.Add(st)
lsz.Add((5, 5))
tc = wx.StaticText(self, wx.ID_ANY, "", size = (260, -1),
style = wx.ALIGN_LEFT)
tc = wx.StaticText(self, wx.ID_ANY, "", size=(260, -1), style=wx.ALIGN_LEFT)
tc.SetFont(font)
lsz.Add(tc)
self.tcResult = tc
sz.Add(lsz)
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, "Resolution:", size = (labelWidth, -1),
style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self, wx.ID_ANY, "Resolution:", size=(labelWidth, -1), style=wx.ALIGN_RIGHT
)
st.SetFont(font)
lsz.Add(st)
lsz.Add((5, 5))
tc = wx.StaticText(self, wx.ID_ANY, "", size = (260, -1),
style = wx.ALIGN_LEFT)
tc = wx.StaticText(self, wx.ID_ANY, "", size=(260, -1), style=wx.ALIGN_LEFT)
tc.SetFont(font)
lsz.Add(tc)
self.tcResolution = tc
@ -187,7 +224,6 @@ class CalcBelt(wx.Dialog):
self.calculate()
def calculate(self):
self.tcResult.SetLabel("")
self.tcResolution.SetLabel("")
@ -214,8 +250,7 @@ class CalcBelt(wx.Dialog):
resultmm = steps / length
self.result = int(resultmm * 1000.0)
self.tcResult.SetLabel("%d steps/m (%.3f steps/mm)" %
(self.result, resultmm))
self.tcResult.SetLabel("%d steps/m (%.3f steps/mm)" % (self.result, resultmm))
self.tcResolution.SetLabel("%.3f micrometers" % (length / steps * 1000.0))
self.enableUseButtons(True)
@ -226,16 +261,16 @@ class CalcBelt(wx.Dialog):
self.bUseForE.Enable(flag)
def onUseForX(self, evt):
self.use('STEPS_PER_M_X', self.result)
self.use("STEPS_PER_M_X", self.result)
def onUseForY(self, evt):
self.use('STEPS_PER_M_Y', self.result)
self.use("STEPS_PER_M_Y", self.result)
def onUseForZ(self, evt):
self.use('STEPS_PER_M_Z', self.result)
self.use("STEPS_PER_M_Z", self.result)
def onUseForE(self, evt):
self.use('STEPS_PER_M_E', self.result)
self.use("STEPS_PER_M_E", self.result)
def onPresetChoice(self, evt):
s = self.tcPresets.GetSelection()

View File

@ -1,13 +1,16 @@
import wx
from configtool.data import BSIZESMALL, reFloat, offsetChLabel, offsetTcLabel
class CalcScrew(wx.Dialog):
def __init__(self, parent, font, cbUse):
wx.Dialog.__init__(self, parent, wx.ID_ANY,
wx.Dialog.__init__(
self,
parent,
wx.ID_ANY,
"Steps calculator for screw driven axes",
size = (400, 204))
size=(400, 204),
)
self.SetFont(font)
self.Bind(wx.EVT_CLOSE, self.onExit)
@ -21,14 +24,18 @@ class CalcScrew(wx.Dialog):
sz.Add((10, 10))
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, "Step Angle:", size = (labelWidth, -1),
style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self, wx.ID_ANY, "Step Angle:", size=(labelWidth, -1), style=wx.ALIGN_RIGHT
)
st.SetFont(font)
lsz.Add(st, 1, wx.TOP, offsetChLabel)
lsz.Add((5, 5))
stepAngles = ["1.8 (200 per revolution)", "0.9 (400 per revolution)",
"7.5 (48 per revolution)"]
stepAngles = [
"1.8 (200 per revolution)",
"0.9 (400 per revolution)",
"7.5 (48 per revolution)",
]
self.stepAngleValues = [200, 400, 48]
tc = wx.Choice(self, wx.ID_ANY, choices=stepAngles)
tc.SetFont(font)
@ -42,32 +49,52 @@ class CalcScrew(wx.Dialog):
sz.Add((10, 10))
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, "Microstepping:",
size = (labelWidth, -1), style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self,
wx.ID_ANY,
"Microstepping:",
size=(labelWidth, -1),
style=wx.ALIGN_RIGHT,
)
st.SetFont(font)
lsz.Add(st, 1, wx.TOP, offsetChLabel)
lsz.Add((5, 5))
microStepping = ["1 - full step", "1/2 - half step", "1/4 - quarter step",
"1/8", "1/16", "1/32", "1/64", "1/128"]
microStepping = [
"1 - full step",
"1/2 - half step",
"1/4 - quarter step",
"1/8",
"1/16",
"1/32",
"1/64",
"1/128",
]
self.microSteppingValues = [1, 2, 4, 8, 16, 32, 64, 128]
tc = wx.Choice(self, wx.ID_ANY, choices=microStepping)
tc.SetFont(font)
tc.Bind(wx.EVT_CHOICE, self.onChoice)
tc.SetSelection(4)
lsz.Add(tc)
tc.SetToolTip("Microstepping. Most boards allow to change this by "
tc.SetToolTip(
"Microstepping. Most boards allow to change this by "
"setting jumpers. The value here must match the "
"setting on the board in conjunction with the type "
"of stepper driver chip.")
"of stepper driver chip."
)
self.tcMicroStepping = tc
sz.Add(lsz)
sz.Add((10, 10))
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, "Screw Pitch (mm/rev):",
size = (labelWidth, -1), style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self,
wx.ID_ANY,
"Screw Pitch (mm/rev):",
size=(labelWidth, -1),
style=wx.ALIGN_RIGHT,
)
st.SetFont(font)
lsz.Add(st, 1, wx.TOP, offsetTcLabel)
lsz.Add((5, 5))
@ -81,14 +108,30 @@ class CalcScrew(wx.Dialog):
lsz.Add((5, 5))
screwPresets = ["-", "M8 - metric (1.25 mm/rev)", "M6 - metric (1 mm/rev)",
"M5 - metric (0.8 mm/rev)", "12 (12 mm/rev)",
"16 (16 mm/rev)", "25 (25 mm/rev)",
"5/15\"-18 imperial coarse (1.41111 mm/rev)",
"3/16\"-20 imperial (1.270 mm/rev)",
"1/4\"-16 ACME (1.5875 mm/rev)"]
self.screwPresetValues = [-1, 1.25, 1.00, 0.8, 12.0, 16.0, 25.0, 1.41111,
1.270, 1.5875]
screwPresets = [
"-",
"M8 - metric (1.25 mm/rev)",
"M6 - metric (1 mm/rev)",
"M5 - metric (0.8 mm/rev)",
"12 (12 mm/rev)",
"16 (16 mm/rev)",
"25 (25 mm/rev)",
'5/15"-18 imperial coarse (1.41111 mm/rev)',
'3/16"-20 imperial (1.270 mm/rev)',
'1/4"-16 ACME (1.5875 mm/rev)',
]
self.screwPresetValues = [
-1,
1.25,
1.00,
0.8,
12.0,
16.0,
25.0,
1.41111,
1.270,
1.5875,
]
tc = wx.Choice(self, wx.ID_ANY, choices=screwPresets)
tc.SetFont(font)
tc.SetSelection(0)
@ -101,8 +144,9 @@ class CalcScrew(wx.Dialog):
sz.Add((10, 10))
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, "Gear Ratio:", size = (labelWidth, -1),
style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self, wx.ID_ANY, "Gear Ratio:", size=(labelWidth, -1), style=wx.ALIGN_RIGHT
)
st.SetFont(font)
lsz.Add(st, 1, wx.TOP, offsetTcLabel)
lsz.Add((5, 5))
@ -131,28 +175,28 @@ class CalcScrew(wx.Dialog):
sz.Add((30, 30))
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, "Result:", size = (labelWidth, -1),
style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self, wx.ID_ANY, "Result:", size=(labelWidth, -1), style=wx.ALIGN_RIGHT
)
st.SetFont(font)
lsz.Add(st)
lsz.Add((5, 5))
tc = wx.StaticText(self, wx.ID_ANY, "", size = (300, -1),
style = wx.ALIGN_LEFT)
tc = wx.StaticText(self, wx.ID_ANY, "", size=(300, -1), style=wx.ALIGN_LEFT)
tc.SetFont(font)
lsz.Add(tc)
self.tcResult = tc
sz.Add(lsz)
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, "Resolution:", size = (labelWidth, -1),
style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self, wx.ID_ANY, "Resolution:", size=(labelWidth, -1), style=wx.ALIGN_RIGHT
)
st.SetFont(font)
lsz.Add(st)
lsz.Add((5, 5))
tc = wx.StaticText(self, wx.ID_ANY, "", size = (300, -1),
style = wx.ALIGN_LEFT)
tc = wx.StaticText(self, wx.ID_ANY, "", size=(300, -1), style=wx.ALIGN_LEFT)
tc.SetFont(font)
lsz.Add(tc)
self.tcResolution = tc
@ -234,8 +278,7 @@ class CalcScrew(wx.Dialog):
resultmm = steps / sp / ratio
self.result = int(resultmm * 1000.0)
self.tcResult.SetLabel("%d steps/m (%.3f steps/mm)" %
(self.result, resultmm))
self.tcResult.SetLabel("%d steps/m (%.3f steps/mm)" % (self.result, resultmm))
self.tcResolution.SetLabel("%.3f micrometers" % (1.0 / resultmm * 1000.0))
self.enableUseButtons(True)
@ -246,16 +289,16 @@ class CalcScrew(wx.Dialog):
self.bUseForE.Enable(flag)
def onUseForX(self, evt):
self.use('STEPS_PER_M_X', self.result)
self.use("STEPS_PER_M_X", self.result)
def onUseForY(self, evt):
self.use('STEPS_PER_M_Y', self.result)
self.use("STEPS_PER_M_Y", self.result)
def onUseForZ(self, evt):
self.use('STEPS_PER_M_Z', self.result)
self.use("STEPS_PER_M_Z", self.result)
def onUseForE(self, evt):
self.use('STEPS_PER_M_E', self.result)
self.use("STEPS_PER_M_E", self.result)
def onPresetChoice(self, evt):
s = self.tcPresets.GetSelection()

View File

@ -1,4 +1,3 @@
import wx
from configtool.page import Page
@ -9,25 +8,29 @@ class CommunicationsPage(wx.Panel, Page):
Page.__init__(self, font)
self.parent = parent
self.id = idPg
self.defaultBaud = '115200'
self.defaultBaud = "115200"
self.bauds = ['19200', '38400', '57600', '115200', '230400', '250000']
self.bauds = ["19200", "38400", "57600", "115200", "230400", "250000"]
self.labels = {'XONXOFF': "XON/XOFF Flow Control", 'BAUD': "Baud Rate:",
'USB_SERIAL': "USB Serial"}
self.labels = {
"XONXOFF": "XON/XOFF Flow Control",
"BAUD": "Baud Rate:",
"USB_SERIAL": "USB Serial",
}
sz = wx.GridBagSizer()
sz.Add((20, 40), pos=(0, 0))
k = 'USB_SERIAL'
k = "USB_SERIAL"
cb = self.addCheckBox(k, self.onUSBCheckBox)
sz.Add(cb, pos=(1, 1))
ch = self.addChoice('BAUD', self.bauds, self.bauds.index(self.defaultBaud),
80, self.onChoice)
ch = self.addChoice(
"BAUD", self.bauds, self.bauds.index(self.defaultBaud), 80, self.onChoice
)
sz.Add(ch, pos=(1, 3))
cb = self.addCheckBox('XONXOFF', self.onCheckBox)
cb = self.addCheckBox("XONXOFF", self.onCheckBox)
sz.Add(cb, pos=(3, 3))
sz.Add((100, 10), pos=(2, 2))
@ -37,26 +40,26 @@ class CommunicationsPage(wx.Panel, Page):
def onUSBCheckBox(self, evt):
self.assertModified(True)
f = not self.checkBoxes['USB_SERIAL'].IsChecked()
self.checkBoxes['XONXOFF'].Enable(f)
self.choices['BAUD'].Enable(f)
f = not self.checkBoxes["USB_SERIAL"].IsChecked()
self.checkBoxes["XONXOFF"].Enable(f)
self.choices["BAUD"].Enable(f)
evt.Skip()
def insertValues(self, cfgValues):
Page.insertValues(self, cfgValues)
k = 'BAUD'
k = "BAUD"
self.setChoice(k, cfgValues, self.defaultBaud)
if self.checkBoxes['USB_SERIAL'].IsChecked():
self.checkBoxes['XONXOFF'].Enable(False)
self.choices['BAUD'].Enable(False)
if self.checkBoxes["USB_SERIAL"].IsChecked():
self.checkBoxes["XONXOFF"].Enable(False)
self.choices["BAUD"].Enable(False)
def getValues(self):
result = Page.getValues(self)
if result['USB_SERIAL']:
result['BAUD'] = result['BAUD'][0], False
result['XONXOFF'] = False
if result["USB_SERIAL"]:
result["BAUD"] = result["BAUD"][0], False
result["XONXOFF"] = False
return result

View File

@ -1,4 +1,3 @@
import wx
from configtool.page import Page
@ -10,35 +9,34 @@ class CpuPage(wx.Panel, Page):
self.parent = parent
self.id = idPg
self.labels = {'F_CPU': "CPU Clock Rate:", 'CPU': "Processor Type:"}
self.labels = {"F_CPU": "CPU Clock Rate:", "CPU": "Processor Type:"}
self.clocks = []
self.processors = []
sz = wx.GridBagSizer()
sz.Add((20, 40), pos=(0, 0))
k = 'F_CPU'
k = "F_CPU"
ch = self.addChoice(k, self.clocks, 0, 100, self.onChoice, size=(140, -1))
sz.Add(ch, pos=(1, 1))
sz.Add((100, 10), pos=(1, 2))
k = 'CPU'
ch = self.addChoice(k, self.processors, 0, 100, self.onChoice,
size = (140, -1))
k = "CPU"
ch = self.addChoice(k, self.processors, 0, 100, self.onChoice, size=(140, -1))
sz.Add(ch, pos=(1, 3))
self.SetSizer(sz)
self.enableAll(False)
def setCandidateProcessors(self, plist):
k = 'CPU'
k = "CPU"
self.choices[k].Clear()
for p in plist:
self.choices[k].Append(p)
self.processors = plist
def setCandidateClocks(self, clist):
k = 'F_CPU'
k = "F_CPU"
self.choices[k].Clear()
for c in clist:
self.choices[k].Append(c)
@ -48,6 +46,6 @@ class CpuPage(wx.Panel, Page):
Page.insertValues(self, cfgValues)
if len(self.clocks) > 0:
self.setChoice('F_CPU', cfgValues, self.clocks[0])
self.setChoice("F_CPU", cfgValues, self.clocks[0])
if len(self.processors) > 0:
self.setChoice('CPU', cfgValues, self.processors[0])
self.setChoice("CPU", cfgValues, self.processors[0])

View File

@ -1,24 +1,38 @@
import re
from sys import platform
supportedCPUs = ['ATmega168', 'ATmega328P', 'ATmega644', 'ATmega644P',
'ATmega644PA', 'ATmega1280', 'ATmega1284', 'ATmega1284P',
'ATmega2560', 'AT90USB1286']
supportedCPUs = [
"ATmega168",
"ATmega328P",
"ATmega644",
"ATmega644P",
"ATmega644PA",
"ATmega1280",
"ATmega1284",
"ATmega1284P",
"ATmega2560",
"AT90USB1286",
]
# Note: this is a kludge and works for ATmegas, only. Smaller ATmegas have a
# lot fewer pins, so this list provides a lot of clutter for them. ARMs
# have entirely different names. The right way would be to fetch pin
# names from the compiler environment and/or header files.
pinNames = ["AIO%d" % x for x in range(16)] + \
["DIO%d" % x for x in range(64)] + \
["P%c%d" % (c, x) for c in range(ord('A'), ord('L') + 1) \
for x in range(8)]
pinNames = (
["AIO%d" % x for x in range(16)]
+ ["DIO%d" % x for x in range(64)]
+ ["P%c%d" % (c, x) for c in range(ord("A"), ord("L") + 1) for x in range(8)]
)
sensorTypes = {'MAX6675': "TT_MAX6675", 'Thermistor': "TT_THERMISTOR",
'AD595': "TT_AD595", 'PT100': "TT_PT100",
'Intercom': "TT_INTERCOM", 'MCP3008': "TT_MCP3008"}
sensorTypes = {
"MAX6675": "TT_MAX6675",
"Thermistor": "TT_THERMISTOR",
"AD595": "TT_AD595",
"PT100": "TT_PT100",
"Intercom": "TT_INTERCOM",
"MCP3008": "TT_MCP3008",
}
BSIZE = (100, 60)
BSIZESMALL = (90, 30)
@ -35,13 +49,13 @@ TYPE_GENERAL = 0
TYPE_FLOAT = 1
reDefQSm = re.compile("\s*#define\s+(\S+)\s+(.*)")
reDefQSm2 = re.compile("\s*(\"[^\"]*\")")
reDefQSm2 = re.compile('\s*("[^"]*")')
reInclude = re.compile("^\s*#include\s+\"([^\"]*)")
reInclude = re.compile('^\s*#include\s+"([^"]*)')
reFloatAttr = re.compile("/\*\s*float\s*\*/")
reDefine = re.compile("\s*#define\s+(\w+)\s+(\S+)")
reDefineBL = re.compile("^\s*#define\s+(\w+)\s+(\S+)")
reDefQS = re.compile("\s*#define\s+(\w+)\s+(\"[^\"]*\")")
reDefQS = re.compile('\s*#define\s+(\w+)\s+("[^"]*")')
reDefTS = re.compile("\s*(DEFINE_TEMP_SENSOR\\([^)]*\\))")
reDefHT = re.compile("\s*(DEFINE_HEATER\\([^)]*\\))")
reDefTT = re.compile("^\s*//\s*TEMP_TABLE\s+(\S+)\s+(\\(.*\\))")
@ -64,9 +78,15 @@ reSensor = re.compile(".*\\(\s*(\w+)\s*,\s*(\w+)\s*,\s*(\w+)\s*,\s*(\w+)\s*\\)")
# reHeater3 and reHeater4 deprecated, for compatibility with old config files only.
reHeater3 = re.compile(".*\\(\s*(\w+)\s*,\s*(\w+)\s*,\s*(\w+)\s*\\)")
reHeater4 = re.compile(".*\\(\s*(\w+)\s*,\s*(\w+)\s*,\s*(\w+)\s*,\s*(\w+)\s*\\)")
reHeater5 = re.compile(".*\\(\s*(\w+)\s*,\s*(\w+)\s*,\s*(\w+)\s*,\s*(\w+)\s*,\s*(\w+)\s*\\)")
reTempTable4 = re.compile(".*\\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d*.?\d*)\s*\\)")
reTempTable7 = re.compile(".*\\(\s*(\d+)\s*,\s*(\d*.?\d*)\s*,\s*(\d+)\s*,\s*(\d*.?\d*)\s*,\s*(\d+)\s*,\s*(\d*.?\d*)\s*,\s*(\d+)\s*\\)")
reHeater5 = re.compile(
".*\\(\s*(\w+)\s*,\s*(\w+)\s*,\s*(\w+)\s*,\s*(\w+)\s*,\s*(\w+)\s*\\)"
)
reTempTable4 = re.compile(
".*\\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d*.?\d*)\s*\\)"
)
reTempTable7 = re.compile(
".*\\(\s*(\d+)\s*,\s*(\d*.?\d*)\s*,\s*(\d+)\s*,\s*(\d*.?\d*)\s*,\s*(\d+)\s*,\s*(\d*.?\d*)\s*,\s*(\d+)\s*\\)"
)
reInteger = re.compile("^\d+U?L?$")
reFloat = re.compile("^\d+(\.\d*)?$")

View File

@ -7,13 +7,13 @@ import os.path
class Decoration(object):
def __new__(type, *args):
# Make it a Singleton.
if not '_the_instance' in type.__dict__:
if not "_the_instance" in type.__dict__:
type._the_instance = object.__new__(type)
return type._the_instance
def __init__(self):
if not '_ready' in dir(self):
if not "_ready" in dir(self):
self._ready = True
# It's a Singleton. Initialisations go in here.
self.backPic = None
@ -52,15 +52,17 @@ class Decoration(object):
# subwindow as usual.
# Align bottom right.
offX, offY = topLevel.GetClientSize() - self.backPic.GetSize() + \
self.backPicOffset
offX, offY = (
topLevel.GetClientSize() - self.backPic.GetSize() + self.backPicOffset
)
if client != topLevel:
# Note: trying to figure this additional offset via various
# .GetScreenPosition() or .GetPosition() or whatever is hopeless.
# Of many many tries only this worked on Linux.
offX, offY = \
client.ScreenToClient(topLevel.ClientToScreen((offX, offY)))
offX, offY = client.ScreenToClient(
topLevel.ClientToScreen((offX, offY))
)
if self.backPic:
dc.DrawBitmap(self.backPic, offX, offY)

View File

@ -1,4 +1,3 @@
# coding=utf-8
import wx
@ -12,41 +11,51 @@ class DisplayPage(wx.Panel, Page):
self.parent = parent
self.id = idPg
self.labels = {'DISPLAY_BUS': "Display Bus:",
'DISPLAY_TYPE': "Display Type:",
'DISPLAY_BUS_4BIT': "Direct with 4 pins",
'DISPLAY_BUS_8BIT': "Direct with 8 pins",
'DISPLAY_BUS_I2C': "I²C ( = TWI)",
'DISPLAY_BUS_SPI': "SPI",
'DISPLAY_TYPE_SSD1306': "SSD1306 O-LED, 128x32 pixels",
'DISPLAY_TYPE_HD44780': "HD44780 or 1602A, 16x2 characters",
'DISPLAY_RS_PIN': "RS pin",
'DISPLAY_RW_PIN': "R/W pin",
'DISPLAY_E_PIN': "E pin",
'DISPLAY_D4_PIN': "D4 pin",
'DISPLAY_D5_PIN': "D5 pin",
'DISPLAY_D6_PIN': "D6 pin",
'DISPLAY_D7_PIN': "D7 pin"}
self.labels = {
"DISPLAY_BUS": "Display Bus:",
"DISPLAY_TYPE": "Display Type:",
"DISPLAY_BUS_4BIT": "Direct with 4 pins",
"DISPLAY_BUS_8BIT": "Direct with 8 pins",
"DISPLAY_BUS_I2C": "I²C ( = TWI)",
"DISPLAY_BUS_SPI": "SPI",
"DISPLAY_TYPE_SSD1306": "SSD1306 O-LED, 128x32 pixels",
"DISPLAY_TYPE_HD44780": "HD44780 or 1602A, 16x2 characters",
"DISPLAY_RS_PIN": "RS pin",
"DISPLAY_RW_PIN": "R/W pin",
"DISPLAY_E_PIN": "E pin",
"DISPLAY_D4_PIN": "D4 pin",
"DISPLAY_D5_PIN": "D5 pin",
"DISPLAY_D6_PIN": "D6 pin",
"DISPLAY_D7_PIN": "D7 pin",
}
sz = wx.GridBagSizer()
sz.Add((20, 40), pos=(0, 0))
ch = self.addBoolChoice('DISPLAY_BUS', True, 100, self.onBusChoice,
size = (160, -1))
ch = self.addBoolChoice(
"DISPLAY_BUS", True, 100, self.onBusChoice, size=(160, -1)
)
sz.Add(ch, pos=(1, 1))
sz.Add((100, 10), pos=(1, 2))
ch = self.addBoolChoice('DISPLAY_TYPE', False, 100, self.onChoice,
size = (240, -1))
ch = self.addBoolChoice(
"DISPLAY_TYPE", False, 100, self.onChoice, size=(240, -1)
)
sz.Add(ch, pos=(1, 3))
b = wx.StaticBox(self, wx.ID_ANY, "Direct 4-bit Bus Pins:")
b.SetFont(font)
self.pinbox = wx.StaticBoxSizer(b, wx.VERTICAL)
self.pinbox.Add((5, 5))
for k in ('DISPLAY_RS_PIN', 'DISPLAY_RW_PIN', 'DISPLAY_E_PIN',
'DISPLAY_D4_PIN', 'DISPLAY_D5_PIN', 'DISPLAY_D6_PIN',
'DISPLAY_D7_PIN'):
for k in (
"DISPLAY_RS_PIN",
"DISPLAY_RW_PIN",
"DISPLAY_E_PIN",
"DISPLAY_D4_PIN",
"DISPLAY_D5_PIN",
"DISPLAY_D6_PIN",
"DISPLAY_D7_PIN",
):
tc = self.addPinChoice(k, 200)
self.pinbox.Add(tc)
self.pinbox.Add((5, 5))
@ -56,11 +65,11 @@ class DisplayPage(wx.Panel, Page):
self.enableAll(False)
def onBusChoice(self, evt):
choice = self.boolChoices['DISPLAY_BUS']
choice = self.boolChoices["DISPLAY_BUS"]
if choice.GetClientData(choice.GetSelection()):
self.boolChoices['DISPLAY_TYPE'].Enable(True)
self.boolChoices["DISPLAY_TYPE"].Enable(True)
else:
self.boolChoices['DISPLAY_TYPE'].Enable(False)
self.boolChoices["DISPLAY_TYPE"].Enable(False)
self.adjustPinVisibility()
Page.onChoice(self, evt)
@ -68,10 +77,10 @@ class DisplayPage(wx.Panel, Page):
def adjustPinVisibility(self):
visible = False
choice = self.boolChoices['DISPLAY_BUS']
choice = self.boolChoices["DISPLAY_BUS"]
if choice.GetSelection() >= 0:
selection = choice.GetClientData(choice.GetSelection())
if selection == 'DISPLAY_BUS_4BIT':
if selection == "DISPLAY_BUS_4BIT":
visible = True
self.pinbox.ShowItems(visible)

View File

@ -2,6 +2,7 @@ from __future__ import print_function
import sys
import time
try:
import wx
if int(wx.__version__[0]) < 4:
@ -16,12 +17,6 @@ except:
)
time.sleep(10)
sys.exit(-1)
except:
print("ImportError: No module named wx\n\n"
"wxPython is not installed. This program requires wxPython to run.\n"
"See your package manager and/or https://wxpython.org/pages/downloads/.")
time.sleep(10)
sys.exit(-1)
import os.path
@ -64,8 +59,9 @@ class ConfigFrame(wx.Frame):
self.settings = settings
self.settings.app = self
self.settings.font = wx.Font(8, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL,
wx.FONTWEIGHT_BOLD)
self.settings.font = wx.Font(
8, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD
)
self.heaters = []
self.savePrtEna = False
@ -75,8 +71,7 @@ class ConfigFrame(wx.Frame):
sz = wx.BoxSizer(wx.HORIZONTAL)
self.nb = wx.Notebook(panel, wx.ID_ANY, size = (880, 550),
style = wx.BK_DEFAULT)
self.nb = wx.Notebook(panel, wx.ID_ANY, size=(880, 550), style=wx.BK_DEFAULT)
self.nb.SetBackgroundColour(self.deco.getBackgroundColour())
self.nb.SetFont(self.settings.font)
@ -111,7 +106,7 @@ class ConfigFrame(wx.Frame):
def onResize(self, evt):
self.panel.SetSize(self.GetClientSize())
self.Refresh()
evt.Skip();
evt.Skip()
def setPrinterTabFile(self, fn):
self.printerFileName = fn
@ -148,8 +143,11 @@ class ConfigFrame(wx.Frame):
def makeMenu(self):
file_menu = wx.Menu()
file_menu.Append(ID_LOAD_CONFIG, "Load config.h",
"Load config.h and its named printer and board files.")
file_menu.Append(
ID_LOAD_CONFIG,
"Load config.h",
"Load config.h and its named printer and board files.",
)
self.Bind(wx.EVT_MENU, self.onLoadConfig, id=ID_LOAD_CONFIG)
file_menu.Enable(ID_LOAD_CONFIG, False)
@ -159,32 +157,39 @@ class ConfigFrame(wx.Frame):
file_menu.AppendSeparator()
file_menu.Append(ID_LOAD_PRINTER, "Load printer",
"Load a printer configuration file.")
file_menu.Append(
ID_LOAD_PRINTER, "Load printer", "Load a printer configuration file."
)
self.Bind(wx.EVT_MENU, self.pgPrinter.onLoadConfig, id=ID_LOAD_PRINTER)
file_menu.Append(ID_SAVE_PRINTER, "Save printer",
"Save printer configuration.")
file_menu.Append(ID_SAVE_PRINTER, "Save printer", "Save printer configuration.")
self.Bind(wx.EVT_MENU, self.onSavePrinterConfig, id=ID_SAVE_PRINTER)
file_menu.Enable(ID_SAVE_PRINTER, False)
file_menu.Append(ID_SAVE_PRINTER_AS, "Save printer as...",
"Save printer configuration to a new file.")
file_menu.Append(
ID_SAVE_PRINTER_AS,
"Save printer as...",
"Save printer configuration to a new file.",
)
self.Bind(wx.EVT_MENU, self.onSavePrinterConfigAs, id=ID_SAVE_PRINTER_AS)
file_menu.Enable(ID_SAVE_PRINTER_AS, False)
file_menu.AppendSeparator()
file_menu.Append(ID_LOAD_BOARD, "Load board",
"Load a board configuration file.")
file_menu.Append(
ID_LOAD_BOARD, "Load board", "Load a board configuration file."
)
self.Bind(wx.EVT_MENU, self.pgBoard.onLoadConfig, id=ID_LOAD_BOARD)
file_menu.Append(ID_SAVE_BOARD, "Save board", "Save board configuration.")
self.Bind(wx.EVT_MENU, self.onSaveBoardConfig, id=ID_SAVE_BOARD)
file_menu.Enable(ID_SAVE_BOARD, False)
file_menu.Append(ID_SAVE_BOARD_AS, "Save board as...",
"Save board configuration to a new file.")
file_menu.Append(
ID_SAVE_BOARD_AS,
"Save board as...",
"Save board configuration to a new file.",
)
self.Bind(wx.EVT_MENU, self.onSaveBoardConfigAs, id=ID_SAVE_BOARD_AS)
file_menu.Enable(ID_SAVE_BOARD_AS, False)
@ -225,8 +230,9 @@ class ConfigFrame(wx.Frame):
help_menu.Append(ID_HELP, "Help", "Find help.")
self.Bind(wx.EVT_MENU, self.onHelp, id=ID_HELP)
help_menu.Append(ID_REPORT, "Report problem",
"Report a problem to Teacup maintainers.")
help_menu.Append(
ID_REPORT, "Report problem", "Report a problem to Teacup maintainers."
)
self.Bind(wx.EVT_MENU, self.onReportProblem, id=ID_REPORT)
help_menu.AppendSeparator()
@ -322,23 +328,31 @@ class ConfigFrame(wx.Frame):
pfile, bfile = self.getConfigFileNames(fn)
if not pfile:
self.message("Config file did not contain a printer file "
"include statement.", "Config error")
self.message(
"Config file did not contain a printer file " "include statement.",
"Config error",
)
return False
else:
if not self.pgPrinter.loadConfigFile(pfile):
self.message("There was a problem loading the printer config file:\n%s"
% pfile, "Config error")
self.message(
"There was a problem loading the printer config file:\n%s" % pfile,
"Config error",
)
return False
if not bfile:
self.message("Config file did not contain a board file "
"include statement.", "Config error")
self.message(
"Config file did not contain a board file " "include statement.",
"Config error",
)
return False
else:
if not self.pgBoard.loadConfigFile(bfile):
self.message("There was a problem loading the board config file:\n%s"
% bfile, "Config error")
self.message(
"There was a problem loading the board config file:\n%s" % bfile,
"Config error",
)
return False
return True
@ -363,28 +377,36 @@ class ConfigFrame(wx.Frame):
if len(t) == 1:
if "printer." in t[0]:
if pfile:
self.message("Multiple printer file include statements.\n"
"Ignoring %s." % ln, "Config error",
wx.OK + wx.ICON_WARNING)
self.message(
"Multiple printer file include statements.\n"
"Ignoring %s." % ln,
"Config error",
wx.OK + wx.ICON_WARNING,
)
else:
pfile = os.path.join(self.settings.folder, t[0])
elif "board." in t[0]:
if bfile:
self.message("Multiple board file include statements.\n"
"Ignoring %s." % ln, "Config error",
wx.OK + wx.ICON_WARNING)
self.message(
"Multiple board file include statements.\n"
"Ignoring %s." % ln,
"Config error",
wx.OK + wx.ICON_WARNING,
)
else:
bfile = os.path.join(self.settings.folder, t[0])
else:
self.message("Unable to parse include statement:\n%s" % ln,
"Config error")
self.message(
"Unable to parse include statement:\n%s" % ln,
"Config error",
)
return pfile, bfile
def onSaveConfig(self, evt):
fn = os.path.join(self.settings.folder, "config.h")
try:
fp = open(fn, 'w')
fp = open(fn, "w")
except:
self.message("Unable to open config.h for output.", "File error")
return False
@ -416,10 +438,10 @@ class ConfigFrame(wx.Frame):
fp.write("\n")
fp.write("// Configuration for controller board.\n")
fp.write("#include \"%s\"\n" % rbfn)
fp.write('#include "%s"\n' % rbfn)
fp.write("\n")
fp.write("// Configuration for printer board.\n")
fp.write("#include \"%s\"\n" % rpfn)
fp.write('#include "%s"\n' % rpfn)
fp.close()
@ -434,10 +456,12 @@ class ConfigFrame(wx.Frame):
def onBuildorUpload(self, buildFlag):
if not (self.pgPrinter.hasData() or self.pgBoard.hasData()):
dlg = wx.MessageDialog(self, "Data needs to be loaded. "
"Click Yes to load config.h.",
dlg = wx.MessageDialog(
self,
"Data needs to be loaded. " "Click Yes to load config.h.",
"Data missing",
wx.YES_NO | wx.NO_DEFAULT | wx.ICON_INFORMATION)
wx.YES_NO | wx.NO_DEFAULT | wx.ICON_INFORMATION,
)
rc = dlg.ShowModal()
dlg.Destroy()
if rc != wx.ID_YES:
@ -446,10 +470,13 @@ class ConfigFrame(wx.Frame):
self.loadConfigFile("config.h")
else:
if self.pgPrinter.isModified():
dlg = wx.MessageDialog(self, "Printer data needs to be saved. Click "
dlg = wx.MessageDialog(
self,
"Printer data needs to be saved. Click "
"Yes to save printer configuration.",
"Changes pending",
wx.YES_NO | wx.NO_DEFAULT | wx.ICON_INFORMATION)
wx.YES_NO | wx.NO_DEFAULT | wx.ICON_INFORMATION,
)
rc = dlg.ShowModal()
dlg.Destroy()
if rc != wx.ID_YES:
@ -463,10 +490,13 @@ class ConfigFrame(wx.Frame):
return
if self.pgBoard.isModified():
dlg = wx.MessageDialog(self, "Board data needs to be saved. Click "
dlg = wx.MessageDialog(
self,
"Board data needs to be saved. Click "
"Yes to save board configuration.",
"Changes pending",
wx.YES_NO | wx.NO_DEFAULT | wx.ICON_INFORMATION)
wx.YES_NO | wx.NO_DEFAULT | wx.ICON_INFORMATION,
)
rc = dlg.ShowModal()
dlg.Destroy()
if rc != wx.ID_YES:
@ -480,10 +510,13 @@ class ConfigFrame(wx.Frame):
return
if not self.verifyConfigLoaded():
dlg = wx.MessageDialog(self, "Loaded configuration does not match the "
dlg = wx.MessageDialog(
self,
"Loaded configuration does not match the "
"config.h file. Click Yes to save config.h.",
"Configuration changed",
wx.YES_NO | wx.NO_DEFAULT | wx.ICON_INFORMATION)
wx.YES_NO | wx.NO_DEFAULT | wx.ICON_INFORMATION,
)
rc = dlg.ShowModal()
dlg.Destroy()
if rc != wx.ID_YES:
@ -494,15 +527,23 @@ class ConfigFrame(wx.Frame):
f_cpu, cpu = self.pgBoard.getCPUInfo()
if not cpu:
dlg = wx.MessageDialog(self, "Unable to determine CPU type.",
"CPU type error", wx.OK | wx.ICON_ERROR)
dlg = wx.MessageDialog(
self,
"Unable to determine CPU type.",
"CPU type error",
wx.OK | wx.ICON_ERROR,
)
dlg.ShowModal()
dlg.Destroy()
return
if not f_cpu:
dlg = wx.MessageDialog(self, "Unable to determine CPU clock rate.",
"CPU clock rate error", wx.OK | wx.ICON_ERROR)
dlg = wx.MessageDialog(
self,
"Unable to determine CPU clock rate.",
"CPU clock rate error",
wx.OK | wx.ICON_ERROR,
)
dlg.ShowModal()
dlg.Destroy()
return
@ -522,7 +563,7 @@ class ConfigFrame(wx.Frame):
lpfile = self.pgPrinter.getFileName()
lbfile = self.pgBoard.getFileName()
return ((pfile == lpfile) and (bfile == lbfile))
return (pfile == lpfile) and (bfile == lbfile)
def onEditSettings(self, evt):
dlg = SettingsDlg(self, self.settings)
@ -530,9 +571,12 @@ class ConfigFrame(wx.Frame):
dlg.Destroy()
def onHelp(self, evt):
self.message("Find help by hovering slowly over the buttons and text "
self.message(
"Find help by hovering slowly over the buttons and text "
"fields. Tooltip should appear, explaining things.",
"Find help", style = wx.OK)
"Find help",
style=wx.OK,
)
def onReportProblem(self, evt):
import urllib
@ -541,16 +585,20 @@ class ConfigFrame(wx.Frame):
from sys import platform
# Testing allowed URLs up to 32 kB in size. Longer URLs are simply chopped.
mailRecipients ="reply+0004dc756da9f0641af0a3834c580ad5be469f4f6b" \
"5d4cfc92cf00000001118c958a92a169ce051faa8c@" \
mailRecipients = (
"reply+0004dc756da9f0641af0a3834c580ad5be469f4f6b"
"5d4cfc92cf00000001118c958a92a169ce051faa8c@"
"reply.github.com,mah@jump-ing.de"
)
mailSubject = "Teacup problem report"
mailBody = "Please answer these questions before hitting \"send\":\n\n" \
"What did you try to do?\n\n\n" \
"What did you expect to happen?\n\n\n" \
"What happened instead?\n\n\n\n" \
"To allow developers to help, configuration files are " \
mailBody = (
'Please answer these questions before hitting "send":\n\n'
"What did you try to do?\n\n\n"
"What did you expect to happen?\n\n\n"
"What happened instead?\n\n\n\n"
"To allow developers to help, configuration files are "
"attached, with help comments stripped:\n"
)
for f in self.pgBoard.getFileName(), self.pgPrinter.getFileName():
if not f:
@ -567,9 +615,14 @@ class ConfigFrame(wx.Frame):
mailBody += "(could not read this file)\n"
mailBody += "----------------------------------------------\n"
url = "mailto:" + urllib.quote(mailRecipients) + \
"?subject=" + urllib.quote(mailSubject) + \
"&body=" + urllib.quote(mailBody)
url = (
"mailto:"
+ urllib.quote(mailRecipients)
+ "?subject="
+ urllib.quote(mailSubject)
+ "&body="
+ urllib.quote(mailBody)
)
# This is a work around a bug in gvfs-open coming with (at least) Ubuntu
# 15.04. gvfs-open would open mailto:///user@example.com instead of
@ -580,11 +633,20 @@ class ConfigFrame(wx.Frame):
# Broken gvfs-open exists, so it might be used.
# Try to open the URL directly.
for urlOpener in "thunderbird", "evolution", "firefox", "mozilla", \
"epiphany", "konqueror", "chromium-browser", \
"google-chrome":
for urlOpener in (
"thunderbird",
"evolution",
"firefox",
"mozilla",
"epiphany",
"konqueror",
"chromium-browser",
"google-chrome",
):
try:
subprocess.check_output([urlOpener, url], stderr=subprocess.STDOUT)
subprocess.check_output(
[urlOpener, url], stderr=subprocess.STDOUT
)
return
except:
pass
@ -599,7 +661,8 @@ class ConfigFrame(wx.Frame):
# git log $B | grep "Author:" | sort | uniq | while \
# read A; do N=$(git log $B | grep "$A" | wc -l); echo "$N $A"; done | \
# sort -rn
self.message("Teacup Firmware is a 3D Printer and CNC machine controlling "
self.message(
"Teacup Firmware is a 3D Printer and CNC machine controlling "
"firmware with emphasis on performance, efficiency and "
"outstanding quality. What Teacup does, shall it do very well."
"\n\n\n"
@ -616,7 +679,9 @@ class ConfigFrame(wx.Frame):
" Stephan Walter (9 commits)\n"
" Roland Brochard (3 commits)\n"
" Jens Ch. Restemeier (3 commits)\n",
"About Teacup", style = wx.OK)
"About Teacup",
style=wx.OK,
)
def message(self, text, title, style=wx.OK + wx.ICON_ERROR):
dlg = wx.MessageDialog(self, text, title, style)

View File

@ -1,4 +1,3 @@
import wx
@ -6,10 +5,13 @@ class HeaterList(wx.ListCtrl):
def __init__(self, parent, font):
self.parent = parent
self.currentItem = None
wx.ListCtrl.__init__(self, parent, wx.ID_ANY,
wx.ListCtrl.__init__(
self,
parent,
wx.ID_ANY,
size=(95 + 75 + 55 + 55 + 95 + 4, 100),
style = wx.LC_REPORT | wx.LC_VIRTUAL | wx.LC_HRULES |
wx.LC_VRULES)
style=wx.LC_REPORT | wx.LC_VIRTUAL | wx.LC_HRULES | wx.LC_VRULES,
)
self.SetFont(font)
self.valid = []

View File

@ -1,4 +1,3 @@
import wx
from configtool.page import Page
from configtool.data import pinNames, BSIZESMALL
@ -14,7 +13,7 @@ class HeatersPage(wx.Panel, Page):
self.font = font
self.id = idPg
self.labels = {'FORCE_SOFTWARE_PWM':"Force software PWM"}
self.labels = {"FORCE_SOFTWARE_PWM": "Force software PWM"}
sz = wx.GridBagSizer()
sz.Add((30, 30), pos=(0, 0))
@ -26,7 +25,7 @@ class HeatersPage(wx.Panel, Page):
sz.Add(self.lb, pos=(1, 1))
sz.Add((20, 20), pos=(1, 2))
k = 'FORCE_SOFTWARE_PWM'
k = "FORCE_SOFTWARE_PWM"
cb = self.addCheckBox(k, self.onCheckBox)
sz.Add(cb, pos=(2, 1))
@ -58,8 +57,7 @@ class HeatersPage(wx.Panel, Page):
self.bDelete.SetFont(font)
self.bDelete.Enable(False)
self.Bind(wx.EVT_BUTTON, self.doDelete, self.bDelete)
self.bDelete.SetToolTip("Remove the selected heater from the "
"configuration.")
self.bDelete.SetToolTip("Remove the selected heater from the " "configuration.")
bsz.Add(self.bDelete)
sz.Add(bsz, pos=(1, 3))
@ -123,8 +121,17 @@ class HeatersPage(wx.Panel, Page):
h = self.heaters[self.selection]
dlg = AddHeaterDlg(self, nm, [h[1]] + self.getFreePins(), self.font,
name = h[0], pin = h[1], invert = h[2], pwm = h[3], max_pwm = h[4])
dlg = AddHeaterDlg(
self,
nm,
[h[1]] + self.getFreePins(),
self.font,
name=h[0],
pin=h[1],
invert=h[2],
pwm=h[3],
max_pwm=h[4],
)
rc = dlg.ShowModal()
if rc == wx.ID_OK:
ht = dlg.getValues()
@ -175,15 +182,15 @@ class HeatersPage(wx.Panel, Page):
def validateTable(self):
self.lb.setTableValidity(True)
self.setFieldValidity('HEATERLIST', True)
self.setFieldValidity("HEATERLIST", True)
for i in range(len(self.heaters)):
if self.heaters[i][1] not in self.validPins:
self.lb.setRowValidity(i, False)
self.setFieldValidity('HEATERLIST', False)
self.setFieldValidity("HEATERLIST", False)
def setHelpText(self, ht):
Page.setHelpText(self, ht)
k = 'DEFINE_HEATER'
k = "DEFINE_HEATER"
if k in ht.keys():
self.bAdd.SetToolTip(ht[k])

View File

@ -1,4 +1,3 @@
import wx
from configtool.data import BSIZE
from configtool.page import Page
@ -14,52 +13,78 @@ class MechanicalPage(wx.Panel, Page):
self.parent = parent
self.font = font
self.spmKeys = ['STEPS_PER_M_X', 'STEPS_PER_M_Y', 'STEPS_PER_M_Z',
'STEPS_PER_M_E']
self.spmKeys = [
"STEPS_PER_M_X",
"STEPS_PER_M_Y",
"STEPS_PER_M_Z",
"STEPS_PER_M_E",
]
self.mfrKeys = ['MAXIMUM_FEEDRATE_X', 'MAXIMUM_FEEDRATE_Y',
'MAXIMUM_FEEDRATE_Z', 'MAXIMUM_FEEDRATE_E']
self.mfrKeys = [
"MAXIMUM_FEEDRATE_X",
"MAXIMUM_FEEDRATE_Y",
"MAXIMUM_FEEDRATE_Z",
"MAXIMUM_FEEDRATE_E",
]
self.msrKeys = ['SEARCH_FEEDRATE_X', 'SEARCH_FEEDRATE_Y',
'SEARCH_FEEDRATE_Z']
self.msrKeys = ["SEARCH_FEEDRATE_X", "SEARCH_FEEDRATE_Y", "SEARCH_FEEDRATE_Z"]
self.eclKeys = ['ENDSTOP_CLEARANCE_X', 'ENDSTOP_CLEARANCE_Y',
'ENDSTOP_CLEARANCE_Z']
self.eclKeys = [
"ENDSTOP_CLEARANCE_X",
"ENDSTOP_CLEARANCE_Y",
"ENDSTOP_CLEARANCE_Z",
]
self.minmaxKeys = ['X_MIN', 'X_MAX', 'Y_MIN', 'Y_MAX', 'Z_MIN', 'Z_MAX']
self.minmaxKeys = ["X_MIN", "X_MAX", "Y_MIN", "Y_MAX", "Z_MIN", "Z_MAX"]
self.kinematicsKeys = ['KINEMATICS_STRAIGHT', 'KINEMATICS_COREXY']
self.kinematicsKeys = ["KINEMATICS_STRAIGHT", "KINEMATICS_COREXY"]
self.homingKeys = [('HOMING_STEP1', 2), ('HOMING_STEP2', 2),
('HOMING_STEP3', 2), ('HOMING_STEP4', 2)]
self.homingKeys = [
("HOMING_STEP1", 2),
("HOMING_STEP2", 2),
("HOMING_STEP3", 2),
("HOMING_STEP4", 2),
]
self.labels = {'STEPS_PER_M_X': "X:", 'STEPS_PER_M_Y': "Y:",
'STEPS_PER_M_Z': "Z:", 'STEPS_PER_M_E' : "E:",
'MAXIMUM_FEEDRATE_X': "X:", 'MAXIMUM_FEEDRATE_Y': "Y:",
'MAXIMUM_FEEDRATE_Z': "Z:", 'MAXIMUM_FEEDRATE_E': "E:",
'SEARCH_FEEDRATE_X': "X:", 'SEARCH_FEEDRATE_Y': "Y:",
'SEARCH_FEEDRATE_Z': "Z:",
'ENDSTOP_CLEARANCE_X': "X:", 'ENDSTOP_CLEARANCE_Y': "Y:",
'ENDSTOP_CLEARANCE_Z': "Z:",
'X_MIN': "Min X:", 'X_MAX': "Max X:", 'Y_MIN': "Min Y:",
'Y_MAX': "Max Y:", 'Z_MIN': "Min Z:", 'Z_MAX': "Max Z:",
'E_ABSOLUTE': "Absolute E Coordinates",
'KINEMATICS_STRAIGHT': "Straight",
'KINEMATICS_COREXY': "CoreXY",
'HOMING_STEP1': "Step 1:",
'HOMING_STEP2': "Step 2:",
'HOMING_STEP3': "Step 3:",
'HOMING_STEP4': "Step 4:",
'none': "-",
'x_negative': "X min",
'x_positive': "X max",
'y_negative': "Y min",
'y_positive': "Y max",
'z_negative': "Z min",
'z_positive': "Z max"}
self.labels = {
"STEPS_PER_M_X": "X:",
"STEPS_PER_M_Y": "Y:",
"STEPS_PER_M_Z": "Z:",
"STEPS_PER_M_E": "E:",
"MAXIMUM_FEEDRATE_X": "X:",
"MAXIMUM_FEEDRATE_Y": "Y:",
"MAXIMUM_FEEDRATE_Z": "Z:",
"MAXIMUM_FEEDRATE_E": "E:",
"SEARCH_FEEDRATE_X": "X:",
"SEARCH_FEEDRATE_Y": "Y:",
"SEARCH_FEEDRATE_Z": "Z:",
"ENDSTOP_CLEARANCE_X": "X:",
"ENDSTOP_CLEARANCE_Y": "Y:",
"ENDSTOP_CLEARANCE_Z": "Z:",
"X_MIN": "Min X:",
"X_MAX": "Max X:",
"Y_MIN": "Min Y:",
"Y_MAX": "Max Y:",
"Z_MIN": "Min Z:",
"Z_MAX": "Max Z:",
"E_ABSOLUTE": "Absolute E Coordinates",
"KINEMATICS_STRAIGHT": "Straight",
"KINEMATICS_COREXY": "CoreXY",
"HOMING_STEP1": "Step 1:",
"HOMING_STEP2": "Step 2:",
"HOMING_STEP3": "Step 3:",
"HOMING_STEP4": "Step 4:",
"none": "-",
"x_negative": "X min",
"x_positive": "X max",
"y_negative": "Y min",
"y_positive": "Y max",
"z_negative": "Z min",
"z_positive": "Z max",
}
labelWidth = 40;
labelWidthHoming = 60;
labelWidth = 40
labelWidthHoming = 60
sz = wx.GridBagSizer()
sz.Add((10, 10), pos=(0, 0))
@ -136,7 +161,7 @@ class MechanicalPage(wx.Panel, Page):
vsz.Add(sbox, 1, wx.LEFT, 10)
cb = self.addCheckBox('E_ABSOLUTE', self.onCheckBox)
cb = self.addCheckBox("E_ABSOLUTE", self.onCheckBox)
vsz.Add(cb, 1, wx.LEFT, 10)
@ -204,24 +229,24 @@ class MechanicalPage(wx.Panel, Page):
def setHelpText(self, ht):
Page.setHelpText(self, ht)
if 'KINEMATICS' in ht.keys():
if "KINEMATICS" in ht.keys():
for k in self.kinematicsKeys:
self.radioButtons[k].SetToolTip(ht['KINEMATICS'])
self.radioButtons[k].SetToolTip(ht["KINEMATICS"])
def prepareHomingValues(self, name, i, cfgValues):
self.choices[name].Clear()
for p in cfgValues['HOMING_OPTS']:
for p in cfgValues["HOMING_OPTS"]:
self.choices[name].Append(self.labels[p])
i = cfgValues['HOMING_OPTS'].index(cfgValues[name])
i = cfgValues["HOMING_OPTS"].index(cfgValues[name])
self.choices[name].SetSelection(i)
def insertValues(self, cfgValues):
Page.insertValues(self, cfgValues)
self.prepareHomingValues('HOMING_STEP1', 0, cfgValues)
self.prepareHomingValues('HOMING_STEP2', 1, cfgValues)
self.prepareHomingValues('HOMING_STEP3', 2, cfgValues)
self.prepareHomingValues('HOMING_STEP4', 3, cfgValues)
self.prepareHomingValues("HOMING_STEP1", 0, cfgValues)
self.prepareHomingValues("HOMING_STEP2", 1, cfgValues)
self.prepareHomingValues("HOMING_STEP3", 2, cfgValues)
self.prepareHomingValues("HOMING_STEP4", 3, cfgValues)
for tag in self.kinematicsKeys:
if tag in cfgValues.keys() and cfgValues[tag]:
@ -236,9 +261,9 @@ class MechanicalPage(wx.Panel, Page):
for tag in self.kinematicsKeys:
result[tag] = self.radioButtons[tag].GetValue()
result['HOMING_STEP1'] = self.getHomingValue('HOMING_STEP1', result)
result['HOMING_STEP2'] = self.getHomingValue('HOMING_STEP2', result)
result['HOMING_STEP3'] = self.getHomingValue('HOMING_STEP3', result)
result['HOMING_STEP4'] = self.getHomingValue('HOMING_STEP4', result)
result["HOMING_STEP1"] = self.getHomingValue("HOMING_STEP1", result)
result["HOMING_STEP2"] = self.getHomingValue("HOMING_STEP2", result)
result["HOMING_STEP3"] = self.getHomingValue("HOMING_STEP3", result)
result["HOMING_STEP4"] = self.getHomingValue("HOMING_STEP4", result)
return result

View File

@ -1,4 +1,3 @@
import wx
from configtool.page import Page
from configtool.data import reFloat
@ -12,25 +11,28 @@ class MiscellaneousPage(wx.Panel, Page):
self.id = idPg
self.font = font
self.labels = {'USE_INTERNAL_PULLUPS': "Use Internal Pullups",
'BED_LEVELING': "Enable dynamic bed leveling",
'Z_AUTODISABLE': "Z Autodisable",
'EECONFIG': "Enable EEPROM Storage",
'BANG_BANG': "Enable",
'BANG_BANG_ON': "On PWM Level:",
'BANG_BANG_OFF': "Off PWM Level:",
'REPORT_TARGET_TEMPS': "Report Target Temperatures",
'MOVEBUFFER_SIZE': "Movebuffer Size:",
'DC_EXTRUDER': "Heater:", 'DC_EXTRUDER_PWM': "PWM:",
'USE_WATCHDOG': "Use the Watchdog Timer",
'TH_COUNT': "Temperature History Size:",
'FAST_PWM': "Fast PWM",
'ENDSTOP_STEPS': "Endstop Steps:",
'PID_SCALE': "PID Scaling Factor:",
'TEMP_HYSTERESIS': "Temperature Hysteresis:",
'TEMP_RESIDENCY_TIME': "Temperature Residency Time:",
'TEMP_EWMA': "Temperature EWMA:",
'HEATER_SANITY_CHECK': "Heater Sanity Check"}
self.labels = {
"USE_INTERNAL_PULLUPS": "Use Internal Pullups",
"BED_LEVELING": "Enable dynamic bed leveling",
"Z_AUTODISABLE": "Z Autodisable",
"EECONFIG": "Enable EEPROM Storage",
"BANG_BANG": "Enable",
"BANG_BANG_ON": "On PWM Level:",
"BANG_BANG_OFF": "Off PWM Level:",
"REPORT_TARGET_TEMPS": "Report Target Temperatures",
"MOVEBUFFER_SIZE": "Movebuffer Size:",
"DC_EXTRUDER": "Heater:",
"DC_EXTRUDER_PWM": "PWM:",
"USE_WATCHDOG": "Use the Watchdog Timer",
"TH_COUNT": "Temperature History Size:",
"FAST_PWM": "Fast PWM",
"ENDSTOP_STEPS": "Endstop Steps:",
"PID_SCALE": "PID Scaling Factor:",
"TEMP_HYSTERESIS": "Temperature Hysteresis:",
"TEMP_RESIDENCY_TIME": "Temperature Residency Time:",
"TEMP_EWMA": "Temperature EWMA:",
"HEATER_SANITY_CHECK": "Heater Sanity Check",
}
self.heaterNameNone = "<none>"
self.heaterNames = [self.heaterNameNone]
@ -52,35 +54,35 @@ class MiscellaneousPage(wx.Panel, Page):
labelWidth = 140
k = 'EECONFIG'
k = "EECONFIG"
cb = self.addCheckBox(k, self.onCheckBox)
sz.Add(cb, pos=(1, 1))
k = 'USE_INTERNAL_PULLUPS'
k = "USE_INTERNAL_PULLUPS"
cb = self.addCheckBox(k, self.onCheckBox)
sz.Add(cb, pos=(2, 1))
k = 'USE_WATCHDOG'
k = "USE_WATCHDOG"
cb = self.addCheckBox(k, self.onCheckBox)
sz.Add(cb, pos=(3, 1))
k = 'FAST_PWM'
k = "FAST_PWM"
cb = self.addCheckBox(k, self.onCheckBox)
sz.Add(cb, pos=(4, 1))
k = 'HEATER_SANITY_CHECK'
k = "HEATER_SANITY_CHECK"
cb = self.addCheckBox(k, self.onCheckBox)
sz.Add(cb, pos=(5, 1))
k = 'REPORT_TARGET_TEMPS'
k = "REPORT_TARGET_TEMPS"
cb = self.addCheckBox(k, self.onCheckBox)
sz.Add(cb, pos=(6, 1))
k = 'Z_AUTODISABLE'
k = "Z_AUTODISABLE"
cb = self.addCheckBox(k, self.onCheckBox)
sz.Add(cb, pos=(7, 1))
k = 'BED_LEVELING'
k = "BED_LEVELING"
cb = self.addCheckBox(k, self.onCheckBox)
sz.Add(cb, pos=(8, 1))
@ -89,17 +91,17 @@ class MiscellaneousPage(wx.Panel, Page):
sbox = wx.StaticBoxSizer(b, wx.VERTICAL)
sbox.Add((5, 5))
k = 'BANG_BANG'
k = "BANG_BANG"
cb = self.addCheckBox(k, self.onCheckBox)
sbox.Add(cb, 1, wx.LEFT, 60)
sbox.Add((5, 20))
k = 'BANG_BANG_ON'
k = "BANG_BANG_ON"
tc = self.addTextCtrl(k, 100, self.onTextCtrlInteger)
sbox.Add(tc)
sbox.Add((5, 5))
k = 'BANG_BANG_OFF'
k = "BANG_BANG_OFF"
tc = self.addTextCtrl(k, 100, self.onTextCtrlInteger)
sbox.Add(tc)
sbox.Add((5, 5))
@ -111,45 +113,45 @@ class MiscellaneousPage(wx.Panel, Page):
sbox = wx.StaticBoxSizer(b, wx.VERTICAL)
sbox.Add((5, 5))
k = 'DC_EXTRUDER'
k = "DC_EXTRUDER"
ch = self.addChoice(k, self.heaterNames, 0, 60, self.onChoice)
sbox.Add(ch)
sbox.Add((5, 5))
k = 'DC_EXTRUDER_PWM'
k = "DC_EXTRUDER_PWM"
tc = self.addTextCtrl(k, 60, self.onTextCtrlInteger)
sbox.Add(tc)
sbox.Add((5, 5))
sz.Add(sbox, pos=(6, 3), span=(3, 1), flag=wx.ALIGN_CENTER_HORIZONTAL)
labelWidth = 190;
labelWidth = 190
k = 'MOVEBUFFER_SIZE'
k = "MOVEBUFFER_SIZE"
tc = self.addTextCtrl(k, labelWidth, self.onTextCtrlInteger)
sz.Add(tc, pos=(1, 5))
k = 'TH_COUNT'
k = "TH_COUNT"
tc = self.addTextCtrl(k, labelWidth, self.onTextCtrlInteger)
sz.Add(tc, pos=(2, 5))
k = 'ENDSTOP_STEPS'
k = "ENDSTOP_STEPS"
tc = self.addTextCtrl(k, labelWidth, self.onTextCtrlInteger)
sz.Add(tc, pos=(3, 5))
k = 'PID_SCALE'
k = "PID_SCALE"
tc = self.addTextCtrl(k, labelWidth, self.onTextCtrlInteger)
sz.Add(tc, pos=(4, 5))
k = 'TEMP_HYSTERESIS'
k = "TEMP_HYSTERESIS"
tc = self.addTextCtrl(k, labelWidth, self.onTextCtrlInteger)
sz.Add(tc, pos=(6, 5))
k = 'TEMP_RESIDENCY_TIME'
k = "TEMP_RESIDENCY_TIME"
tc = self.addTextCtrl(k, labelWidth, self.onTextCtrlInteger)
sz.Add(tc, pos=(7, 5))
k = 'TEMP_EWMA'
k = "TEMP_EWMA"
tc = self.addTextCtrl(k, labelWidth, self.onTextCtrlInteger)
sz.Add(tc, pos=(8, 5))
@ -157,7 +159,7 @@ class MiscellaneousPage(wx.Panel, Page):
self.enableAll(False)
def setHeaters(self, hlist):
k = 'DC_EXTRUDER'
k = "DC_EXTRUDER"
v = self.choices[k].GetSelection()
currentChoice = self.heaterNames[v]
self.boardHeaters = [s[0] for s in hlist]
@ -171,11 +173,13 @@ class MiscellaneousPage(wx.Panel, Page):
v = self.heaterNames.index(currentChoice)
except:
v = 0
dlg = wx.MessageDialog(self,
dlg = wx.MessageDialog(
self,
"Printer: Miscellaneous tab:\nDC Extruder heater "
"\"%s\" not defined for this board. Please check."
% currentChoice, "Warning",
wx.OK + wx.ICON_WARNING)
'"%s" not defined for this board. Please check.' % currentChoice,
"Warning",
wx.OK + wx.ICON_WARNING,
)
dlg.ShowModal()
dlg.Destroy()
@ -183,18 +187,21 @@ class MiscellaneousPage(wx.Panel, Page):
self.choices[k].SetSelection(v)
def setOriginalHeater(self, h):
k = 'DC_EXTRUDER'
k = "DC_EXTRUDER"
if h and h.startswith("HEATER_"):
hname = h[len("HEATER_") :]
else:
hname = h
if hname and len(self.boardHeaters) != 0:
if hname not in self.boardHeaters:
dlg = wx.MessageDialog(self,
dlg = wx.MessageDialog(
self,
"Printer: Miscellaneous tab:\nDC Extruder "
"heater \"%s\" not defined for this board. "
"Please check."
% hname, "Warning", wx.OK + wx.ICON_WARNING)
'heater "%s" not defined for this board. '
"Please check." % hname,
"Warning",
wx.OK + wx.ICON_WARNING,
)
dlg.ShowModal()
dlg.Destroy()
@ -219,7 +226,7 @@ class MiscellaneousPage(wx.Panel, Page):
def getValues(self):
result = Page.getValues(self)
k = 'DC_EXTRUDER'
k = "DC_EXTRUDER"
s = self.choices[k].GetSelection()
v = self.choices[k].GetString(s)
if v == self.heaterNameNone:

View File

@ -3,8 +3,7 @@ from __future__ import print_function
import wx
from configtool.decoration import Decoration
from configtool.data import (reInteger, reFloat, offsetChLabel, offsetTcLabel,
pinNames)
from configtool.data import reInteger, reFloat, offsetChLabel, offsetTcLabel, pinNames
class Page:
@ -38,8 +37,13 @@ class Page:
def addTextCtrl(self, name, labelWidth, validator):
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, self.labels[name] + " ",
size = (labelWidth, -1), style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self,
wx.ID_ANY,
self.labels[name] + " ",
size=(labelWidth, -1),
style=wx.ALIGN_RIGHT,
)
st.SetFont(self.font)
lsz.Add(st, 1, wx.TOP, offsetTcLabel)
@ -74,11 +78,15 @@ class Page:
return rb
def addChoice(self, name, choices, selection, labelWidth, validator,
size = (-1, -1)):
def addChoice(self, name, choices, selection, labelWidth, validator, size=(-1, -1)):
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, self.labels[name],
size = (labelWidth, -1), style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self,
wx.ID_ANY,
self.labels[name],
size=(labelWidth, -1),
style=wx.ALIGN_RIGHT,
)
st.SetFont(self.font)
lsz.Add(st, 1, wx.TOP, offsetChLabel)
@ -94,8 +102,13 @@ class Page:
def addPinChoice(self, name, labelWidth):
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, self.labels[name],
size = (labelWidth, -1), style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self,
wx.ID_ANY,
self.labels[name],
size=(labelWidth, -1),
style=wx.ALIGN_RIGHT,
)
st.SetFont(self.font)
lsz.Add(st, 1, wx.TOP, offsetChLabel)
@ -111,11 +124,15 @@ class Page:
# addChoice handles #defines with value, this handles choices for
# sets of boolean #defines.
def addBoolChoice(self, name, allowBlank, labelWidth, validator,
size = (-1, -1)):
def addBoolChoice(self, name, allowBlank, labelWidth, validator, size=(-1, -1)):
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, self.labels[name],
size = (labelWidth, -1), style = wx.ALIGN_RIGHT)
st = wx.StaticText(
self,
wx.ID_ANY,
self.labels[name],
size=(labelWidth, -1),
style=wx.ALIGN_RIGHT,
)
st.SetFont(self.font)
lsz.Add(st, 1, wx.TOP, offsetChLabel)
@ -269,8 +286,9 @@ class Page:
choice = self.boolChoices[k]
# Remove items left behind from the previous configuration.
while (choice.GetCount() and
not choice.GetString(choice.GetCount() - 1).startswith('(')):
while choice.GetCount() and not choice.GetString(
choice.GetCount() - 1
).startswith("("):
choice.Delete(choice.GetCount() - 1)
# Add items found in this configuration.
@ -328,7 +346,7 @@ class Page:
for i in range(choice.GetCount()):
s = choice.GetClientData(i)
if s:
result[s] = (i == choice.GetSelection())
result[s] = i == choice.GetSelection()
return result

View File

@ -1,4 +1,3 @@
import wx
from configtool.page import Page
@ -10,59 +9,88 @@ class PinoutsPage(wx.Panel, Page):
self.parent = parent
self.id = idPg
pinXkeys = [('X_STEP_PIN', 2), ('X_DIR_PIN', 2), ('X_MIN_PIN', 2),
('X_MAX_PIN', 2), ('X_ENABLE_PIN', 2), ('X_INVERT_DIR', 1),
('X_INVERT_MIN', 1), ('X_INVERT_MAX', 1),
('X_INVERT_ENABLE', 1)]
pinYkeys = [('Y_STEP_PIN', 2), ('Y_DIR_PIN', 2), ('Y_MIN_PIN', 2),
('Y_MAX_PIN', 2), ('Y_ENABLE_PIN', 2), ('Y_INVERT_DIR', 1),
('Y_INVERT_MIN', 1), ('Y_INVERT_MAX', 1),
('Y_INVERT_ENABLE', 1)]
pinZkeys = [('Z_STEP_PIN', 2), ('Z_DIR_PIN', 2), ('Z_MIN_PIN', 2),
('Z_MAX_PIN', 2), ('Z_ENABLE_PIN', 2), ('Z_INVERT_DIR', 1),
('Z_INVERT_MIN', 1), ('Z_INVERT_MAX', 1),
('Z_INVERT_ENABLE', 1)]
pinEkeys = [('E_STEP_PIN', 2), ('E_DIR_PIN', 2), ('E_ENABLE_PIN', 2),
('E_INVERT_DIR', 1), ('E_INVERT_ENABLE', 1)]
pinXkeys = [
("X_STEP_PIN", 2),
("X_DIR_PIN", 2),
("X_MIN_PIN", 2),
("X_MAX_PIN", 2),
("X_ENABLE_PIN", 2),
("X_INVERT_DIR", 1),
("X_INVERT_MIN", 1),
("X_INVERT_MAX", 1),
("X_INVERT_ENABLE", 1),
]
pinYkeys = [
("Y_STEP_PIN", 2),
("Y_DIR_PIN", 2),
("Y_MIN_PIN", 2),
("Y_MAX_PIN", 2),
("Y_ENABLE_PIN", 2),
("Y_INVERT_DIR", 1),
("Y_INVERT_MIN", 1),
("Y_INVERT_MAX", 1),
("Y_INVERT_ENABLE", 1),
]
pinZkeys = [
("Z_STEP_PIN", 2),
("Z_DIR_PIN", 2),
("Z_MIN_PIN", 2),
("Z_MAX_PIN", 2),
("Z_ENABLE_PIN", 2),
("Z_INVERT_DIR", 1),
("Z_INVERT_MIN", 1),
("Z_INVERT_MAX", 1),
("Z_INVERT_ENABLE", 1),
]
pinEkeys = [
("E_STEP_PIN", 2),
("E_DIR_PIN", 2),
("E_ENABLE_PIN", 2),
("E_INVERT_DIR", 1),
("E_INVERT_ENABLE", 1),
]
self.labels = {'X_STEP_PIN': "Step Pin:", 'X_DIR_PIN': "Direction Pin:",
'X_MIN_PIN': "Minimum Pin:", 'X_MAX_PIN': "Maximum Pin:",
'X_ENABLE_PIN': "Enable Pin:",
'X_INVERT_DIR': "Invert Direction",
'X_INVERT_MIN': "Invert Minimum",
'X_INVERT_MAX': "Invert Maximum",
'X_INVERT_ENABLE': "Invert Enable",
'Y_STEP_PIN': "Step Pin:", 'Y_DIR_PIN': "Direction Pin:",
'Y_MIN_PIN': "Minimum Pin:", 'Y_MAX_PIN': "Maximum Pin:",
'Y_ENABLE_PIN': "Enable Pin:",
'Y_INVERT_DIR': "Invert Direction",
'Y_INVERT_MIN': "Invert Minimum",
'Y_INVERT_MAX': "Invert Maximum",
'Y_INVERT_ENABLE': "Invert Enable",
'Z_STEP_PIN': "Step Pin:", 'Z_DIR_PIN': "Direction Pin:",
'Z_MIN_PIN': "Minimum Pin:", 'Z_MAX_PIN': "Maximum Pin:",
'Z_ENABLE_PIN': "Enable Pin:",
'Z_INVERT_DIR': "Invert Direction",
'Z_INVERT_MIN': "Invert Minimum",
'Z_INVERT_MAX': "Invert Maximum",
'Z_INVERT_ENABLE': "Invert Enable",
'E_STEP_PIN': "Step Pin:", 'E_DIR_PIN': "Direction Pin:",
'E_ENABLE_PIN': "Enable Pin:",
'E_INVERT_DIR': "Invert Direction",
'E_INVERT_ENABLE': "Invert Enable",
'PS_ON_PIN': "PSU On Pin:",
'PS_INVERT_ON': "Invert PSU On Pin",
'PS_MOSFET_PIN': "PSU MOSFET Pin:",
'STEPPER_ENABLE_PIN': "Stepper Enable Pin:",
'STEPPER_INVERT_ENABLE': "Stepper Invert Enable",
'SD_CARD_SELECT_PIN': "SD Card Pin:",
'DEBUG_LED_PIN': "Debug LED Pin:"}
self.labels = {
"X_STEP_PIN": "Step Pin:",
"X_DIR_PIN": "Direction Pin:",
"X_MIN_PIN": "Minimum Pin:",
"X_MAX_PIN": "Maximum Pin:",
"X_ENABLE_PIN": "Enable Pin:",
"X_INVERT_DIR": "Invert Direction",
"X_INVERT_MIN": "Invert Minimum",
"X_INVERT_MAX": "Invert Maximum",
"X_INVERT_ENABLE": "Invert Enable",
"Y_STEP_PIN": "Step Pin:",
"Y_DIR_PIN": "Direction Pin:",
"Y_MIN_PIN": "Minimum Pin:",
"Y_MAX_PIN": "Maximum Pin:",
"Y_ENABLE_PIN": "Enable Pin:",
"Y_INVERT_DIR": "Invert Direction",
"Y_INVERT_MIN": "Invert Minimum",
"Y_INVERT_MAX": "Invert Maximum",
"Y_INVERT_ENABLE": "Invert Enable",
"Z_STEP_PIN": "Step Pin:",
"Z_DIR_PIN": "Direction Pin:",
"Z_MIN_PIN": "Minimum Pin:",
"Z_MAX_PIN": "Maximum Pin:",
"Z_ENABLE_PIN": "Enable Pin:",
"Z_INVERT_DIR": "Invert Direction",
"Z_INVERT_MIN": "Invert Minimum",
"Z_INVERT_MAX": "Invert Maximum",
"Z_INVERT_ENABLE": "Invert Enable",
"E_STEP_PIN": "Step Pin:",
"E_DIR_PIN": "Direction Pin:",
"E_ENABLE_PIN": "Enable Pin:",
"E_INVERT_DIR": "Invert Direction",
"E_INVERT_ENABLE": "Invert Enable",
"PS_ON_PIN": "PSU On Pin:",
"PS_INVERT_ON": "Invert PSU On Pin",
"PS_MOSFET_PIN": "PSU MOSFET Pin:",
"STEPPER_ENABLE_PIN": "Stepper Enable Pin:",
"STEPPER_INVERT_ENABLE": "Stepper Invert Enable",
"SD_CARD_SELECT_PIN": "SD Card Pin:",
"DEBUG_LED_PIN": "Debug LED Pin:",
}
labelWidth = 120

View File

@ -4,12 +4,25 @@ import os
import re
from sys import platform
from configtool.data import (defineValueFormat, defineBoolFormat,
reHelpTextStart, reHelpTextEnd,
reDefine, reDefineBL, reDefQS, reDefQSm,
reDefQSm2, reDefBool, reDefBoolBL,
reHomingOpts, reStartHoming, reEndHoming,
reDefHoming, reHoming4)
from configtool.data import (
defineValueFormat,
defineBoolFormat,
reHelpTextStart,
reHelpTextEnd,
reDefine,
reDefineBL,
reDefQS,
reDefQSm,
reDefQSm2,
reDefBool,
reDefBoolBL,
reHomingOpts,
reStartHoming,
reEndHoming,
reDefHoming,
reHoming4,
)
class Printer:
def __init__(self, settings):
@ -24,7 +37,7 @@ class Printer:
return dict(vars)
def hasData(self):
return (self.configFile != None)
return self.configFile != None
def getFileName(self):
return self.configFile
@ -159,11 +172,11 @@ class Printer:
if m:
t = m.groups()
if len(t) == 1:
if 'HOMING_OPTS' in self.cfgValues:
if t[0] not in self.cfgValues['HOMING_OPTS']:
self.cfgValues['HOMING_OPTS'].append(t[0])
if "HOMING_OPTS" in self.cfgValues:
if t[0] not in self.cfgValues["HOMING_OPTS"]:
self.cfgValues["HOMING_OPTS"].append(t[0])
else:
self.cfgValues['HOMING_OPTS'] = [t[0]]
self.cfgValues["HOMING_OPTS"] = [t[0]]
return True
def parseHoming(self, ln):
@ -179,10 +192,10 @@ class Printer:
for x in u:
t2.append(x)
self.cfgValues['HOMING_STEP1'] = t2[0]
self.cfgValues['HOMING_STEP2'] = t2[1]
self.cfgValues['HOMING_STEP3'] = t2[2]
self.cfgValues['HOMING_STEP4'] = t2[3]
self.cfgValues["HOMING_STEP1"] = t2[0]
self.cfgValues["HOMING_STEP2"] = t2[1]
self.cfgValues["HOMING_STEP3"] = t2[2]
self.cfgValues["HOMING_STEP4"] = t2[3]
return True
return None
@ -220,9 +233,13 @@ class Printer:
# Accept booleans, but not those for which a value exists already.
# Booleans already existing as values are most likely misconfigured
# manual edits (or result of a bug).
if len(t) == 1 and t[0] in self.cfgNames \
and not (t[0] in self.cfgValues \
and isinstance(self.cfgValues[t[0]], tuple)):
if (
len(t) == 1
and t[0] in self.cfgNames
and not (
t[0] in self.cfgValues and isinstance(self.cfgValues[t[0]], tuple)
)
):
if reDefBoolBL.search(ln):
self.cfgValues[t[0]] = True
else:
@ -240,7 +257,7 @@ class Printer:
if self.settings.verbose >= 2:
print(values)
fp = file(path, 'w')
fp = file(path, "w")
self.configFile = path
skipToHomingEnd = False
@ -249,10 +266,12 @@ class Printer:
m = reStartHoming.match(ln)
if m:
fp.write(ln)
sstr = "%s, %s, %s, %s" % ((values['HOMING_STEP1']),
(values['HOMING_STEP2']),
(values['HOMING_STEP3']),
(values['HOMING_STEP4']))
sstr = "%s, %s, %s, %s" % (
(values["HOMING_STEP1"]),
(values["HOMING_STEP2"]),
(values["HOMING_STEP3"]),
(values["HOMING_STEP4"]),
)
fp.write("DEFINE_HOMING(%s)\n" % sstr)
skipToHomingEnd = True
continue
@ -274,7 +293,7 @@ class Printer:
fp.write("//")
fp.write(defineValueFormat % (t[0], v[0]))
else:
if t[0] == 'CANNED_CYCLE':
if t[0] == "CANNED_CYCLE":
# Known to be absent in the GUI. Worse, this value is replaced
# by the one in the metadata file.
#

View File

@ -1,14 +1,22 @@
import os
import wx
import re
from sys import platform
from configtool.decoration import Decoration
from configtool.data import (defineValueFormat, defineBoolFormat,
reHelpTextStart, reHelpTextEnd,
reDefine, reDefineBL, reDefQS, reDefQSm,
reDefQSm2, reDefBool, reDefBoolBL)
from configtool.data import (
defineValueFormat,
defineBoolFormat,
reHelpTextStart,
reHelpTextEnd,
reDefine,
reDefineBL,
reDefQS,
reDefQSm,
reDefQSm2,
reDefBool,
reDefBoolBL,
)
from configtool.mechanicalpage import MechanicalPage
from configtool.accelerationpage import AccelerationPage
from configtool.miscellaneouspage import MiscellaneousPage
@ -34,8 +42,7 @@ class PrinterPanel(wx.Panel):
self.Bind(wx.EVT_PAINT, self.deco.onPaintBackground)
sz = wx.BoxSizer(wx.HORIZONTAL)
self.nb = wx.Notebook(self, wx.ID_ANY, size = (21, 21),
style = wx.BK_DEFAULT)
self.nb = wx.Notebook(self, wx.ID_ANY, size=(21, 21), style=wx.BK_DEFAULT)
self.nb.SetBackgroundColour(self.deco.getBackgroundColour())
self.nb.SetFont(self.settings.font)
@ -46,8 +53,7 @@ class PrinterPanel(wx.Panel):
self.pgMech = self.registerPage(MechanicalPage, "Mechanical")
self.pgAcc = self.registerPage(AccelerationPage, "Acceleration")
self.pgMiscellaneous = self.registerPage(MiscellaneousPage,
"Miscellaneous")
self.pgMiscellaneous = self.registerPage(MiscellaneousPage, "Miscellaneous")
sz.Add(self.nb, 1, wx.EXPAND + wx.ALL, 5)
@ -55,8 +61,9 @@ class PrinterPanel(wx.Panel):
self.Fit()
def registerPage(self, klass, label, *args, **kwargs):
page = klass(self, self.nb, len(self.pages), *args,
font = self.settings.font, **kwargs)
page = klass(
self, self.nb, len(self.pages), *args, font=self.settings.font, **kwargs
)
self.nb.AddPage(page, label)
self.pages.append(page)
self.titles.append(label)
@ -69,7 +76,7 @@ class PrinterPanel(wx.Panel):
self.modifyTab(pg)
def isModified(self):
return (True in self.pageModified)
return True in self.pageModified
def isValid(self):
return not (False in self.pageValid)
@ -123,11 +130,14 @@ class PrinterPanel(wx.Panel):
if True not in self.pageModified:
return True
dlg = wx.MessageDialog(self, "Are you sure you want to " + msg + "?\n"
dlg = wx.MessageDialog(
self,
"Are you sure you want to " + msg + "?\n"
"There are changes to your printer "
"configuration that will be lost.",
"Changes pending",
wx.YES_NO | wx.NO_DEFAULT | wx.ICON_INFORMATION)
wx.YES_NO | wx.NO_DEFAULT | wx.ICON_INFORMATION,
)
rc = dlg.ShowModal()
dlg.Destroy()
@ -146,9 +156,14 @@ class PrinterPanel(wx.Panel):
else:
wildcard = "Printer configuration (printer.*.h)|printer.*.h"
dlg = wx.FileDialog(self, message = "Choose a printer config file",
defaultDir = self.dir, defaultFile = "",
wildcard = wildcard, style = wx.FD_OPEN | wx.FD_CHANGE_DIR)
dlg = wx.FileDialog(
self,
message="Choose a printer config file",
defaultDir=self.dir,
defaultFile="",
wildcard=wildcard,
style=wx.FD_OPEN | wx.FD_CHANGE_DIR,
)
path = None
if dlg.ShowModal() == wx.ID_OK:
@ -162,8 +177,12 @@ class PrinterPanel(wx.Panel):
rc, efn = self.loadConfigFile(path)
if not rc:
dlg = wx.MessageDialog(self, "Unable to process file %s." % efn,
"File error", wx.OK + wx.ICON_ERROR)
dlg = wx.MessageDialog(
self,
"Unable to process file %s." % efn,
"File error",
wx.OK + wx.ICON_ERROR,
)
dlg.ShowModal()
dlg.Destroy()
return
@ -185,7 +204,7 @@ class PrinterPanel(wx.Panel):
pg.insertValues(self.printer.cfgValues)
pg.setHelpText(self.printer.helpText)
k = 'DC_EXTRUDER'
k = "DC_EXTRUDER"
if k in self.printer.cfgValues.keys() and self.printer.cfgValues[k][1] == True:
self.pgMiscellaneous.setOriginalHeater(self.printer.cfgValues[k][0])
else:
@ -204,9 +223,14 @@ class PrinterPanel(wx.Panel):
else:
wildcard = "Printer configuration (printer.*.h)|printer.*.h"
dlg = wx.FileDialog(self, message = "Save as ...", defaultDir = self.dir,
defaultFile = "", wildcard = wildcard,
style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
dlg = wx.FileDialog(
self,
message="Save as ...",
defaultDir=self.dir,
defaultFile="",
wildcard=wildcard,
style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT,
)
val = dlg.ShowModal()
@ -226,17 +250,25 @@ class PrinterPanel(wx.Panel):
def saveConfigFile(self, path):
if os.path.basename(path) in protectedFiles:
dlg = wx.MessageDialog(self, "It's not allowed to overwrite files "
dlg = wx.MessageDialog(
self,
"It's not allowed to overwrite files "
"distributed by Teacup. Choose another name.",
"Protected file error", wx.OK + wx.ICON_ERROR)
"Protected file error",
wx.OK + wx.ICON_ERROR,
)
dlg.ShowModal()
dlg.Destroy()
return False
if not os.path.basename(path).startswith("printer."):
dlg = wx.MessageDialog(self, "Illegal file name: %s.\n"
"File name must begin with \"printer.\"" % path,
"Illegal file name", wx.OK + wx.ICON_ERROR)
dlg = wx.MessageDialog(
self,
"Illegal file name: %s.\n"
'File name must begin with "printer."' % path,
"Illegal file name",
wx.OK + wx.ICON_ERROR,
)
dlg.ShowModal()
dlg.Destroy()
return False
@ -256,8 +288,12 @@ class PrinterPanel(wx.Panel):
try:
self.printer.saveConfigFile(path, values)
except:
dlg = wx.MessageDialog(self, "Unable to write to file %s." % path,
"File error", wx.OK + wx.ICON_ERROR)
dlg = wx.MessageDialog(
self,
"Unable to write to file %s." % path,
"File error",
wx.OK + wx.ICON_ERROR,
)
dlg.ShowModal()
dlg.Destroy()
return False

View File

@ -1,4 +1,3 @@
protectedFiles = [
"board.3drag.h",
"board.gen3.h",
@ -16,5 +15,5 @@ protectedFiles = [
"board.teensy-v2.0.h",
"board.teensy++-v2.0.h",
"printer.mendel.h",
"printer.wolfstrap.h"
"printer.wolfstrap.h",
]

View File

@ -1,4 +1,3 @@
import wx
@ -6,10 +5,13 @@ class SensorList(wx.ListCtrl):
def __init__(self, parent, font):
self.parent = parent
self.currentItem = None
wx.ListCtrl.__init__(self, parent, wx.ID_ANY,
wx.ListCtrl.__init__(
self,
parent,
wx.ID_ANY,
size=(105 + 105 + 55 + 280 + 4, 100),
style = wx.LC_REPORT | wx.LC_VIRTUAL |
wx.LC_HRULES | wx.LC_VRULES)
style=wx.LC_REPORT | wx.LC_VIRTUAL | wx.LC_HRULES | wx.LC_VRULES,
)
self.SetFont(font)

View File

@ -16,16 +16,23 @@ class SensorsPage(wx.Panel, Page):
self.font = font
self.id = idPg
self.sensorTypeKeys = {'TT_MAX6675': 'TEMP_MAX6675',
'TT_THERMISTOR': 'TEMP_THERMISTOR',
'TT_AD595': 'TEMP_AD595', 'TT_PT100': 'TEMP_PT100',
'TT_INTERCOM': 'TEMP_INTERCOM',
'TT_MCP3008': 'TEMP_MCP3008'}
self.labels = {'TEMP_MAX6675': "MAX6675", 'TEMP_THERMISTOR': "Thermistor",
'TEMP_AD595': "AD595", 'TEMP_PT100': "PT100",
'TEMP_INTERCOM': "Intercom",
'TEMP_MCP3008': 'MCP3008',
'MCP3008_SELECT_PIN': "MCP3008 CS Pin:"}
self.sensorTypeKeys = {
"TT_MAX6675": "TEMP_MAX6675",
"TT_THERMISTOR": "TEMP_THERMISTOR",
"TT_AD595": "TEMP_AD595",
"TT_PT100": "TEMP_PT100",
"TT_INTERCOM": "TEMP_INTERCOM",
"TT_MCP3008": "TEMP_MCP3008",
}
self.labels = {
"TEMP_MAX6675": "MAX6675",
"TEMP_THERMISTOR": "Thermistor",
"TEMP_AD595": "AD595",
"TEMP_PT100": "PT100",
"TEMP_INTERCOM": "Intercom",
"TEMP_MCP3008": "MCP3008",
"MCP3008_SELECT_PIN": "MCP3008 CS Pin:",
}
self.validPins = pinNames
labelWidth = 120
@ -65,8 +72,9 @@ class SensorsPage(wx.Panel, Page):
self.bDelete.Enable(False)
self.Bind(wx.EVT_BUTTON, self.doDelete, self.bDelete)
bsz.Add(self.bDelete)
self.bDelete.SetToolTip("Remove the selected temperature sensor "
"from the configuration.")
self.bDelete.SetToolTip(
"Remove the selected temperature sensor " "from the configuration."
)
sz.Add(bsz, pos=(1, 3))
@ -119,9 +127,18 @@ class SensorsPage(wx.Panel, Page):
else:
params = s[3]
dlg = AddSensorDlg(self, nm, self.validPins, self.heatersPage, self.font,
name = s[0], stype = s[1], pin = s[2],
params = params, modify = True)
dlg = AddSensorDlg(
self,
nm,
self.validPins,
self.heatersPage,
self.font,
name=s[0],
stype=s[1],
pin=s[2],
params=params,
modify=True,
)
rc = dlg.ShowModal()
if rc == wx.ID_OK:
tt = dlg.getValues()
@ -169,16 +186,16 @@ class SensorsPage(wx.Panel, Page):
def validateTable(self):
self.lb.setTableValidity(True)
self.setFieldValidity('SENSORLIST', True)
self.setFieldValidity("SENSORLIST", True)
for i in range(len(self.sensors)):
if self.sensors[i][2] not in self.validPins:
self.lb.setRowValidity(i, False)
self.setFieldValidity('SENSORLIST', False)
self.setFieldValidity("SENSORLIST", False)
def setHelpText(self, ht):
Page.setHelpText(self, ht)
k = 'DEFINE_TEMP_SENSOR'
k = "DEFINE_TEMP_SENSOR"
if k in ht.keys():
self.bAdd.SetToolTip(ht[k])

View File

@ -24,8 +24,8 @@ class Settings:
self.port = "/dev/ttyACM0"
self.uploadspeed = 38400
self.t0 = 25;
self.r1 = 0;
self.t0 = 25
self.r1 = 0
self.numTemps = 25
self.maxAdc = 1023
self.minAdc = 1
@ -45,13 +45,15 @@ class Settings:
else:
if not self.cfg.read(self.inifile):
if not self.cfg.read(os.path.join(self.folder, DEFAULT_INIFILE)):
print ("Neither of settings files %s or %s exist. Using default values."
% (INIFILE, DEFAULT_INIFILE))
print(
"Neither of settings files %s or %s exist. Using default values."
% (INIFILE, DEFAULT_INIFILE)
)
return False
if self.cfg.has_section(self.section):
for opt, value in self.cfg.items(self.section):
value = value.replace('\n', ' ')
value = value.replace("\n", " ")
if opt == "arduinodir":
self.arduinodir = value
elif opt == "cflags":
@ -99,7 +101,7 @@ class Settings:
"numtemps": str(self.numTemps),
"maxadc": str(self.maxAdc),
"minadc": str(self.minAdc),
"uploadspeed": str(self.uploadspeed)
"uploadspeed": str(self.uploadspeed),
}
def saveSettings(self, inifile=None):
@ -117,7 +119,7 @@ class Settings:
self.cfg.set(self.section, k, values[k])
try:
cfp = open(inifile, 'wb')
cfp = open(inifile, "wb")
except:
print("Unable to open settings file %s for writing." % inifile)
return False
@ -126,4 +128,3 @@ class Settings:
cfp.close()
return True

View File

@ -1,4 +1,3 @@
import wx
from configtool.data import BSIZESMALL, offsetTcLabel
@ -19,8 +18,7 @@ R1 = 12
class SettingsDlg(wx.Dialog):
def __init__(self, parent, settings):
wx.Dialog.__init__(self, parent, wx.ID_ANY, "Modify settings",
size = (500, 300))
wx.Dialog.__init__(self, parent, wx.ID_ANY, "Modify settings", size=(500, 300))
self.SetFont(settings.font)
self.settings = settings
@ -28,39 +26,50 @@ class SettingsDlg(wx.Dialog):
self.Bind(wx.EVT_CLOSE, self.onExit)
htArdDir = "Path to the Arduino IDE folder. Configtool will figure the " \
"details on where to find avr-gcc and avrdude inside there." \
htArdDir = (
"Path to the Arduino IDE folder. Configtool will figure the "
"details on where to find avr-gcc and avrdude inside there."
"\n\nIf empty, the system wide installed tools will be used."
htCFlags = "Flags passed into the avr-gcc compiler. These flags can " \
"have 3 different variables embedded within them:" \
"\n\n %F_CPU% will be replaced by the value of the CPU " \
"Clock Rate." \
"\n\n %CPU% will be replaced by the value of the CPU. " \
"\n\n %ALNAME% is the name of the source file being " \
"compiled with the .c extension replaced by .al.\n\n" \
"Note: the flag -save-temps=obj does not appear to be a " \
"valid flag for some compiler versions. Omit the \"=obj\", " \
)
htCFlags = (
"Flags passed into the avr-gcc compiler. These flags can "
"have 3 different variables embedded within them:"
"\n\n %F_CPU% will be replaced by the value of the CPU "
"Clock Rate."
"\n\n %CPU% will be replaced by the value of the CPU. "
"\n\n %ALNAME% is the name of the source file being "
"compiled with the .c extension replaced by .al.\n\n"
"Note: the flag -save-temps=obj does not appear to be a "
'valid flag for some compiler versions. Omit the "=obj", '
"omit the flag entirely, or simply ignore the related warnings."
)
htLDFlags = "Flags passed to avr-gcc to be passed on to the linker."
htObjCopy = "Flags passed to avr-objcopy."
htProgrammer = "The programmer type - passed to avrdude."
htProgramFlags = "Extra flags passed to avrdude."
htPort = "The port to which the controller is connected. Typically a " \
"path starting with /dev/... on Linux or Mac OS X, or some " \
htPort = (
"The port to which the controller is connected. Typically a "
"path starting with /dev/... on Linux or Mac OS X, or some "
"COM... on Windows."
)
htSpeed = "The baud rate with which to communicate with the bootloader."
htNumTemps = "The number of entries generated for the thermistor tables. " \
"Higher numbers slightly increase temperature reading " \
htNumTemps = (
"The number of entries generated for the thermistor tables. "
"Higher numbers slightly increase temperature reading "
"accuracy, but also cost binary size. Default is 25."
)
htMinAdc = "The minimum ADC value returned by the thermistor. Typically 0."
htMaxAdc = "The maximum ADC value returned by the thermistor. " \
htMaxAdc = (
"The maximum ADC value returned by the thermistor. "
"Typically 1023 (maximum of 10-bit ADCs)."
)
htT0 = "The T0 value used for thermistor table calculation. Typically 25."
htR1 = "The R1 value used for thermistor table calculation. Typically 0."
# This table MUST be in the same order as the constants defined at
# the top of this file.
self.fields = [["Arduino Directory", settings.arduinodir, htArdDir],
self.fields = [
["Arduino Directory", settings.arduinodir, htArdDir],
["C Compiler Flags", settings.cflags, htCFlags],
["LD Flags", settings.ldflags, htLDFlags],
["Object Copy Flags", settings.objcopyflags, htObjCopy],
@ -72,7 +81,8 @@ class SettingsDlg(wx.Dialog):
["Minimum ADC value", settings.minAdc, htMinAdc],
["Maximum ADC value", settings.maxAdc, htMaxAdc],
["T0", settings.t0, htT0],
["R1", settings.r1, htR1]]
["R1", settings.r1, htR1],
]
self.teList = []
@ -85,8 +95,9 @@ class SettingsDlg(wx.Dialog):
labelWidth = 140
for f in self.fields:
lsz = wx.BoxSizer(wx.HORIZONTAL)
t = wx.StaticText(self, wx.ID_ANY, f[0], size = (labelWidth, -1),
style = wx.ALIGN_RIGHT)
t = wx.StaticText(
self, wx.ID_ANY, f[0], size=(labelWidth, -1), style=wx.ALIGN_RIGHT
)
t.SetFont(settings.font)
lsz.Add(t, 1, wx.TOP, offsetTcLabel)
@ -171,11 +182,14 @@ class SettingsDlg(wx.Dialog):
if not self.modified:
return True
dlg = wx.MessageDialog(self, "Are you sure you want to " + msg + "?\n"
dlg = wx.MessageDialog(
self,
"Are you sure you want to " + msg + "?\n"
"There are changes to your settings that "
"will be lost.",
"Changes pending",
wx.YES_NO | wx.NO_DEFAULT | wx.ICON_INFORMATION)
wx.YES_NO | wx.NO_DEFAULT | wx.ICON_INFORMATION,
)
rc = dlg.ShowModal()
dlg.Destroy()

View File

@ -10,8 +10,12 @@ class SHThermistor:
self.paramsOK = True
try:
T0 = t0 + 273.15; T1 = t1 + 273.15; T2 = t2 + 273.15
a0 = log(r0); a1 = log(r1); a2 = log(r2)
T0 = t0 + 273.15
T1 = t1 + 273.15
T2 = t2 + 273.15
a0 = log(r0)
a1 = log(r1)
a2 = log(r2)
z = a0 - a1
y = a0 - a2
x = 1 / T0 - 1 / T1
@ -40,7 +44,7 @@ class SHThermistor:
def temp(self, adc):
r = self.adcInv(adc)
t = (1.0 / (self.A + self.B * log(r) + self.C * (log(r) ** 3))) - 273.15;
t = (1.0 / (self.A + self.B * log(r) + self.C * (log(r) ** 3))) - 273.15
return t
def adc(self, r):
@ -49,6 +53,7 @@ class SHThermistor:
def adcInv(self, adc):
return (self.rp * adc) / (1023.0 - adc)
class BetaThermistor:
def __init__(self, r0, t0, beta, r1, r2, vadc):
self.paramsOK = True
@ -71,7 +76,7 @@ class BetaThermistor:
def temp(self, adc):
v = adc * self.vadc / 1024
if (self.vs - v):
if self.vs - v:
r = self.rs * v / (self.vs - v)
else:
r = self.r0 * 10

View File

@ -1,4 +1,3 @@
# Define thermistor presets. These can either be defined to use the
# beta argorithm by specifying 4 parameters:
# R0, beta, Rp, Vadc
@ -7,12 +6,12 @@
# Rp, T0, R0, T1, R1, T2, R2
#
thermistorPresets = {
"RS 10K": ['10000', '3480', '1600', '5.0'],
"RRRF 10K": ['10000', '3964', '1600', '5.0'],
"ATC Semitec 104GT-2": ['100000', '4267', '4700', '5.0'],
"EPCOS 100K (B57560G1104F)": ['100000', '4092', '4700', '5.0'],
"EPCOS 100K (B5754061104)": ['100000', '4066', '4700', '5.0'],
"EPCOS 100K (B57560G104F)": ['100000', '4036', '4700', '5.0'],
"Honeywell 100K": ['100000', '3974', '4700', '5.0'],
"RRRF 100K": ['100000', '3960', '4700', '5.0'],
"RS 10K": ["10000", "3480", "1600", "5.0"],
"RRRF 10K": ["10000", "3964", "1600", "5.0"],
"ATC Semitec 104GT-2": ["100000", "4267", "4700", "5.0"],
"EPCOS 100K (B57560G1104F)": ["100000", "4092", "4700", "5.0"],
"EPCOS 100K (B5754061104)": ["100000", "4066", "4700", "5.0"],
"EPCOS 100K (B57560G104F)": ["100000", "4036", "4700", "5.0"],
"Honeywell 100K": ["100000", "3974", "4700", "5.0"],
"RRRF 100K": ["100000", "3960", "4700", "5.0"],
}

View File

@ -9,7 +9,7 @@ class ThermistorTableFile:
self.error = False
fn = os.path.join(folder, "thermistortable.h")
try:
self.fp = open(fn, 'wb')
self.fp = open(fn, "wb")
except:
self.error = True
@ -19,6 +19,7 @@ class ThermistorTableFile:
def output(self, text):
self.fp.write(text + "\n")
def paramsEqual(p1, p2):
for i in range(len(p1)):
if p1[i] != p2[i]:
@ -26,6 +27,7 @@ def paramsEqual(p1, p2):
return True
def generateTempTables(sensors, settings):
ofp = ThermistorTableFile(settings.folder)
if ofp.error:
@ -44,26 +46,26 @@ def generateTempTables(sensors, settings):
if not found:
tl.append((sensor[3], [sensor[0].upper()]))
ofp.output("");
ofp.output("/**");
ofp.output(" This file was autogenerated when saving a board with");
ofp.output(" Teacup's Configtool. You can edit it, but the next board");
ofp.output(" save operation in Configtool will overwrite it without");
ofp.output(" asking.");
ofp.output("*/");
ofp.output("");
ofp.output("")
ofp.output("/**")
ofp.output(" This file was autogenerated when saving a board with")
ofp.output(" Teacup's Configtool. You can edit it, but the next board")
ofp.output(" save operation in Configtool will overwrite it without")
ofp.output(" asking.")
ofp.output("*/")
ofp.output("")
ofp.output("#define NUMTABLES %d" % len(tl))
ofp.output("#define NUMTEMPS %d" % N)
ofp.output("");
ofp.output("")
for i in range(len(tl)):
for n in tl[i][1]:
ofp.output("#define THERMISTOR_%s %d" % (n, i))
ofp.output("");
ofp.output("")
if len(tl) == 0 or N == 0:
ofp.close();
ofp.close()
return True
ofp.output("const uint16_t PROGMEM temptable[NUMTABLES][NUMTEMPS][3] = {")
@ -83,20 +85,24 @@ def generateTempTables(sensors, settings):
ofp.close()
return True
def BetaTable(ofp, params, names, settings, finalTable):
r0 = params[0]
beta = params[1]
r2 = params[2]
vadc = float(params[3])
ofp.output(" // %s temp table using Beta algorithm with parameters:" %
(", ".join(names)))
ofp.output((" // R0 = %s, T0 = %s, R1 = %s, R2 = %s, beta = %s, "
"maxadc = %s") % (r0, settings.t0, settings.r1, r2,
beta, settings.maxAdc))
ofp.output(
" // %s temp table using Beta algorithm with parameters:" % (", ".join(names))
)
ofp.output(
(" // R0 = %s, T0 = %s, R1 = %s, R2 = %s, beta = %s, " "maxadc = %s")
% (r0, settings.t0, settings.r1, r2, beta, settings.maxAdc)
)
ofp.output(" {")
thrm = BetaThermistor(int(r0), int(settings.t0), int(beta), int(settings.r1),
int(r2), vadc)
thrm = BetaThermistor(
int(r0), int(settings.t0), int(beta), int(settings.r1), int(r2), vadc
)
hiadc = thrm.setting(0)[0]
N = int(settings.numTemps)
@ -122,9 +128,20 @@ def BetaTable(ofp, params, names, settings, finalTable):
c = ","
delta = (t - thrm.temp(prev)) / (prev - i) if i != prev else 0
ostr = (" {%4s, %5s, %5s}%s // %4d C, %6.0f ohms, %0.3f V,"
" %0.2f mW, m = %6.3f") % (i, int(t * 4), int(delta * 4 * 256), c,
int(t), int(round(r)), vTherm, ptherm * 1000, delta)
ostr = (
" {%4s, %5s, %5s}%s // %4d C, %6.0f ohms, %0.3f V,"
" %0.2f mW, m = %6.3f"
) % (
i,
int(t * 4),
int(delta * 4 * 256),
c,
int(t),
int(round(r)),
vTherm,
ptherm * 1000,
delta,
)
ofp.output(ostr)
prev = i
@ -133,18 +150,27 @@ def BetaTable(ofp, params, names, settings, finalTable):
else:
ofp.output(" },")
def SteinhartHartTable(ofp, params, names, settings, finalTable):
ofp.output((" // %s temp table using Steinhart-Hart algorithm with "
"parameters:") % (", ".join(names)))
ofp.output((" // Rp = %s, T0 = %s, R0 = %s, T1 = %s, R1 = %s, "
"T2 = %s, R2 = %s") %
(params[0], params[1], params[2], params[3], params[4], params[5],
params[6]))
ofp.output(
(" // %s temp table using Steinhart-Hart algorithm with " "parameters:")
% (", ".join(names))
)
ofp.output(
(" // Rp = %s, T0 = %s, R0 = %s, T1 = %s, R1 = %s, " "T2 = %s, R2 = %s")
% (params[0], params[1], params[2], params[3], params[4], params[5], params[6])
)
ofp.output(" {")
thrm = SHThermistor(int(params[0]), float(params[1]), int(params[2]),
float(params[3]), int(params[4]), float(params[5]),
int(params[6]))
thrm = SHThermistor(
int(params[0]),
float(params[1]),
int(params[2]),
float(params[3]),
int(params[4]),
float(params[5]),
int(params[6]),
)
hiadc = thrm.setting(0)[0]
N = int(settings.numTemps)
@ -166,9 +192,10 @@ def SteinhartHartTable(ofp, params, names, settings, finalTable):
c = ","
delta = (t - thrm.temp(prev)) / (prev - i) if i != prev else 0
ofp.output(" {%4d, %5d, %5d}%s // %4d C, %6d ohms, m = %6.3f" %
(i, int(t * 4), int(delta * 4 * 256), c, int(t), int(round(r)),
delta))
ofp.output(
" {%4d, %5d, %5d}%s // %4d C, %6d ohms, m = %6.3f"
% (i, int(t * 4), int(delta * 4 * 256), c, int(t), int(round(r)), delta)
)
prev = i
if finalTable:
@ -176,6 +203,7 @@ def SteinhartHartTable(ofp, params, names, settings, finalTable):
else:
ofp.output(" },")
def optimizeTempTable(thrm, length, hiadc):
# This is a variation of the Ramer-Douglas-Peucker algorithm, see
@ -197,8 +225,13 @@ def optimizeTempTable(thrm, length, hiadc):
# Limit ADC range to 0C to 500C.
MIN_TEMP = 0
MAX_TEMP = 500
actual = dict([(adc, actual[adc]) for adc in actual
if actual[adc] <= MAX_TEMP and actual[adc] >= MIN_TEMP])
actual = dict(
[
(adc, actual[adc])
for adc in actual
if actual[adc] <= MAX_TEMP and actual[adc] >= MIN_TEMP
]
)
# Build a lookup table starting with the extremes.
A = min(actual)
@ -206,8 +239,14 @@ def optimizeTempTable(thrm, length, hiadc):
lookup = dict([(x, actual[x]) for x in [A, B]])
error = dict({})
while len(lookup) < length:
error.update(dict([(x, abs(actual[x] - LinearTableEstimate(lookup, x)))
for x in range(A + 1, B)]))
error.update(
dict(
[
(x, abs(actual[x] - LinearTableEstimate(lookup, x)))
for x in range(A + 1, B)
]
)
)
# Correct the most-wrong lookup value.
next = max(error, key=error.get)
@ -219,12 +258,15 @@ def optimizeTempTable(thrm, length, hiadc):
return sorted(lookup)
def after(lookup, value):
return min([x for x in lookup.keys() if x > value])
def before(lookup, value):
return max([x for x in lookup.keys() if x < value])
def LinearTableEstimate(lookup, value):
if value in lookup:
return lookup[value]

View File

@ -43,8 +43,10 @@ from math import *
import sys
import getopt
class Thermistor:
"Class to do the thermistor maths"
def __init__(self, r0, t0, beta, r1, r2, vcc, vadc):
self.r0 = r0 # stated resistance, e.g. 10K
self.t0 = t0 + 273.15 # temperature at stated resistance, e.g. 25C
@ -63,7 +65,7 @@ class Thermistor:
def temp(self, adc):
"Convert ADC reading into a temperature in Celcius"
v = adc * self.vadc / 1024 # convert the 10 bit ADC value to a voltage
if (self.vs - v): # can be zero due to accuracy limitations
if self.vs - v: # can be zero due to accuracy limitations
r = self.rs * v / (self.vs - v) # resistance of thermistor
else:
r = self.r0 * 10 # dummy value
@ -75,34 +77,54 @@ class Thermistor:
def resistance(self, t):
"Convert a temperature into a thermistor resistance"
return self.r0 * exp(self.beta * (1 / (t + 273.15) - 1 / self.t0)) # resistance of the thermistor
return self.r0 * exp(
self.beta * (1 / (t + 273.15) - 1 / self.t0)
) # resistance of the thermistor
def setting(self, t):
"Convert a temperature into a ADC value"
r = self.r0 * exp(self.beta * (1 / (t + 273.15) - 1 / self.t0)) # resistance of the thermistor
r = self.r0 * exp(
self.beta * (1 / (t + 273.15) - 1 / self.t0)
) # resistance of the thermistor
v = self.vs * r / (self.rs + r) # the voltage at the potential divider
return round(v / self.vadc * 1024) # the ADC reading
def main(argv):
r0 = 10000;
t0 = 25;
beta = 3947;
r1 = 680;
r2 = 1600;
num_temps = int(20);
max_adc = int(1023);
min_adc = int(1);
r0 = 10000
t0 = 25
beta = 3947
r1 = 680
r2 = 1600
num_temps = int(20)
max_adc = int(1023)
min_adc = int(1)
vadc = 5.0
vcc = 5.0
mult = 4
table = False
try:
opts, args = getopt.getopt(argv, "h", ["help", "r0=", "t0=", "beta=", "r1=",
"r2=", "max-adc=", "min-adc=",
"num-temps=", "vcc=", "vadc=",
"multiplier=", "table"])
opts, args = getopt.getopt(
argv,
"h",
[
"help",
"r0=",
"t0=",
"beta=",
"r1=",
"r2=",
"max-adc=",
"min-adc=",
"num-temps=",
"vcc=",
"vadc=",
"multiplier=",
"table",
],
)
except getopt.GetoptError:
usage()
sys.exit(2)
@ -136,14 +158,14 @@ def main(argv):
elif opt == "--table":
table = True
if r1:
max_adc = int(1023. * r1 / (r1 + r2))
max_adc = int(1023.0 * r1 / (r1 + r2))
else:
max_adc = 1023
increment = int((max_adc-min_adc)/(num_temps-1));
increment = int((max_adc - min_adc) / (num_temps - 1))
t = Thermistor(r0, t0, beta, r1, r2, vcc, vadc)
adcs = range(min_adc, max_adc, increment);
adcs = range(min_adc, max_adc, increment)
adcs.append(max_adc)
# adcs = [1, 20, 25, 30, 35, 40, 45, 50, 60, 70, 80, 90, 100, 110, 130, 150, 190, 220, 250, 300]
@ -157,21 +179,44 @@ def main(argv):
if int(t.temp(adcs[i]) * mult) < 0:
adcs[i] -= 1
break
print("// Thermistor lookup table for RepRap Temperature Sensor Boards (http://reprap.org/wiki/Temperature_Sensor_2_0)")
print("// Made with createTemperatureLookup.py (https://github.com/traumflug/Teacup_Firmware/blob/master/createTemperatureLookup.py)")
print("// (patched per https://github.com/drf5n/Teacup_Firmware/blob/Gen7/createTemperatureLookup.py)")
print(
"// Thermistor lookup table for RepRap Temperature Sensor Boards (http://reprap.org/wiki/Temperature_Sensor_2_0)"
)
print(
"// Made with createTemperatureLookup.py (https://github.com/traumflug/Teacup_Firmware/blob/master/createTemperatureLookup.py)"
)
print(
"// (patched per https://github.com/drf5n/Teacup_Firmware/blob/Gen7/createTemperatureLookup.py)"
)
print("// default thermistor lookup table")
print("// You may be able to improve the accuracy of this table in various ways.")
print("// 1. Measure the actual resistance of the resistor. It's \"nominally\" 4.7K, but that's ± 5%.")
print("// 2. Measure the actual beta of your thermistor:http://reprap.org/wiki/MeasuringThermistorBeta")
print("// 3. Generate more table entries than you need, then trim down the ones in uninteresting ranges.")
print("// In either case you'll have to regenerate this table, which requires python, which is difficult to install on windows.")
print("// Since you'll have to do some testing to determine the correct temperature for your application anyway, you")
print("// may decide that the effort isn't worth it. Who cares if it's reporting the \"right\" temperature as long as it's")
print(
"// 1. Measure the actual resistance of the resistor. It's \"nominally\" 4.7K, but that's ± 5%."
)
print(
"// 2. Measure the actual beta of your thermistor:http://reprap.org/wiki/MeasuringThermistorBeta"
)
print(
"// 3. Generate more table entries than you need, then trim down the ones in uninteresting ranges."
)
print(
"// In either case you'll have to regenerate this table, which requires python, which is difficult to install on windows."
)
print(
"// Since you'll have to do some testing to determine the correct temperature for your application anyway, you"
)
print(
"// may decide that the effort isn't worth it. Who cares if it's reporting the \"right\" temperature as long as it's"
)
print("// keeping the temperature steady enough to print, right?")
print("// Temp*%s table from https://github.com/drf5n/Teacup_Firmware/blob/Gen7/createTemperatureLookup.py" %mult)
print("// ./createTemperatureLookup.py --r0=%s --t0=%s --r1=%s --r2=%s --beta=%s --max-adc=%s --min-adc=%s --multiplier=%s --vadc=%s" % (
r0, t0, r1, r2, beta, max_adc, min_adc, mult, vadc))
print(
"// Temp*%s table from https://github.com/drf5n/Teacup_Firmware/blob/Gen7/createTemperatureLookup.py"
% mult
)
print(
"// ./createTemperatureLookup.py --r0=%s --t0=%s --r1=%s --r2=%s --beta=%s --max-adc=%s --min-adc=%s --multiplier=%s --vadc=%s"
% (r0, t0, r1, r2, beta, max_adc, min_adc, mult, vadc)
)
print("// r0: %s" % (r0))
print("// t0: %s" % (t0))
print("// r1: %s (parallel with rTherm)" % (r1))
@ -179,16 +224,30 @@ def main(argv):
print("// beta: %s" % (beta))
print("// min adc: %s at %s V" % (min_adc, min_adc * t.vadc / 1024))
print("// max adc: %s at %s V" % (max_adc, max_adc * t.vadc / 1024))
print("// ADC counts from {min} to {max} by {x}".format(min=min_adc, max=max_adc, x=increment))
print(
"// ADC counts from {min} to {max} by {x}".format(
min=min_adc, max=max_adc, x=increment
)
)
if table == True:
print("// #define NUMTABLES 1 // These three lines open the temptable[NUMTABLES]... array")
print(
"// #define NUMTABLES 1 // These three lines open the temptable[NUMTABLES]... array"
)
print("// #define NUMTEMPS %s // ... " % (len(adcs)))
print("// uint16_t temptable[NUMTABLES][NUMTEMPS][2] PROGMEM = { // ...")
print("{ //" + " Table 0 chunk for B={b}, R0={r0}, R1={r1}, R2={r2}, Vref={v}".format(par="{",b=beta,r0=r0,r1=r1,r2=r2,v=vadc))
print(
"{ //"
+ " Table 0 chunk for B={b}, R0={r0}, R1={r1}, R2={r2}, Vref={v}".format(
par="{", b=beta, r0=r0, r1=r1, r2=r2, v=vadc
)
)
else:
print("#define NUMTEMPS %s " % (len(adcs)))
print("const uint16_t temptable[NUMTEMPS][2] PROGMEM = {")
print("// {ADC, temp*%s }, // temp Rtherm Vtherm resolution power" % (mult))
print(
"// {ADC, temp*%s }, // temp Rtherm Vtherm resolution power"
% (mult)
)
counter = 0
for adc in adcs:
@ -197,17 +256,33 @@ def main(argv):
resistance = t.resistance(t.temp(adc))
vTherm = adc * t.vadc / 1024
ptherm = vTherm * vTherm / resistance
resolution = ( t.temp(adc-1)-t.temp(adc) if adc>1 else t.temp(adc) -t.temp(adc+1))
sep = (',' if counter != len(adcs) else ' ')
print(" {%4s, %6s}%s // %7.2f C, %7.0f Ohm, %0.3f V, %0.2f C/count, %0.2fmW" % (adc, int(t.temp(adc)*mult), sep,degC, resistance,vTherm,resolution,ptherm*1000))
resolution = (
t.temp(adc - 1) - t.temp(adc) if adc > 1 else t.temp(adc) - t.temp(adc + 1)
)
sep = "," if counter != len(adcs) else " "
print(
" {%4s, %6s}%s // %7.2f C, %7.0f Ohm, %0.3f V, %0.2f C/count, %0.2fmW"
% (
adc,
int(t.temp(adc) * mult),
sep,
degC,
resistance,
vTherm,
resolution,
ptherm * 1000,
)
)
if table == False:
print("};")
else:
print('}, // remove comma for last table chunk')
print("}, // remove comma for last table chunk")
print("// }; // Closure for the temptable[NUMTABLES] array")
def usage():
print(__doc__)
if __name__ == "__main__":
main(sys.argv[1:])

View File

@ -9,21 +9,28 @@
# Translate a point relative to some origin
from __future__ import print_function
def translate(point, origin):
return tuple([a - b for a, b in zip(point, origin)])
# Given two points in 3d space, define a vector
def vector(p1, p2):
return tuple([b - a for a, b in zip(p1, p2)])
# Given two vectors in a plane, find the normal vector
def normal(u, v):
# A normal vector is the cross-product of two coplanar vectors
return tuple([
return tuple(
[
u[1] * v[2] - u[2] * v[1],
u[2] * v[0] - u[0] * v[2],
u[0]*v[1] - u[1]*v[0]
])
u[0] * v[1] - u[1] * v[0],
]
)
def plane_from_three_points(P, Q, R):
u = vector(P, Q)
@ -40,6 +47,7 @@ def plane_from_three_points(P, Q, R):
return (A, B, C, K)
# find the Z offset for any x,y
# z = -(Ax + By + K) / C
def calcz(x, y, plane, translation=(0, 0, 0)):
@ -56,13 +64,13 @@ def validate(plane, point):
def verify_plane(points):
print(' ', '\n '.join([str(p) for p in points]))
print(" ", "\n ".join([str(p) for p in points]))
plane = plane_from_three_points(*points)
print('Plane coordinates: ', plane)
print("Plane coordinates: ", plane)
if plane[2] == 0:
print(' Error: points are colinear')
print(" Error: points are colinear")
return
valid = True
@ -73,26 +81,20 @@ def verify_plane(points):
print("Validation:", "Failed" if not valid else "Passed")
samples = [
# canonical example
[(1, -2, 0), (4, -2, -2), (4, 1, 4)],
# three colinear points (infinite planes)
[(2, 2, 2), (4, 4, 4), (10, 10, 10)],
# Extreme tilt example in mm
[(57, 123, -5), (200, 0, 35), (0, 207, 2)],
# Some more examples in um
[(0, 0, 1300), (200000, 200000, 3500), (0, 150000, -1000)],
[(20000, 20000, -300), (220000, 120000, -1700), (120000, 220000, -700)],
# some example in tenths of mm
[(200, 200, -300), (2200, 1200, -1700), (1200, 2200, -700)],
[(20000, 20000, -300), (220000, 120000, -1700), (120000, 220000, -700)],
[ (200, 200, -300 ), (2200, 1200, -1700 ), (1200, 2200, -700 ) ]
[(200, 200, -300), (2200, 1200, -1700), (1200, 2200, -700)],
]
for points in samples:

View File

@ -13,18 +13,19 @@ pseudo_print = list()
# define STEPS_PER_M_Y 40000
# define STEPS_PER_M_Z 320000
def parse_stepper_position(line):
s_line = line.split()
X = float(s_line[1]) / 40. # X-axis
Y = float(s_line[2]) / 40. # Y-axis
Z = float(s_line[3]) / 320. # Z-axis
X = float(s_line[1]) / 40.0 # X-axis
Y = float(s_line[2]) / 40.0 # Y-axis
Z = float(s_line[3]) / 320.0 # Z-axis
return X, Y, Z
def parse_m114_position(line):
s_line = line.split(',')
s_line = line.split(",")
X = float(s_line[0][4:])
Y = float(s_line[1][2:])
@ -32,7 +33,8 @@ def parse_m114_position(line):
return X, Y, Z
with open(in_file, 'r') as file:
with open(in_file, "r") as file:
start_with_line = 50
found_m114 = False
@ -43,11 +45,11 @@ with open(in_file, 'r') as file:
found_m114 = False
x1, y1, z1 = parse_m114_position(line)
x = x2 - x1
diff_list.append('{}\t\t\t{}\t\t\t{}\t\t\t{}\n'.format(i, x1, x2, x))
pseudo_print.append('{}\t\t\t{}\t\t\t{}\n'.format(x2, y2, z2))
diff_list.append("{}\t\t\t{}\t\t\t{}\t\t\t{}\n".format(i, x1, x2, x))
pseudo_print.append("{}\t\t\t{}\t\t\t{}\n".format(x2, y2, z2))
if line[0] == '#':
if line[2:6] == 'M114':
if line[0] == "#":
if line[2:6] == "M114":
found_m114 = True
# find the line with stepping positions before the M114
# print(linecache.getline(in_file, i))
@ -57,8 +59,8 @@ with open(in_file, 'r') as file:
break
x2, y2, z2 = parse_stepper_position(pre_m114_line)
with open(out_file, 'w') as file:
with open(out_file, "w") as file:
file.writelines(diff_list)
with open(pp_file, 'w') as file:
with open(pp_file, "w") as file:
file.writelines(pseudo_print)