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

如何在Serial Monitor中同步显示气体传感器数值与当前日期?

实现Arduino气体检测装置串口显示日期与传感器数值

针对你的需求,下面提供两种可行方案,分别适合无额外硬件和追求高精度时间的场景:


方案一:无额外硬件的软件模拟计时

Arduino基础板无内置实时时钟,可通过软件模拟时间流逝,适合对时间精度要求不高的场景。修改后的代码如下:

int redpin = 13;
int greenled = 7;
int buzzer = 11;
int gasA0 = A0;
// 报警阈值
int sensorThres = 400;

// 模拟时间变量,可按需初始化初始时间
unsigned long seconds = 0;
unsigned long minutes = 0;
unsigned long hours = 12;
unsigned long days = 1;
unsigned long months = 1;
unsigned long years = 2024;

unsigned long previousMillis = 0;
const long interval = 1000; // 每秒更新一次时间

void setup() {
  pinMode(greenled, OUTPUT);
  pinMode(redpin, OUTPUT);
  pinMode(buzzer, OUTPUT);
  pinMode(gasA0, INPUT);
  Serial.begin(9600);
  
  // 初始化绿灯常亮
  digitalWrite(greenled, HIGH);
}

void loop() {
  int analogSensor = analogRead(gasA0);
  
  // 非阻塞式更新时间,避免影响主逻辑
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    seconds++;
    // 时间进位逻辑
    if (seconds >= 60) {
      seconds = 0;
      minutes++;
      if (minutes >= 60) {
        minutes = 0;
        hours++;
        if (hours >= 24) {
          hours = 0;
          days++;
          // 简化的月份/年份进位判断,可按需扩展
          if ((months == 4 || months == 6 || months == 9 || months == 11) && days > 30) {
            days = 1;
            months++;
          } else if (months == 2) {
            // 简单闰年判断
            if ((years % 4 == 0 && years % 100 != 0) || years % 400 == 0) {
              days = days > 29 ? 1 : days;
              months = days == 1 ? months + 1 : months;
            } else {
              days = days > 28 ? 1 : days;
              months = days == 1 ? months + 1 : months;
            }
          } else if (days > 31) {
            days = 1;
            months++;
            months = months > 12 ? 1 : months;
            years = months == 1 ? years + 1 : years;
          }
        }
      }
    }
  }
  
  // 格式化输出日期、时间与传感器数值
  Serial.print("日期: ");
  Serial.print(years);
  Serial.print("-");
  printTwoDigits(months);
  Serial.print("-");
  printTwoDigits(days);
  Serial.print(" 时间: ");
  printTwoDigits(hours);
  Serial.print(":");
  printTwoDigits(minutes);
  Serial.print(":");
  printTwoDigits(seconds);
  Serial.print(" | 传感器数值: ");
  Serial.println(analogSensor);
  
  // 原有报警逻辑
  if (analogSensor > sensorThres) {
    digitalWrite(greenled, LOW);
    digitalWrite(redpin, HIGH);
    tone(buzzer, 100);
  } else {
    digitalWrite(redpin, LOW);
    digitalWrite(greenled, HIGH);
    noTone(buzzer);
  }
  
  delay(400);
}

// 辅助函数:确保时间数字以两位格式显示
void printTwoDigits(unsigned long number) {
  if (number < 10) {
    Serial.print("0");
  }
  Serial.print(number);
}

说明

  • 用millis()实现非阻塞时间更新,避免主循环被阻塞
  • 实现基础的日期进位逻辑,可根据需求扩展更精确的闰年、月份天数判断
  • printTwoDigits函数让时间显示更规范(如09:05:03而非9:5:3)

方案二:外接RTC模块(高精度)

若需要精准实时时间,推荐使用DS3231这类低成本高精度RTC模块,通过I2C接口连接。

步骤1:接线

  • DS3231的VCC接Arduino 3.3V/5V(依模块规格)
  • GND接Arduino GND
  • SDA接Arduino A4(Uno/Nano)
  • SCL接Arduino A5(Uno/Nano)

步骤2:安装库

在Arduino IDE中搜索并安装RTClib库(Adafruit出品)

修改后的代码

#include <Wire.h>
#include <RTClib.h>

int redpin = 13;
int greenled = 7;
int buzzer = 11;
int gasA0 = A0;
int sensorThres = 400;

RTC_DS3231 rtc;

void setup() {
  pinMode(greenled, OUTPUT);
  pinMode(redpin, OUTPUT);
  pinMode(buzzer, OUTPUT);
  pinMode(gasA0, INPUT);
  Serial.begin(9600);
  
  // 初始化RTC模块
  if (!rtc.begin()) {
    Serial.println("无法找到RTC模块!");
    while (1); // 初始化失败则停止运行
  }
  
  // 仅第一次运行时设置时间,之后请注释该行
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // 用编译时间初始化
  // 或手动设置:rtc.adjust(DateTime(2024, 1, 1, 12, 0, 0));
  
  digitalWrite(greenled, HIGH);
}

void loop() {
  int analogSensor = analogRead(gasA0);
  
  // 获取当前实时时间
  DateTime now = rtc.now();
  
  // 格式化输出
  Serial.print("日期: ");
  Serial.print(now.year(), DEC);
  Serial.print("-");
  printTwoDigits(now.month());
  Serial.print("-");
  printTwoDigits(now.day());
  Serial.print(" 时间: ");
  printTwoDigits(now.hour());
  Serial.print(":");
  printTwoDigits(now.minute());
  Serial.print(":");
  printTwoDigits(now.second());
  Serial.print(" | 传感器数值: ");
  Serial.println(analogSensor);
  
  // 原有报警逻辑
  if (analogSensor > sensorThres) {
    digitalWrite(greenled, LOW);
    digitalWrite(redpin, HIGH);
    tone(buzzer, 100);
  } else {
    digitalWrite(redpin, LOW);
    digitalWrite(greenled, HIGH);
    noTone(buzzer);
  }
  
  delay(400);
}

void printTwoDigits(int number) {
  if (number < 10) {
    Serial.print("0");
  }
  Serial.print(number);
}

说明

  • RTClib库简化了RTC操作,时间精度远高于软件模拟
  • 第一次运行时取消注释rtc.adjust()设置时间,之后注释避免每次重启重置
  • 若模块带后备电池,断电后时间会持续运行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 21:15:34