|
@@ -66,27 +66,117 @@ scale, buffering and interpreting the response, and signaling new measurements.
|
66
|
66
|
|
67
|
67
|
#include "3rdparty/qextserialport/src/qextserialport.h"
|
68
|
68
|
|
69
|
|
-class SerialScale : public QObject
|
|
69
|
+class SerialScale : public QextSerialPort
|
70
|
70
|
{
|
71
|
71
|
Q_OBJECT
|
72
|
72
|
public:
|
73
|
|
- SerialScale();
|
74
|
|
- ~SerialScale();
|
|
73
|
+ SerialScale(const QString &port);
|
75
|
74
|
public slots:
|
76
|
|
- void setPort(const QString &port);
|
77
|
|
- void setBaudRate(BaudRateType baud);
|
78
|
|
- void setDataBits(DataBitsType data);
|
79
|
|
- void setParity(ParityType parity);
|
80
|
|
- void setStopBits(StopBitsType stop);
|
81
|
|
- void setFlowControl(FlowType flow);
|
82
|
|
- void open();
|
83
|
75
|
void tare();
|
84
|
76
|
void weigh();
|
|
77
|
+ signals:
|
|
78
|
+ void newMeasurement(double weight, Units::Unit unit);
|
85
|
79
|
private slots:
|
86
|
80
|
void dataAvailable();
|
87
|
81
|
private:
|
88
|
|
- QextSerialPort *port;
|
89
|
82
|
QByteArray responseBuffer;
|
90
|
83
|
};
|
91
|
84
|
|
92
|
|
-#endif
|
|
85
|
+#endif
|
|
86
|
+
|
|
87
|
+@ The constructor tells the port that this should be event driven and connects
|
|
88
|
+a signal to buffer data..
|
|
89
|
+
|
|
90
|
+@(scale.cpp@>=
|
|
91
|
+#include "scale.h"
|
|
92
|
+
|
|
93
|
+SerialScale::SerialScale(const QString &port) :
|
|
94
|
+ QextSerialPort(port, QextSerialPort::EventDriven)
|
|
95
|
+{
|
|
96
|
+ connect(this, SIGNAL(readyRead()), this, SLOT(dataAvailable()));
|
|
97
|
+}
|
|
98
|
+
|
|
99
|
+@ The |dataAvailable| method handles buffering incoming data and processing
|
|
100
|
+responses when they have come in. Serial port communications are likely to be
|
|
101
|
+very slow in comparison to everything else so it is likely that only one
|
|
102
|
+character will come in at a time.
|
|
103
|
+
|
|
104
|
+Note that this currently only understands single line output and a limited
|
|
105
|
+selection of units.
|
|
106
|
+
|
|
107
|
+@(scale.cpp@>=
|
|
108
|
+void SerialScale::dataAvailable()
|
|
109
|
+{
|
|
110
|
+ responseBuffer.append(readAll());
|
|
111
|
+ if(responseBuffer.contains("\x0D"))
|
|
112
|
+ {
|
|
113
|
+ if(responseBuffer.startsWith("!"))
|
|
114
|
+ {
|
|
115
|
+ responseBuffer.clear();
|
|
116
|
+ weigh();
|
|
117
|
+ }
|
|
118
|
+ else
|
|
119
|
+ {
|
|
120
|
+ @<Process weight measurement@>@;
|
|
121
|
+ responseBuffer.clear();
|
|
122
|
+ }
|
|
123
|
+ }
|
|
124
|
+}
|
|
125
|
+
|
|
126
|
+@ Each line of data consists of characters representing a number followed by a
|
|
127
|
+space followed by characters indicating a unit. This may be preceeded and
|
|
128
|
+followed by a variable amount of white space. To process a new measurement, we
|
|
129
|
+must remove the excess white space, split the number from the unit, convert the
|
|
130
|
+string representing the number to a numeric type, and determine which unit the
|
|
131
|
+measurement is in.
|
|
132
|
+
|
|
133
|
+\medskip
|
|
134
|
+
|
|
135
|
+\settabs 8 \columns
|
|
136
|
+\+&&&{\tt |"lb"|}&|Units::Pound|\cr
|
|
137
|
+\+&&&{\tt |"kg"|}&|Units::Kilogram|\cr
|
|
138
|
+\+&&&{\tt |"g"|}&|Units::Gram|\cr
|
|
139
|
+\+&&&{\tt |"oz"|}&|Units::Ounce|\cr
|
|
140
|
+
|
|
141
|
+\smallskip
|
|
142
|
+
|
|
143
|
+\centerline{Table \secno: Unit Strings and Representative Unit Enumeration}
|
|
144
|
+
|
|
145
|
+\medskip
|
|
146
|
+
|
|
147
|
+@<Process weight measurement@>=
|
|
148
|
+QStringList responseParts = QString(responseBuffer.simplified()).split(' ');
|
|
149
|
+double weight = responseParts[0].toDouble();
|
|
150
|
+Units::Unit unit = Units::Unitless;
|
|
151
|
+if(responseParts[1] == "lb")
|
|
152
|
+{
|
|
153
|
+ unit = Units::Pound;
|
|
154
|
+}
|
|
155
|
+else if(responseParts[1] == "kg")
|
|
156
|
+{
|
|
157
|
+ unit = Units::Kilogram;
|
|
158
|
+}
|
|
159
|
+else if(responseParts[1] == "g")
|
|
160
|
+{
|
|
161
|
+ unit = Units::gram;
|
|
162
|
+}
|
|
163
|
+else if(responseParts[1] == "oz")
|
|
164
|
+{
|
|
165
|
+ unit = Units::ounce;
|
|
166
|
+}
|
|
167
|
+emit newMeasurement(weight, unit);
|
|
168
|
+
|
|
169
|
+@ Two methods are used to send commands to the scale. I am unsure of how well
|
|
170
|
+standardized remote key operation of scales are. The class may need to be
|
|
171
|
+extended to support more devices.
|
|
172
|
+
|
|
173
|
+@(scale.cpp@>=
|
|
174
|
+void SerialScale::tare()
|
|
175
|
+{
|
|
176
|
+ write("!KT\x0D");
|
|
177
|
+}
|
|
178
|
+
|
|
179
|
+void SerialScale::weight()
|
|
180
|
+{
|
|
181
|
+ write("!KP\x0D");
|
|
182
|
+}
|