Skip to content

Commit 03a7c94

Browse files
feat(qe): Improve SerialPortTool
Close #1900 Signed-off-by: IfGuestInDream <ifGuestInDream@163.com>
1 parent 82c4a11 commit 03a7c94

File tree

4 files changed

+124
-107
lines changed

4 files changed

+124
-107
lines changed

core/src/main/java/com/tlcsdm/core/util/DependencyInfo.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,10 @@ private static class SingletonInstance {
232232
"https://javaluator.fathzer.com", "Apache License, Version 2.0",
233233
"https://www.apache.org/licenses/LICENSE-2.0"),
234234

235+
new Dependency("com.fazecast", "jSerialComm", "2.11.0", false,
236+
"https://fazecast.github.io/jSerialComm", "GNU LGPL",
237+
"https://www.gnu.org/licenses/lgpl-3.0.html"),
238+
235239
new Dependency("com.github.gino0631", "icns-core", "1.2", false,
236240
"https://github.com/gino0631/icns", "GNU LGPL",
237241
"https://opensource.org/license/lgpl-3-0"));

qe/src/main/java/com/tlcsdm/qe/tools/SerialPortTool.java

Lines changed: 111 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,16 @@
2727

2828
package com.tlcsdm.qe.tools;
2929

30-
import cn.hutool.core.util.StrUtil;
3130
import cn.hutool.log.StaticLog;
3231
import com.fazecast.jSerialComm.SerialPort;
3332
import com.fazecast.jSerialComm.SerialPortDataListener;
3433
import com.fazecast.jSerialComm.SerialPortEvent;
35-
import com.tlcsdm.core.javafx.control.FxTextInput;
3634
import com.tlcsdm.core.javafx.helper.LayoutHelper;
3735
import com.tlcsdm.core.javafx.util.Config;
3836
import com.tlcsdm.core.javafx.util.FxmlUtil;
3937
import com.tlcsdm.qe.QeSample;
4038
import com.tlcsdm.qe.util.I18nUtils;
39+
import javafx.animation.Timeline;
4140
import javafx.event.ActionEvent;
4241
import javafx.fxml.FXML;
4342
import javafx.fxml.FXMLLoader;
@@ -57,11 +56,8 @@
5756

5857
import java.net.URL;
5958
import java.util.ArrayList;
60-
import java.util.HashMap;
6159
import java.util.List;
62-
import java.util.Map;
6360
import java.util.ResourceBundle;
64-
import java.util.Timer;
6561
import java.util.stream.Collectors;
6662

6763
/**
@@ -72,28 +68,41 @@
7268
*/
7369
public class SerialPortTool extends QeSample implements Initializable {
7470

71+
//串口名称选择器
7572
@FXML
7673
private ComboBox<SerialPort> serPort;
74+
//波特率选择器
7775
@FXML
7876
private ComboBox<String> serPortSpeed;
77+
//检验位选择器
7978
@FXML
8079
private ComboBox<String> serPortCheckBit;
80+
//数据位选择器
8181
@FXML
8282
private ComboBox<String> serPortDataBit;
83+
//停止位选择器
8384
@FXML
8485
private ComboBox<String> serPortStopBit;
86+
//流控选择器
87+
@FXML
88+
private ComboBox<String> serFlowControl;
8589
@FXML
8690
private Button serPortOpenBtn;
91+
//16进制接收显示开关
8792
@FXML
8893
private CheckBox recvShowHex;
94+
//显示时间
8995
@FXML
9096
private CheckBox recvShowTime;
97+
//暂停接收
9198
@FXML
9299
private CheckBox recvStopShow;
93100
@FXML
94101
private Button recvClear;
102+
//16进制发送开关
95103
@FXML
96104
private CheckBox sendHex;
105+
//定时发送开关
97106
@FXML
98107
private CheckBox sendCycle;
99108
@FXML
@@ -113,7 +122,8 @@ public class SerialPortTool extends QeSample implements Initializable {
113122
@FXML
114123
private Button sendBtn;
115124

116-
private Timer t;
125+
private final Timeline circularSending = new Timeline();
126+
private volatile long waitTime = 1000;
117127

118128
@Override
119129
public Node getPanel(Stage stage) {
@@ -152,6 +162,11 @@ public String getSampleVersion() {
152162
return "1.0.1";
153163
}
154164

165+
@Override
166+
public boolean hasControlPanel() {
167+
return false;
168+
}
169+
155170
@Override
156171
public void initialize(URL location, ResourceBundle resources) {
157172
initializeUserDataBindings();
@@ -161,33 +176,6 @@ public void initialize(URL location, ResourceBundle resources) {
161176
initializeUI();
162177
}
163178

164-
@Override
165-
public Node getControlPanel() {
166-
String content = """
167-
{note}
168-
{enableMunge}: {enableMungeDesc}
169-
{enableVerbose}: {enableVerboseDesc}
170-
{enableOptimizations}: {enableOptimizationsDesc}
171-
{enablePreserveAllSemiColons}: {enablePreserveAllSemiColonsDesc}
172-
{enableLinebreakpos}: {enableLinebreakposDesc}
173-
""";
174-
175-
Map<String, String> map = new HashMap<>(32);
176-
map.put("note", I18nUtils.get("qe.tool.compress.description.note"));
177-
map.put("enableMunge", I18nUtils.get("qe.tool.compress.check.enableMunge"));
178-
map.put("enableVerbose", I18nUtils.get("qe.tool.compress.check.enableVerbose"));
179-
map.put("enableOptimizations", I18nUtils.get("qe.tool.compress.check.enableOptimizations"));
180-
map.put("enablePreserveAllSemiColons", I18nUtils.get("qe.tool.compress.check.enablePreserveAllSemiColons"));
181-
map.put("enableLinebreakpos", I18nUtils.get("qe.tool.compress.check.enableLinebreakpos"));
182-
map.put("enableMungeDesc", I18nUtils.get("qe.tool.compress.check.enableMunge.description"));
183-
map.put("enableVerboseDesc", I18nUtils.get("qe.tool.compress.check.enableVerbose.description"));
184-
map.put("enableOptimizationsDesc", I18nUtils.get("qe.tool.compress.check.enableOptimizations.description"));
185-
map.put("enablePreserveAllSemiColonsDesc",
186-
I18nUtils.get("qe.tool.compress.check.enablePreserveAllSemiColons.description"));
187-
map.put("enableLinebreakposDesc", I18nUtils.get("qe.tool.compress.check.enableLinebreakpos.description"));
188-
return FxTextInput.textArea(StrUtil.format(content, map));
189-
}
190-
191179
/**
192180
* 设置刷新串口信息按钮被点击时的事件处理器: 重新获取本机当前串口信息
193181
*/
@@ -242,6 +230,12 @@ public ImageView getSampleImageIcon() {
242230
// https://github.com/yiaoBang/SerialPortToolFX/blob/master/src/main/java/com/yiaoBang/serialPortToolFX/view/SerialPortView.java
243231

244232
public void initializeUI() {
233+
//无限循环发送
234+
circularSending.setCycleCount(Timeline.INDEFINITE);
235+
236+
// recvCount
237+
// sendNumber.textProperty().bind(viewModel.getSEND_LONG_PROPERTY().asString());
238+
// receiveNumber.textProperty().bind(viewModel.getRECEIVE_LONG_PROPERTY().asString());
245239

246240
// // 初始化常用波特率列表
247241
// baudRateComboBox.getItems().addAll("9600", "4800", "2400", "1200");
@@ -308,6 +302,28 @@ public void initializeUI() {
308302
}
309303
serPortStopBit.setValue("1");
310304

305+
//流控
306+
// String[] flowControl = new String[]{
307+
// "100", "300", "600", "1200"
308+
// };
309+
// for (String s : speeds) {
310+
// serPortSpeed.getItems().add(s);
311+
// }
312+
// serPortSpeed.setValue("9600");
313+
//serFlowControl.getItems().addAll(SerialPort.FLOW_CONTROL_DISABLED);
314+
315+
//循环发送的等待时间(ms)
316+
sendCycleRap.textProperty().addListener((o, oldValue, newValue) -> {
317+
try {
318+
waitTime = Integer.parseInt(newValue);
319+
if (waitTime < 1) {
320+
waitTime = 1;
321+
}
322+
} catch (NumberFormatException e) {
323+
sendCycleRap.setText(oldValue);
324+
}
325+
});
326+
311327
serPortOpenBtn.setOnAction((ActionEvent event) -> {
312328
SerialPort serialPort = serPort.getSelectionModel().getSelectedItem();
313329
if (serialPort == null) {
@@ -322,6 +338,8 @@ public void initializeUI() {
322338
serPortDataBit.setDisable(false);
323339
serPortStopBit.setDisable(false);
324340
} else {
341+
serialPortDataListener listener = new serialPortDataListener();
342+
serialPort.addDataListener(listener);
325343
serialPort.openPort();
326344
//SerialPort.ONE_STOP_BIT
327345
//SerialPort.NO_PARITY
@@ -333,7 +351,7 @@ public void initializeUI() {
333351
serialPort.setFlowControl(SerialPort.FLOW_CONTROL_DISABLED);
334352
serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_BLOCKING | SerialPort.TIMEOUT_WRITE_BLOCKING,
335353
1000, 1000);
336-
//UsartRXEven();
354+
337355
serPortOpenBtn.setText("关闭");
338356
serPort.setDisable(true);
339357
serPortSpeed.setDisable(true);
@@ -342,48 +360,52 @@ public void initializeUI() {
342360
serPortStopBit.setDisable(true);
343361
}
344362
});
345-
//
346-
// sendBtn.setOnAction(event -> {
347-
// if (null == serialPort || (!serialPort.isOpened())) {
348-
// // new AlertBox().display("错误", "请先打开串口");
349-
// return;
350-
// }
351-
// try {
352-
// if (sendHex.isSelected()) {
353-
// serialPort.writeBytes(hexStringToBytes(sendTextAear.getText()));
354-
// sendCount.setText(String.valueOf(
355-
// (Integer.parseInt(sendCount.getText()) + hexStringToBytes(sendTextAear.getText()).length)));
356-
// } else {
357-
// serialPort.writeBytes(sendTextAear.getText().getBytes());
358-
// sendCount.setText(String.valueOf(
359-
// (Integer.parseInt(sendCount.getText()) + sendTextAear.getText().getBytes().length)));
360-
// }
361-
//
362-
// } catch (Exception e) {
363-
// //new AlertBox().display("发送数据错误", e.getMessage());
364-
// }
365-
// });
366-
//
367-
// recvClear.setOnAction(event -> {
368-
// recvTextAear.setText("");
369-
// });
370-
// sendHex.setOnAction(event -> {
371-
// if (!sendHex.isSelected())
372-
// try {
373-
// sendTextAear.setText(new String(hexStringToBytes(sendTextAear.getText())));
374-
// } catch (Exception e) {
375-
// //new AlertBox().display("非法16进制字符", e.getMessage());
376-
// }
377-
// else
378-
// sendTextAear.setText(bytesToHexString(sendTextAear.getText().getBytes()));
379-
// });
380-
// sendClear.setOnAction(event -> {
381-
// sendTextAear.setText("");
382-
// });
383-
// CountReset.setOnAction(event -> {
384-
// sendCount.setText("0");
385-
// recvCount.setText("0");
386-
// });
363+
364+
sendBtn.setOnAction(event -> {
365+
SerialPort serialPort = serPort.getSelectionModel().getSelectedItem();
366+
if (null == serialPort || (!serialPort.isOpen())) {
367+
// new AlertBox().display("错误", "请先打开串口");
368+
return;
369+
}
370+
try {
371+
if (sendHex.isSelected()) {
372+
byte[] bytes = hexStringToBytes(sendTextAear.getText());
373+
serialPort.writeBytes(bytes, bytes.length);
374+
sendCount.setText(String.valueOf(
375+
(Integer.parseInt(sendCount.getText()) + hexStringToBytes(sendTextAear.getText()).length)));
376+
} else {
377+
byte[] bytes = sendTextAear.getText().getBytes();
378+
serialPort.writeBytes(bytes, bytes.length);
379+
sendCount.setText(String.valueOf(
380+
(Integer.parseInt(sendCount.getText()) + sendTextAear.getText().getBytes().length)));
381+
}
382+
383+
} catch (Exception e) {
384+
//new AlertBox().display("发送数据错误", e.getMessage());
385+
}
386+
});
387+
388+
recvClear.setOnAction(event -> {
389+
recvTextAear.setText("");
390+
});
391+
sendHex.setOnAction(event -> {
392+
if (!sendHex.isSelected())
393+
try {
394+
sendTextAear.setText(new String(hexStringToBytes(sendTextAear.getText())));
395+
} catch (Exception e) {
396+
//new AlertBox().display("非法16进制字符", e.getMessage());
397+
}
398+
else {
399+
sendTextAear.setText(bytesToHexString(sendTextAear.getText().getBytes()));
400+
}
401+
});
402+
sendClear.setOnAction(event -> {
403+
sendTextAear.setText("");
404+
});
405+
CountReset.setOnAction(event -> {
406+
sendCount.setText("0");
407+
recvCount.setText("0");
408+
});
387409
// sendCycle.setOnAction(event -> {
388410
// if (null == serialPort || (!serialPort.isOpened())) {
389411
// //new AlertBox().display("错误", "请先打开串口");
@@ -462,6 +484,17 @@ public void initializeUserDataBindings() {
462484
// userData.put("txtCssLinebreakpos", txtCssLinebreakpos);
463485
}
464486

487+
@Override
488+
public void dispose() {
489+
SerialPort serialPort = serPort.getSelectionModel().getSelectedItem();
490+
if (serialPort == null) {
491+
return;
492+
}
493+
if (serialPort.isOpen()) {
494+
serialPort.closePort();
495+
}
496+
}
497+
465498
/**
466499
* 获得当前计算机所有的串口的名称列表
467500
*
@@ -511,30 +544,6 @@ private SerialPort openPort(String portName, int baudRate) {
511544
return serialPort;
512545
}
513546

514-
/**
515-
* 关闭串口
516-
*
517-
* @param serialPort 待关闭的串口对象
518-
*/
519-
private void closePort(SerialPort serialPort) {
520-
if (serialPort != null && serialPort.isOpen()) {
521-
serialPort.closePort();
522-
}
523-
}
524-
525-
/**
526-
* 往串口发送数据
527-
*
528-
* @param serialPort 串口对象
529-
* @param content 待发送数据
530-
*/
531-
private void sendToPort(SerialPort serialPort, byte[] content) {
532-
if (!serialPort.isOpen()) {
533-
return;
534-
}
535-
serialPort.writeBytes(content, content.length);
536-
}
537-
538547
/**
539548
* 从串口读取数据
540549
*
@@ -573,8 +582,9 @@ public int getListeningEvents() {
573582
public void serialEvent(SerialPortEvent event) {
574583
byte[] newData = event.getReceivedData();
575584
System.out.println("Received data of size: " + newData.length);
576-
for (int i = 0; i < newData.length; ++i)
585+
for (int i = 0; i < newData.length; ++i) {
577586
System.out.print((char) newData[i]);
587+
}
578588
System.out.println("\n");
579589
}
580590
}

qe/src/main/java/com/tlcsdm/qe/util/QeConstant.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public class QeConstant {
9696
*/
9797
public static final List<String> DEPENDENCY_LIST = List.of("poi", "freemarker", "dom4j", "java-diff-utils",
9898
"richtextfx", "thumbnailator", "jackson", "yuicompressor", "teenyhttpd", "image4j", "commons-imaging",
99-
"icns-core", "preferencesfx");
99+
"icns-core", "preferencesfx", "jSerialComm");
100100

101101
private QeConstant() {
102102
}

qe/src/main/resources/com/tlcsdm/qe/fxml/serialPortTool.fxml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,20 +62,23 @@
6262
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
6363
</rowConstraints>
6464
<children>
65-
<Label text="串口号:" GridPane.columnIndex="0"/>
65+
<Label text="串口号" GridPane.columnIndex="0"/>
6666
<ComboBox fx:id="serPort" prefWidth="150.0" GridPane.columnIndex="1"/>
67-
<Label text="波特率:" GridPane.rowIndex="1"/>
67+
<Label text="波特率" GridPane.rowIndex="1"/>
6868
<ComboBox fx:id="serPortSpeed" editable="true" prefWidth="150.0"
6969
GridPane.columnIndex="1" GridPane.rowIndex="1"/>
70-
<Label text="检验位:" GridPane.rowIndex="2"/>
70+
<Label text="检验位" GridPane.rowIndex="2"/>
7171
<ComboBox fx:id="serPortCheckBit" prefWidth="150.0" GridPane.columnIndex="1"
7272
GridPane.rowIndex="2"/>
73-
<Label text="数据位:" GridPane.rowIndex="3"/>
73+
<Label text="数据位" GridPane.rowIndex="3"/>
7474
<ComboBox fx:id="serPortDataBit" prefWidth="150.0" GridPane.columnIndex="1"
7575
GridPane.rowIndex="3"/>
76-
<Label text="停止位:" GridPane.rowIndex="4"/>
76+
<Label text="停止位" GridPane.rowIndex="4"/>
7777
<ComboBox fx:id="serPortStopBit" prefWidth="150.0" GridPane.columnIndex="1"
7878
GridPane.rowIndex="4"/>
79+
<Label text="流控" GridPane.rowIndex="5"/>
80+
<ComboBox fx:id="serFlowControl" prefWidth="150.0" GridPane.columnIndex="1"
81+
GridPane.rowIndex="5"/>
7982
</children>
8083
</GridPane>
8184
<Button fx:id="serPortOpenBtn" minWidth="130" mnemonicParsing="false"

0 commit comments

Comments
 (0)