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

基于Arduino的24小时数码管时钟复位异常问题求助

Arduino四位七段数码管24小时时钟复位异常问题解决

问题根源

你的时钟复位异常主要由两个核心问题导致:

  • 变量类型溢出:startTime被定义为int类型,但millis()返回的是unsigned long(最大值约49天),int的最大值仅为32767,运行几分钟后就会溢出,导致时间计算完全混乱。
  • 复位逻辑漏洞:当触发displayNum > 2359的复位条件时,你直接将now赋值为millis()而非millis() - startTime,且未重新计算sec、minute,导致后续循环的时间计算出现断层,出现跳数、停摆现象。

解决方案

方案一:用取模实现自动24小时循环(推荐)

这种方式无需手动判断复位,通过数学取模自动实现循环,逻辑更简洁可靠,同时修正变量类型避免溢出:

#include "SevSeg.h"
SevSeg sevseg;

unsigned long startTime = 0; // 改为unsigned long,避免溢出
int sec;
int minute;

void setup(){
  
  byte numDigits = 4;
  byte digitPins[] = {10, 11, 12, 13};
  byte segmentPins[] = {9, 2, 3, 5, 6, 8, 7, 4};

  bool resistorsOnSegments = true; 
  bool updateWithDelaysIn = true;
  byte hardwareConfig = COMMON_ANODE; 
  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments);
  sevseg.setBrightness(100);

  Serial.begin(9600);
}

void loop(){
    
  sevseg.refreshDisplay();

  unsigned long now = millis() - startTime;
  now /= 50; // 测试加速用,实际场景改为1000
  
  // 计算总测试秒数对应的24小时制时间
  unsigned long totalTestSeconds = now;
  unsigned long totalMinutes = totalTestSeconds / 60;
  totalMinutes %= 1440; // 24*60=1440分钟,超过自动取模循环
  
  minute = (totalMinutes / 60) * 100;
  sec = totalTestSeconds % 60;

  int displayNum = minute + sec;

  sevseg.setNumber(displayNum, 2);
  Serial.println(displayNum);
  
}

方案二:修正原复位逻辑

如果你想保留原有的复位判断方式,需要修正变量类型和复位时的计算逻辑:

#include "SevSeg.h"
SevSeg sevseg;

unsigned long startTime = 0; // 改为unsigned long
int sec;
int minute;

void setup(){
  
  byte numDigits = 4;
  byte digitPins[] = {10, 11, 12, 13};
  byte segmentPins[] = {9, 2, 3, 5, 6, 8, 7, 4};

  bool resistorsOnSegments = true; 
  bool updateWithDelaysIn = true;
  byte hardwareConfig = COMMON_ANODE; 
  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments);
  sevseg.setBrightness(100);

  Serial.begin(9600);
}

void loop(){
    
  sevseg.refreshDisplay();

  unsigned long now = millis() - startTime;
  now /= 50; // 测试加速用
  sec = now % 60;
  minute = 100*(now / 60);

  int displayNum = sec + minute;

  if(displayNum > 2359){
    startTime = millis();
    now = 0; // 重置当前时间差为0
    sec = now % 60;
    minute = 100*(now / 60);
    displayNum = sec + minute;
  }

  sevseg.setNumber(displayNum,2);
  Serial.println(displayNum);
  
}

修改说明

  1. 变量类型修正:将startTime和now改为unsigned long,彻底避免整数溢出问题,这是解决长时间运行后异常的关键。
  2. 循环逻辑优化:方案一通过对总分钟数取1440(24小时总分钟数)的模,自动实现24小时循环,无需手动复位,避免了复位时的逻辑错误。
  3. 复位逻辑修复:方案二中,复位时重新计算now、sec、minute,确保复位后显示正确的0值,且后续循环的时间计算正常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 19:23:26