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

Arduino IDE中C++毫秒转时间戳异常:时间戳递减问题排查

时间戳递减问题的修复方案

问题现象

串口输出的CSV格式数据中,时间戳出现递减情况,示例输出如下:

timestamp,lux
0:0:16,66
0:0:11,30
0:0:7,30
0:0:2,35
1:1:3,30
0:0:59,171
0:0:54,36
0:0:50,35
0:0:45,32

现有代码

用于生成CSV的函数:

void writeToCsv() {
  Serial.println("timestamp,lux");
  unsigned timestamp = last_save;
  for (int i = 0; i < EEPROM.length(); i++) {
    int seconds = (int) (timestamp / 1000) % 60;
    int minutes = (int) ((timestamp / (1000*60)) % 60);
    int hours   = (int) ((timestamp / (1000*60*60)) % 24);
    Serial.print(hours);
    Serial.print(":");
    Serial.print(minutes);
    Serial.print(":");
    Serial.print(seconds);
    Serial.print(",");
    Serial.println(EEPROM.read(i));
    timestamp += LOGGING_DELAY;
  }
  last_save = timestamp;
}

关键变量定义

#define LOGGING_DELAY 1 * 60 * 60 * 1000
#define HOUR 11 + (23/60) // 11:23 am (the starting time)
int start_time = 1000 * 60 * 60 * HOUR

问题根源

  1. 变量类型溢出:多数嵌入式平台(如Arduino)的int是16位类型,最大值仅为32767,而LOGGING_DELAY计算值为3600000,远超出int范围,导致数值溢出后变为负数。每次累加这个溢出的负数,会让timestamp实际递减,最终表现为时间戳倒退。
  2. 时间初始化错误:23/60属于整数除法,结果为0,因此HOUR实际等于11,无法正确表示11:23的起始时间。

修复步骤

1. 修正变量类型

将所有存储毫秒数的变量改为unsigned long(32位无符号长整型,可容纳约49天的毫秒数,完全满足需求):

  • 将last_save的类型从int改为unsigned long
  • 将start_time的类型从int改为unsigned long
  • 函数内的timestamp改为unsigned long,避免局部变量溢出

2. 修正起始时间定义

替换原有的HOUR宏,直接计算起始时间的总毫秒数,避免整数除法丢失精度:

#define START_HOURS 11
#define START_MINUTES 23
unsigned long start_time = (unsigned long)(START_HOURS * 3600 + START_MINUTES * 60) * 1000;

3. 确保宏定义数值无溢出

给LOGGING_DELAY的数值加上UL后缀,强制编译器按无符号长整型处理,避免编译时溢出:

#define LOGGING_DELAY 1UL * 60UL * 60UL * 1000UL // 1小时对应的毫秒数

4. 调整writeToCsv函数

修改局部变量timestamp的类型:

void writeToCsv() {
  Serial.println("timestamp,lux");
  unsigned long timestamp = last_save; // 改为unsigned long
  for (int i = 0; i < EEPROM.length(); i++) {
    int seconds = (int) (timestamp / 1000) % 60;
    int minutes = (int) ((timestamp / (1000*60)) % 60);
    int hours   = (int) ((timestamp / (1000*60*60)) % 24);
    Serial.print(hours);
    Serial.print(":");
    Serial.print(minutes);
    Serial.print(":");
    Serial.print(seconds);
    Serial.print(",");
    Serial.println(EEPROM.read(i));
    timestamp += LOGGING_DELAY;
  }
  last_save = timestamp;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 02:48:14