You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Processing按AM/PM分时段保存CSV表并重置数据表的问题

问题

我有一个项目,每15分钟通过串口接收数据,用Processing读取并保存为CSV文件。预期每12小时创建一个新文件,但从AM切换到PM时,之前所有AM的数据都会被存入PM文件。我试过这段代码:

saveTable(dataTable, fileName());
dataTable.clearRows();

但这样操作只会清空CSV文件,请问如何正确重置数据表并开始保存到新文件?

生成文件名的代码
String fileName() {
  String fileName = "";
  String month = "";
  String day = "";
  int m = month();
  int d = day();

  if (d < 10) {
    day = str(d);
    day = "-0" + day;
  } else {
    day = "-" + str(d);
  }

  switch(m) {
  case 1:
    month = "-JAN";
    break;
  case 2:
    month = "-FEB";
    break;
  case 3:
    month = "-MAR";
    break;
  case 4:
    month = "-APR";
    break;
  case 5:
    month = "-MAY";
    break;
  case 6:
    month = "-JUN";
    break;
  case 7:
    month = "-JUL";
    break;
  case 8:
    month = "-AUG";
    break;
  case 9:
    month = "-SEP";
    break;
  case 10:
    month = "-OCT";
    break;
  case 11:
    month = "-NOV";
    break;
  case 12:
    month = "-DEC";
    break;
  }

  if (hour() >= 12) {
    hour = "-PM";
  } else {
    hour = "-AM";
  }

  fileName = "SensorData_" + str(year()) + month + day  + hour + ".csv";
  return fileName;
}
更新:数据采集与保存代码
void serialEvent(Serial myPort) {
  if (myPort.available() > 0) {
    String serialDataString = myPort.readString();
    if (serialDataString != null) {
      serialDataString = trim(serialDataString);
      float[] sensorData = float(split(serialDataString, ','));
      TableRow newRow = dataTable.addRow();
      if (sensorData.length == 4) {
        temperature = sensorData[0];
        humidity    = sensorData[1];
        moisture    = sensorData[2];
        int packet = int(sensorData[3]);

        if (packet < 10) {
          packets = "00" + str(packet);
        } else if (packet < 100) {
          packets = "0" + str(packet);
        }

        String time = str(hour()) + ":" + str(minute()) + ":" + str(second());
        String date = str(month()) + "/" + str(day());
        newRow.setFloat("Temperature", temperature);
        newRow.setFloat("Humidity", humidity);
        newRow.setFloat("Moisture", moisture);
        newRow.setString("Time", time);
        newRow.setString("Date", date);
      }
      saveTable(dataTable, fileName());
    }
  }
}
解决方案

问题根源在于每次调用saveTable时,都会把dataTable的全部内容写入当前文件名对应的文件。当时间从AM切换到PM时,新的PM文件名生成后,dataTable仍保留着AM时段的所有数据,导致这些数据被一并写入PM文件。

正确做法是跟踪当前正在使用的文件名,每次生成新文件名时,先保存旧文件并重置数据表:

  1. 添加全局跟踪变量
Table dataTable;
String currentFileName; // 跟踪当前使用的文件名
  1. 初始化数据表与文件名
    在setup()中完成初始化:
void setup() {
  // 串口初始化等其他代码
  dataTable = new Table();
  // 添加数据表列
  dataTable.addColumn("Temperature");
  dataTable.addColumn("Humidity");
  dataTable.addColumn("Moisture");
  dataTable.addColumn("Time");
  dataTable.addColumn("Date");
  
  currentFileName = fileName(); // 初始化当前文件名
}
  1. 修改串口事件处理逻辑
    每次处理数据前检查文件名是否变化,按需保存旧文件并重置数据表:
void serialEvent(Serial myPort) {
  if (myPort.available() > 0) {
    String serialDataString = myPort.readString();
    if (serialDataString != null) {
      serialDataString = trim(serialDataString);
      float[] sensorData = float(split(serialDataString, ','));
      
      // 检查文件名是否更新
      String newFileName = fileName();
      if (!newFileName.equals(currentFileName)) {
        // 保存旧时段的数据表
        saveTable(dataTable, currentFileName);
        // 清空数据表,准备新时段数据
        dataTable.clearRows();
        // 更新当前文件名
        currentFileName = newFileName;
      }
      
      if (sensorData.length == 4) {
        float temperature = sensorData[0];
        float humidity    = sensorData[1];
        float moisture    = sensorData[2];
        int packet = int(sensorData[3]);

        String packets;
        if (packet < 10) {
          packets = "00" + str(packet);
        } else if (packet < 100) {
          packets = "0" + str(packet);
        } else {
          packets = str(packet); // 补充三位数的处理
        }

        String time = str(hour()) + ":" + str(minute()) + ":" + str(second());
        String date = str(month()) + "/" + str(day());
        
        // 仅在数据有效时添加行
        TableRow newRow = dataTable.addRow();
        newRow.setFloat("Temperature", temperature);
        newRow.setFloat("Humidity", humidity);
        newRow.setFloat("Moisture", moisture);
        newRow.setString("Time", time);
        newRow.setString("Date", date);
      }
      
      // 保存当前数据到对应文件
      saveTable(dataTable, currentFileName);
    }
  }
}
  1. 修复文件名函数的变量冲突
    原函数中hour是Processing内置函数,不能用作变量名,修改为:
String fileName() {
  String fileName = "";
  String month = "";
  String day = "";
  int m = month();
  int d = day();

  if (d < 10) {
    day = "-0" + str(d);
  } else {
    day = "-" + str(d);
  }

  switch(m) {
  case 1: month = "-JAN"; break;
  case 2: month = "-FEB"; break;
  case 3: month = "-MAR"; break;
  case 4: month = "-APR"; break;
  case 5: month = "-MAY"; break;
  case 6: month = "-JUN"; break;
  case 7: month = "-JUL"; break;
  case 8: month = "-AUG"; break;
  case 9: month = "-SEP"; break;
  case 10: month = "-OCT"; break;
  case 11: month = "-NOV"; break;
  case 12: month = "-DEC"; break;
  }

  String hourSuffix = (hour() >= 12) ? "-PM" : "-AM";

  fileName = "SensorData_" + str(year()) + month + day + hourSuffix + ".csv";
  return fileName;
}

核心改进点:

  • 通过跟踪文件名,确保时段切换时仅保存对应时段的数据
  • 避免无效空行生成,仅在数据有效时添加行
  • 修复了变量名冲突问题

内容的提问来源于stack exchange,提问作者Justin Wilker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 14:01:40