关于串口获取的问题,如何解决?

问题遇到的现象和发生背景

在串口获取数据,拿到的数据不一致

用代码块功能插入代码,请勿粘贴截图

@SpringBootApplication
@MapperScan({"com.example.demo.vegabigv.dao"})
public class VegabigvApplication {

@Autowired
private VegeEnviDao vegeEnviDao;

{
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                final SerialPort serialPort = SerialPortUtil.openSerialPort("COM2" , 115200);

                //设置串口的listener
                SerialPortUtil.setListenerToSerialPort(serialPort, event -> {

                    //数据通知
                    if (event.getEventType() == SerialPortEvent.DATA_AVAILABLE) {

                        byte[] bytes = SerialPortUtil.readData(serialPort);

                        System.out.println("收到的数据:" + new String(bytes));
                        String s = new String(bytes);

                        // 解析属性
                        String record_time = new SimpleDateFormat("yyyy-MM-dd HH:ss:mm").format(new Date());
                        String[] split = s.split(";");
                        String vege_no = split[0].split(":")[1];
                        String temperature = split[1].split(":")[1];
                        String humidity = split[2].split(":")[1];
                        String beam = split[3].split(":")[1];
                        String nutrient = split[4].split(":")[1];
                        String ph_value = split[5].split(":")[1];
                        String name = "";
                        if (Objects.equals(vege_no, "1")) {
                            name = "辣椒";
                        } else if (Objects.equals(vege_no, "2")) {
                            name = "空心菜";
                        } else if (Objects.equals(vege_no, "3")) {
                            name = "上海青";
                        } else if (Objects.equals(vege_no, "4")) {
                            name = "黄瓜";
                        } else if (Objects.equals(vege_no, "5")) {
                            name = "萝卜";
                        } else if (Objects.equals(vege_no, "6")) {
                            name = "西红柿";
                        }
                        // 封装属性
                        VegeEnvi vegeEnvi = new VegeEnvi();
                        vegeEnvi.setRecordTime(record_time);
                        vegeEnvi.setVegeNo(Integer.parseInt(vege_no));
                        vegeEnvi.setVegeName(name);
                        vegeEnvi.setTemperature(temperature);
                        vegeEnvi.setHumidity(humidity);
                        vegeEnvi.setBeam(beam);
                        vegeEnvi.setNutrient(nutrient);
                        vegeEnvi.setPhValue(ph_value);
                        // 保存至数据库
                        vegeEnviDao.insert(vegeEnvi);
                    }
                });
            } catch (NoSuchPortException | PortInUseException | UnsupportedCommOperationException | TooManyListenersException e) {
                e.printStackTrace();
            }
        }
    }).start();
}

public static void main(String[] args) {
    SpringApplication.run(VegabigvApplication.class, args);
}

}

运行结果及报错内容

img

我想要达到的结果

每一次拿到的数据一致

你这得每次判断数据是否已经完整接收,看你的截图数据好像是串行的,所以你加个判断数据完整性的逻辑,比如从第一个vege_no开始到下一个vege_no开始前就是一条完整数据。

@Autowired
private VegeEnviDao vegeEnviDao;
 
    {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    final SerialPort serialPort = SerialPortUtil.openSerialPort("COM2" , 115200);
                    CheckData checkData = new CheckData();

                    //设置串口的listener
                    SerialPortUtil.setListenerToSerialPort(serialPort, event -> {

                        //数据通知
                        if (event.getEventType() == SerialPortEvent.DATA_AVAILABLE) {

                             byte[] bytes = SerialPortUtil.readData(serialPort);

                             String s = checkData.getData(new String(bytes));
                             if(s.isEmpty()){
                                return;
                             }
                             System.out.println("收到的数据:" + okData );
                            // 解析属性
                            String record_time = new SimpleDateFormat("yyyy-MM-dd HH:ss:mm").format(new Date());
                            String[] split = s.split(";");
                            String vege_no = split[0].split(":")[1];
                            String temperature = split[1].split(":")[1];
                            String humidity = split[2].split(":")[1];
                            String beam = split[3].split(":")[1];
                            String nutrient = split[4].split(":")[1];
                            String ph_value = split[5].split(":")[1];
                            String name = "";
                            if (Objects.equals(vege_no, "1")) {
                                name = "辣椒";
                            } else if (Objects.equals(vege_no, "2")) {
                                name = "空心菜";
                            } else if (Objects.equals(vege_no, "3")) {
                                name = "上海青";
                            } else if (Objects.equals(vege_no, "4")) {
                                name = "黄瓜";
                            } else if (Objects.equals(vege_no, "5")) {
                                name = "萝卜";
                            } else if (Objects.equals(vege_no, "6")) {
                                name = "西红柿";
                            }
                            // 封装属性
                            VegeEnvi vegeEnvi = new VegeEnvi();
                            vegeEnvi.setRecordTime(record_time);
                            vegeEnvi.setVegeNo(Integer.parseInt(vege_no));
                            vegeEnvi.setVegeName(name);
                            vegeEnvi.setTemperature(temperature);
                            vegeEnvi.setHumidity(humidity);
                            vegeEnvi.setBeam(beam);
                            vegeEnvi.setNutrient(nutrient);
                            vegeEnvi.setPhValue(ph_value);
                            // 保存至数据库
                            vegeEnviDao.insert(vegeEnvi);
                        }
                    });
                } catch (NoSuchPortException | PortInUseException | UnsupportedCommOperationException |
                         TooManyListenersException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
 
public static void main(String[] args) {
    SpringApplication.run(VegabigvApplication.class, args);
}

   static class CheckData{
        private String okData = "";
        String getData(String data){
            okData += data;
            if(okData.split(":").length == 7){
                String d = okData;
                okData = "";
                return d;
            }
            return "";
        }
    }

串口不能这样搞呀
你的串口对象应该是个静态的,它一直开启着,然后你定期去串口里拿数据,最终把数据拼接成一个完整的包
串口就是这么个东西,它随时给你发数据,你就要随时接,没有包的概念,你只能自己判断一定时间内没有数据了就算是发完了