如何在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
相关产品推荐
相关产品推荐

