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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,4 +1,3 @@
import wx import wx
from configtool.page import Page from configtool.page import Page
@ -10,35 +9,34 @@ class CpuPage(wx.Panel, Page):
self.parent = parent self.parent = parent
self.id = idPg 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.clocks = []
self.processors = [] self.processors = []
sz = wx.GridBagSizer() sz = wx.GridBagSizer()
sz.Add((20, 40), pos=(0, 0)) 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)) ch = self.addChoice(k, self.clocks, 0, 100, self.onChoice, size=(140, -1))
sz.Add(ch, pos=(1, 1)) sz.Add(ch, pos=(1, 1))
sz.Add((100, 10), pos=(1, 2)) sz.Add((100, 10), pos=(1, 2))
k = 'CPU' k = "CPU"
ch = self.addChoice(k, self.processors, 0, 100, self.onChoice, ch = self.addChoice(k, self.processors, 0, 100, self.onChoice, size=(140, -1))
size = (140, -1))
sz.Add(ch, pos=(1, 3)) sz.Add(ch, pos=(1, 3))
self.SetSizer(sz) self.SetSizer(sz)
self.enableAll(False) self.enableAll(False)
def setCandidateProcessors(self, plist): def setCandidateProcessors(self, plist):
k = 'CPU' k = "CPU"
self.choices[k].Clear() self.choices[k].Clear()
for p in plist: for p in plist:
self.choices[k].Append(p) self.choices[k].Append(p)
self.processors = plist self.processors = plist
def setCandidateClocks(self, clist): def setCandidateClocks(self, clist):
k = 'F_CPU' k = "F_CPU"
self.choices[k].Clear() self.choices[k].Clear()
for c in clist: for c in clist:
self.choices[k].Append(c) self.choices[k].Append(c)
@ -48,6 +46,6 @@ class CpuPage(wx.Panel, Page):
Page.insertValues(self, cfgValues) Page.insertValues(self, cfgValues)
if len(self.clocks) > 0: 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: 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 import re
from sys import platform from sys import platform
supportedCPUs = ['ATmega168', 'ATmega328P', 'ATmega644', 'ATmega644P', supportedCPUs = [
'ATmega644PA', 'ATmega1280', 'ATmega1284', 'ATmega1284P', "ATmega168",
'ATmega2560', 'AT90USB1286'] "ATmega328P",
"ATmega644",
"ATmega644P",
"ATmega644PA",
"ATmega1280",
"ATmega1284",
"ATmega1284P",
"ATmega2560",
"AT90USB1286",
]
# Note: this is a kludge and works for ATmegas, only. Smaller ATmegas have a # 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 # 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 # have entirely different names. The right way would be to fetch pin
# names from the compiler environment and/or header files. # names from the compiler environment and/or header files.
pinNames = ["AIO%d" % x for x in range(16)] + \ pinNames = (
["DIO%d" % x for x in range(64)] + \ ["AIO%d" % x for x in range(16)]
["P%c%d" % (c, x) for c in range(ord('A'), ord('L') + 1) \ + ["DIO%d" % x for x in range(64)]
for x in range(8)] + ["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", sensorTypes = {
'AD595': "TT_AD595", 'PT100': "TT_PT100", "MAX6675": "TT_MAX6675",
'Intercom': "TT_INTERCOM", 'MCP3008': "TT_MCP3008"} "Thermistor": "TT_THERMISTOR",
"AD595": "TT_AD595",
"PT100": "TT_PT100",
"Intercom": "TT_INTERCOM",
"MCP3008": "TT_MCP3008",
}
BSIZE = (100, 60) BSIZE = (100, 60)
BSIZESMALL = (90, 30) BSIZESMALL = (90, 30)
@ -35,13 +49,13 @@ TYPE_GENERAL = 0
TYPE_FLOAT = 1 TYPE_FLOAT = 1
reDefQSm = re.compile("\s*#define\s+(\S+)\s+(.*)") 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*\*/") reFloatAttr = re.compile("/\*\s*float\s*\*/")
reDefine = re.compile("\s*#define\s+(\w+)\s+(\S+)") reDefine = re.compile("\s*#define\s+(\w+)\s+(\S+)")
reDefineBL = 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\\([^)]*\\))") reDefTS = re.compile("\s*(DEFINE_TEMP_SENSOR\\([^)]*\\))")
reDefHT = re.compile("\s*(DEFINE_HEATER\\([^)]*\\))") reDefHT = re.compile("\s*(DEFINE_HEATER\\([^)]*\\))")
reDefTT = re.compile("^\s*//\s*TEMP_TABLE\s+(\S+)\s+(\\(.*\\))") 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 and reHeater4 deprecated, for compatibility with old config files only.
reHeater3 = re.compile(".*\\(\s*(\w+)\s*,\s*(\w+)\s*,\s*(\w+)\s*\\)") 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*\\)") 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*\\)") reHeater5 = re.compile(
reTempTable4 = re.compile(".*\\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d*.?\d*)\s*\\)") ".*\\(\s*(\w+)\s*,\s*(\w+)\s*,\s*(\w+)\s*,\s*(\w+)\s*,\s*(\w+)\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*\\)") )
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?$") reInteger = re.compile("^\d+U?L?$")
reFloat = re.compile("^\d+(\.\d*)?$") reFloat = re.compile("^\d+(\.\d*)?$")

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -43,8 +43,10 @@ from math import *
import sys import sys
import getopt import getopt
class Thermistor: class Thermistor:
"Class to do the thermistor maths" "Class to do the thermistor maths"
def __init__(self, r0, t0, beta, r1, r2, vcc, vadc): def __init__(self, r0, t0, beta, r1, r2, vcc, vadc):
self.r0 = r0 # stated resistance, e.g. 10K self.r0 = r0 # stated resistance, e.g. 10K
self.t0 = t0 + 273.15 # temperature at stated resistance, e.g. 25C self.t0 = t0 + 273.15 # temperature at stated resistance, e.g. 25C
@ -63,7 +65,7 @@ class Thermistor:
def temp(self, adc): def temp(self, adc):
"Convert ADC reading into a temperature in Celcius" "Convert ADC reading into a temperature in Celcius"
v = adc * self.vadc / 1024 # convert the 10 bit ADC value to a voltage 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 r = self.rs * v / (self.vs - v) # resistance of thermistor
else: else:
r = self.r0 * 10 # dummy value r = self.r0 * 10 # dummy value
@ -75,34 +77,54 @@ class Thermistor:
def resistance(self, t): def resistance(self, t):
"Convert a temperature into a thermistor resistance" "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): def setting(self, t):
"Convert a temperature into a ADC value" "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 v = self.vs * r / (self.rs + r) # the voltage at the potential divider
return round(v / self.vadc * 1024) # the ADC reading return round(v / self.vadc * 1024) # the ADC reading
def main(argv): def main(argv):
r0 = 10000; r0 = 10000
t0 = 25; t0 = 25
beta = 3947; beta = 3947
r1 = 680; r1 = 680
r2 = 1600; r2 = 1600
num_temps = int(20); num_temps = int(20)
max_adc = int(1023); max_adc = int(1023)
min_adc = int(1); min_adc = int(1)
vadc = 5.0 vadc = 5.0
vcc = 5.0 vcc = 5.0
mult = 4 mult = 4
table = False table = False
try: try:
opts, args = getopt.getopt(argv, "h", ["help", "r0=", "t0=", "beta=", "r1=", opts, args = getopt.getopt(
"r2=", "max-adc=", "min-adc=", argv,
"num-temps=", "vcc=", "vadc=", "h",
"multiplier=", "table"]) [
"help",
"r0=",
"t0=",
"beta=",
"r1=",
"r2=",
"max-adc=",
"min-adc=",
"num-temps=",
"vcc=",
"vadc=",
"multiplier=",
"table",
],
)
except getopt.GetoptError: except getopt.GetoptError:
usage() usage()
sys.exit(2) sys.exit(2)
@ -136,14 +158,14 @@ def main(argv):
elif opt == "--table": elif opt == "--table":
table = True table = True
if r1: if r1:
max_adc = int(1023. * r1 / (r1 + r2)) max_adc = int(1023.0 * r1 / (r1 + r2))
else: else:
max_adc = 1023 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) 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.append(max_adc)
# adcs = [1, 20, 25, 30, 35, 40, 45, 50, 60, 70, 80, 90, 100, 110, 130, 150, 190, 220, 250, 300] # 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: if int(t.temp(adcs[i]) * mult) < 0:
adcs[i] -= 1 adcs[i] -= 1
break break
print("// Thermistor lookup table for RepRap Temperature Sensor Boards (http://reprap.org/wiki/Temperature_Sensor_2_0)") print(
print("// Made with createTemperatureLookup.py (https://github.com/traumflug/Teacup_Firmware/blob/master/createTemperatureLookup.py)") "// Thermistor lookup table for RepRap Temperature Sensor Boards (http://reprap.org/wiki/Temperature_Sensor_2_0)"
print("// (patched per https://github.com/drf5n/Teacup_Firmware/blob/Gen7/createTemperatureLookup.py)") )
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("// default thermistor lookup table")
print("// You may be able to improve the accuracy of this table in various ways.") 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(
print("// 2. Measure the actual beta of your thermistor:http://reprap.org/wiki/MeasuringThermistorBeta") "// 1. Measure the actual resistance of the resistor. It's \"nominally\" 4.7K, but that's ± 5%."
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(
print("// Since you'll have to do some testing to determine the correct temperature for your application anyway, you") "// 2. Measure the actual beta of your thermistor:http://reprap.org/wiki/MeasuringThermistorBeta"
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(
"// 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("// 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(
print("// ./createTemperatureLookup.py --r0=%s --t0=%s --r1=%s --r2=%s --beta=%s --max-adc=%s --min-adc=%s --multiplier=%s --vadc=%s" % ( "// Temp*%s table from https://github.com/drf5n/Teacup_Firmware/blob/Gen7/createTemperatureLookup.py"
r0, t0, r1, r2, beta, max_adc, min_adc, mult, vadc)) % 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("// r0: %s" % (r0))
print("// t0: %s" % (t0)) print("// t0: %s" % (t0))
print("// r1: %s (parallel with rTherm)" % (r1)) print("// r1: %s (parallel with rTherm)" % (r1))
@ -179,16 +224,30 @@ def main(argv):
print("// beta: %s" % (beta)) print("// beta: %s" % (beta))
print("// min adc: %s at %s V" % (min_adc, min_adc * t.vadc / 1024)) 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("// 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: 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("// #define NUMTEMPS %s // ... " % (len(adcs)))
print("// uint16_t temptable[NUMTABLES][NUMTEMPS][2] PROGMEM = { // ...") 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: else:
print("#define NUMTEMPS %s " % (len(adcs))) print("#define NUMTEMPS %s " % (len(adcs)))
print("const uint16_t temptable[NUMTEMPS][2] PROGMEM = {") 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 counter = 0
for adc in adcs: for adc in adcs:
@ -197,17 +256,33 @@ def main(argv):
resistance = t.resistance(t.temp(adc)) resistance = t.resistance(t.temp(adc))
vTherm = adc * t.vadc / 1024 vTherm = adc * t.vadc / 1024
ptherm = vTherm * vTherm / resistance ptherm = vTherm * vTherm / resistance
resolution = ( t.temp(adc-1)-t.temp(adc) if adc>1 else t.temp(adc) -t.temp(adc+1)) resolution = (
sep = (',' if counter != len(adcs) else ' ') t.temp(adc - 1) - t.temp(adc) if adc > 1 else t.temp(adc) - t.temp(adc + 1)
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)) )
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: if table == False:
print("};") print("};")
else: else:
print('}, // remove comma for last table chunk') print("}, // remove comma for last table chunk")
print("// }; // Closure for the temptable[NUMTABLES] array") print("// }; // Closure for the temptable[NUMTABLES] array")
def usage(): def usage():
print(__doc__) print(__doc__)
if __name__ == "__main__": if __name__ == "__main__":
main(sys.argv[1:]) main(sys.argv[1:])

View File

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

View File

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