From 61462a50a4cf4684045cc19a4476d6d29ef141ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Thu, 15 Nov 2012 19:08:59 +0100 Subject: [PATCH] simple solder selection --- oven_control.cpp | 84 ++++++++++++++++------------------- oven_control.h | 32 ++++++------- qtplot.py => reflowctl_gui.py | 50 ++++++++++++++++----- 3 files changed, 93 insertions(+), 73 deletions(-) rename qtplot.py => reflowctl_gui.py (87%) mode change 100644 => 100755 diff --git a/oven_control.cpp b/oven_control.cpp index 8a5c204..c76eb1a 100644 --- a/oven_control.cpp +++ b/oven_control.cpp @@ -3,6 +3,8 @@ #include #include "profile.h" + + //Pin assignments for SainSmart LCD Keypad Shield LiquidCrystal lcd(8, 9, 4, 5, 6, 7); DFR_Key keypad; @@ -16,13 +18,6 @@ OvenCtl::OvenCtl() { actual_dt = 0.f; - // timestamps of event beginnings/ends - Ts_time_start = 0; - Ts_time_end = 0; - Tl_time_start = 0; - Tl_time_end = 0; - Tp_time_start = 0; - Tp_time_end = 0; // thermostat set_min = 0; @@ -30,7 +25,7 @@ OvenCtl::OvenCtl() { set_dt_min = 0; set_dt_max = 0; - op_state = OP_CONFIG; + oven_mode = OM_CONFIG; profile_state = START_STATE; error_condition = 0; is_oven_heating = false; @@ -43,14 +38,10 @@ OvenCtl::OvenCtl() { lcd.begin(16, 2); } -void OvenCtl::reset() { - digitalWrite(7, LOW); -} - void OvenCtl::send_state() { Serial.write(time & 0xff); - Serial.write((time>>8) & 0xff); + Serial.write((time >> 8) & 0xff); Serial.write(temperature & 0xff); Serial.write((temperature >> 8) & 0xff); Serial.write(last_temperature & 0xff); @@ -80,15 +71,22 @@ void OvenCtl::recv_config() { } -void OvenCtl::dispatch_input_config(int cmd) { - if (cmd == 255) - send_config(); - else if (cmd == 254) - recv_config(); - else if (cmd == 250) - reset(); - else if (cmd == 253) - ; +void OvenCtl::dispatch_remote_cmd(COMMAND cmd) { + switch (cmd) { + case SEND_CONFIG: + send_config(); + break; + case RECV_CONFIG: + recv_config(); + break; + case SEND_STATE: + recv_config(); + break; + case RECV_STEPS: + break; + default: + ; + } } void OvenCtl::handle_stand_alone_state() { @@ -112,18 +110,20 @@ void OvenCtl::handle_remote_state() { * */ void OvenCtl::loop() { - int cmd = -1; +// int cmd = -1; - switch (op_state) { - case OP_CONFIG: + switch (oven_mode) { + case OM_CONFIG: // if (profile.handle_config_state()) // set_start_state(); break; - case OP_STAND_ALONE: + case OM_CALIBRATION: + break; + case OM_STAND_ALONE: // if (profile.handle_config_state()) // set_start_state(); // break; - case OP_REMOTE: + case OM_REMOTE: // if (profile.handle_config_state()) // set_start_state(); break; @@ -133,24 +133,13 @@ void OvenCtl::loop() { // set_error_state(); // } - if (Serial.available() > 0) { - cmd = Serial.read(); - if (cmd == 255) - send_config(); - else if (cmd == 254) - send_state(); - else if (cmd == 253) - recv_config(); - else if (cmd == 252) - reset(); + // else if (cmd == 251) // set_start_state(); - } - - + control_oven(); - if (profile_state > 0) { + if (oven_mode != OM_CONFIG) { print_status(); delay(1000); } @@ -214,12 +203,15 @@ void OvenCtl::print_status() { void OvenCtl::control_oven() { - if (temperature <= set_min + actual_hysteresis && !is_oven_heating) { - is_oven_heating = true; -// Serial.println("Oven turned on"); + if (is_oven_heating) { + if (temperature >= set_min + actual_hysteresis) { + is_oven_heating = false; + } } - else if (temperature >= set_min + actual_hysteresis && is_oven_heating) { - is_oven_heating = false; + else { + if (temperature <= set_min + actual_hysteresis) { + is_oven_heating = true; + } } } diff --git a/oven_control.h b/oven_control.h index 862b9bd..cb66b6e 100644 --- a/oven_control.h +++ b/oven_control.h @@ -7,10 +7,18 @@ #define OP_STAND_ALONE 1 #define OP_REMOTE 2*/ -enum OP_STATE { - OP_CONFIG, - OP_STAND_ALONE, - OP_REMOTE +enum OVEN_MODE { + OM_CONFIG, + OM_CALIBRATION, + OM_STAND_ALONE, + OM_REMOTE +}; + +enum COMMAND { + SEND_CONFIG, + RECV_CONFIG, + SEND_STATE, + RECV_STEPS }; #define E_DT_MIN 1 // temperature dt too small @@ -55,19 +63,13 @@ public: // void set_config_state(); private: + // system time, timestamps and temperatures from sensors int time; // profile seconds int temperature; // actual oven temp int last_temperature; // last oven temp float actual_dt; // actual difference from last to actual temperatur - // timestamps of event beginnings/ends - int Ts_time_start; - int Ts_time_end; - int Tl_time_start; - int Tl_time_end; - int Tp_time_start; - int Tp_time_end; // thermostat float set_min; @@ -84,7 +86,7 @@ private: // state machine unsigned int error_condition; - OP_STATE op_state; + OVEN_MODE oven_mode; PROFILE_STATE profile_state; boolean is_oven_heating; @@ -127,13 +129,11 @@ private: // void check_Tp_duration_min(); // void check_Tp_duration_max(); + // commands void send_state(); void send_config(); - void reset(); - void recv_config(); - - void dispatch_input_config(int); + void dispatch_remote_cmd(COMMAND cmd); }; #endif diff --git a/qtplot.py b/reflowctl_gui.py old mode 100644 new mode 100755 similarity index 87% rename from qtplot.py rename to reflowctl_gui.py index 68ff9cf..4079fa1 --- a/qtplot.py +++ b/reflowctl_gui.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +#!/usr/bin/python import sys, os, random @@ -31,6 +32,7 @@ class Solder(object): self.psteps = [] self.durations = dict() self.rates = dict() + self.name = None #start = self.add_state("start", 25) #ps = self.add_state("preheat start", 150) @@ -47,6 +49,12 @@ class Solder(object): #self.add_rate((pe, tal), 1) #self.add_rate((tal, end), -2) + def __unicode__(self): + return unicode(self.name) + + def __str__(self): + return self.name + def add_state(self, name, temp): s = State(name, temp) @@ -131,6 +139,7 @@ class Solder(object): xmltree = etree.parse(filename) root = xmltree.getroot() s = Solder() + s.name = root[0].attrib["name"] for state in root[0].findall("state"): s.add_state(state.attrib["name"], int(state.attrib["temperature"])) for duration in root[0].findall("duration"): @@ -147,7 +156,21 @@ class Solder(object): return s +class SolderListModel(QtCore.QAbstractListModel): + def __init__(self, parent=None, *args): + """ datain: a list where each item is a row + """ + super(SolderListModel, self).__init__(parent, *args) + self.listdata = [Solder.unpack(os.path.join("solder_types", p)) for p in os.listdir("solder_types")] + def rowCount(self, parent=QtCore.QModelIndex()): + return len(self.listdata) + + def data(self, index, role): + if index.isValid() and role == QtCore.Qt.DisplayRole: + return QtCore.QVariant(self.listdata[index.row()].name) + else: + return QtCore.QVariant() class MyDynamicMplCanvas(FigureCanvas): """A canvas that updates itself every second with a new plot.""" @@ -293,23 +316,32 @@ class ApplicationWindow(QtGui.QMainWindow): self.help_menu.addAction('&About', self.about) self.main_widget = QtGui.QWidget(self) + self.profile_widget = QtGui.QWidget(self) self.dpi = 100 - #pl = QtGui.QVBoxLayout(self.main_widget) - #self.p + pl = QtGui.QHBoxLayout(self.profile_widget) + self.solder_model = SolderListModel(self) + self.solder_view = QtGui.QListView() + self.solder_view.setModel(self.solder_model) + + self.connect(self.solder_view, QtCore.SIGNAL("clicked(QModelIndex)"), self.solder_selected) + pl.addWidget(self.solder_view) l = QtGui.QVBoxLayout(self.main_widget) - #sc = MyStaticMplCanvas(self.main_widget, width=5, height=4, dpi=100) self.dc = MyDynamicMplCanvas(self.main_widget, width=5, height=4, dpi=self.dpi) - #l.addWidget(sc) - l.addWidget(self.dc) + l.addWidget(self.profile_widget, 1) + l.addWidget(self.dc, 10) self.main_widget.setFocus() self.setCentralWidget(self.main_widget) self.statusBar().showMessage("All hail matplotlib!", 2000) + def solder_selected(self, index): + if index.isValid(): + self.dc.solder = self.solder_model.listdata[index.row()] + def save_plot(self): file_choices = "PNG (*.png)|*.png" @@ -326,13 +358,9 @@ class ApplicationWindow(QtGui.QMainWindow): def about(self): QtGui.QMessageBox.about(self, "About %s" % progname, u"""%(prog)s version %(version)s -Copyright \N{COPYRIGHT SIGN} 2005 Florent Rougon, 2006 Darren Dale +Copyright \N{COPYRIGHT SIGN} 2012 Stefan Kögl -This program is a simple example of a Qt4 application embedding matplotlib -canvases. - -It may be used and modified with no restriction; raw copies as well as -modified versions may be distributed without limitation.""" +reflowctl frontend""" % {"prog": progname, "version": progversion})