// ÉùÃ÷°üÃû dell_system
|
package dell_system;
|
|
// µ¼Èë´®¿ÚͨÐÅ¿â
|
import com.fazecast.jSerialComm.SerialPort;
|
// µ¼Èë Java º¯Êýʽ½Ó¿Ú Consumer£¬ÓÃÓÚÊý¾Ý½ÓÊջص÷
|
import java.util.function.Consumer;
|
// µ¼Èë×Ö½ÚÊý×éÊä³öÁ÷
|
import java.io.ByteArrayOutputStream;
|
|
/**
|
* ´®¿Ú·þÎñÀà
|
* ¸ºÔ𴮿ڵĴò¿ª¡¢¹Ø±Õ¡¢Êý¾ÝÊÕ·¢
|
*/
|
public class SerialPortService {
|
|
// ´®¿Ú¶ÔÏó£¬ÓÃÓÚÓëÓ²¼þͨÐÅ
|
private SerialPort port;
|
// ±ê¼ÇÊÇ·ñÕýÔÚ²¶»ñÊý¾Ý£¨Ïß³ÌÔËÐÐÖУ©
|
private volatile boolean capturing = false;
|
// ±ê¼ÇÊÇ·ñÔÝÍ£½ÓÊÕÊý¾Ý
|
private volatile boolean paused = false;
|
|
// Êý¾Ý¶ÁÈ¡Ïß³Ì
|
private Thread readerThread;
|
|
/**
|
* ´ò¿ª´®¿Ú
|
* @param portName ´®¿ÚÃû³Æ£¨Èç COM3£©
|
* @param baud ²¨ÌØÂÊ£¨Èç 9600£©
|
* @return ÊÇ·ñ³É¹¦´ò¿ª
|
*/
|
public boolean open(String portName, int baud) {
|
// Èç¹û´®¿ÚÒÑ´ò¿ª£¬Ö±½Ó·µ»Ø³É¹¦
|
if (port != null && port.isOpen()) {
|
return true;
|
}
|
|
// ¸ù¾ÝÃû³Æ»ñÈ¡´®¿ÚʵÀý
|
port = SerialPort.getCommPort(portName);
|
// ÉèÖô®¿Ú²ÎÊý£º²¨ÌØÂÊ¡¢Êý¾Ýλ8¡¢Í£Ö¹Î»1¡¢ÎÞУÑéλ
|
port.setComPortParameters(baud, 8, 1, SerialPort.NO_PARITY);
|
// ÐÞ¸ÄΪ°ë×èÈûģʽ£¬¶Á³¬Ê±1ms
|
port.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 1, 0);
|
|
// ´ò¿ª´®¿Ú²¢·µ»Ø½á¹û
|
return port.openPort();
|
}
|
|
/**
|
* ¹Ø±Õ´®¿Ú
|
*/
|
public void close() {
|
// ÏÈÍ£Ö¹Êý¾Ý½ÓÊÕÏß³Ì
|
stopCapture();
|
// Èç¹û´®¿ÚÒÑ´ò¿ª£¬¹Ø±ÕËü
|
if (port != null && port.isOpen()) {
|
port.closePort();
|
}
|
// ÊÍ·Å´®¿ÚÒýÓÃ
|
port = null;
|
}
|
|
/**
|
* Æô¶¯Êý¾Ý½ÓÊÕÏß³Ì
|
* @param onReceived Êý¾Ý½ÓÊջص÷º¯Êý£¬ÊÕµ½Êý¾Ýʱµ÷ÓÃ
|
*/
|
public void startCapture(Consumer<byte[]> onReceived) {
|
if (capturing || port == null || !port.isOpen()) return;
|
capturing = true;
|
paused = false;
|
|
readerThread = new Thread(() -> {
|
// ´´½¨Êý¾Ý»º³åÇø
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
// ×îºóÊÕµ½Êý¾ÝµÄʱ¼ä´Á
|
long lastReceivedTime = 0;
|
// ¶ÁÈ¡»º³åÇø
|
byte[] readBuffer = new byte[200];
|
|
while (capturing && port.isOpen()) {
|
// ´¦ÀíÔÝͣ״̬
|
if (paused) {
|
buffer.reset(); // Çå¿ÕÀÛ»ýÊý¾Ý
|
// Çå¿Õ´®¿Ú½ÓÊÕ»º³åÇø£¨¶ÁÈ¡²¢¶ªÆú£©
|
int len;
|
do {
|
len = port.readBytes(readBuffer, readBuffer.length);
|
} while (len > 0);
|
// ½µµÍÔÝͣ״̬ϵÄCPUÕ¼ÓÃ
|
try { Thread.sleep(100); } catch (InterruptedException ignore) {}
|
continue;
|
}
|
|
// 1. ¼ì²é³¬Ê±²¢·¢ËÍÀÛ»ýÊý¾Ý
|
long currentTime = System.currentTimeMillis();
|
if (buffer.size() > 0 && (currentTime - lastReceivedTime) >= 20) {
|
onReceived.accept(buffer.toByteArray());
|
buffer.reset();
|
}
|
|
// 2. ¶ÁÈ¡ÐÂÊý¾Ý
|
int len = port.readBytes(readBuffer, readBuffer.length);
|
currentTime = System.currentTimeMillis(); // ¸üе±Ç°Ê±¼ä
|
|
if (len > 0) {
|
// дÈ뻺³åÇø²¢¸üÐÂʱ¼ä´Á
|
buffer.write(readBuffer, 0, len);
|
lastReceivedTime = currentTime;
|
}
|
|
// 3. ½µµÍCPUÕ¼ÓãºÎÞÊý¾ÝÇÒ»º³åÇø¿Õʱ¶ÌÔÝÐÝÃß
|
if (len <= 0 && buffer.size() == 0) {
|
try { Thread.sleep(1); } catch (InterruptedException ignore) {}
|
}
|
}
|
|
// Ï߳̽áÊøÇ°·¢ËÍÊ£ÓàÊý¾Ý
|
if (buffer.size() > 0) {
|
onReceived.accept(buffer.toByteArray());
|
}
|
});
|
readerThread.setDaemon(true);
|
readerThread.start();
|
}
|
|
/**
|
* Í£Ö¹Êý¾Ý½ÓÊÕÏß³Ì
|
*/
|
public void stopCapture() {
|
// ÉèÖò¶»ñ±ê־Ϊ false£¬Í¨ÖªÏß³ÌÍ˳ö
|
capturing = false;
|
// Èç¹ûÏ̴߳æÔÚ£¬µÈ´ý×î¶à500msÈ·±£Ï߳̽áÊø
|
if (readerThread != null) {
|
try { readerThread.join(500); } catch (InterruptedException ignore) {}
|
// Çå¿ÕÏß³ÌÒýÓÃ
|
readerThread = null;
|
}
|
}
|
|
// ÉèÖÃÔÝͣ״̬
|
public void setPaused(boolean paused) {
|
this.paused = paused;
|
}
|
|
// »ñÈ¡µ±Ç°ÊÇ·ñÔÝÍ£
|
public boolean isPaused() {
|
return paused;
|
}
|
|
// Åжϴ®¿ÚÊÇ·ñÒÑ´ò¿ª
|
public boolean isOpen() {
|
return port != null && port.isOpen();
|
}
|
|
/**
|
* ·¢ËÍÊý¾Ý
|
* @param data Òª·¢Ë͵Ä×Ö½ÚÊý×é
|
* @return ÊÇ·ñ³É¹¦·¢ËÍ
|
*/
|
public boolean send(byte[] data) {
|
// Èç¹û´®¿ÚÒѳõʼ»¯ÇÒÒÑ´ò¿ª£¬·¢ËÍÊý¾Ý²¢·µ»Ø½á¹û
|
return port != null && port.isOpen() && port.writeBytes(data, data.length) > 0;
|
}
|
}
|