// ÉùÃ÷°üÃû 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 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; } }