Arduino Nano 桌面时钟 + 温湿度计

准备工作:
材料:
序号 | 名称 | 型号/规格 | 数量 | 备注 |
1 | Arduino Nano 开发板 | CH340 / ATmega328P | 1块 | 带 USB 数据线 |
2 | 0.96 寸 OLED 显示屏 | SSD1306,I2C 接口,128×64 | 1块 | 4 个引脚(VCC/GND/SCL/SDA) |
3 | DS1302 时钟模块 | 5 引脚(带 CR2032 电池) | 1个 | 含电池,用于掉电走时 |
4 | DHT11 温湿度传感器 | 3 引脚(VCC/DATA/GND) | 1个 | 部分模块带 4.7kΩ 上拉电阻 |
5 | 公对母杜邦线 | 20cm,彩色 | 10-15 根 | 用于连接各模块 |
6 | 面包板 | 400 孔或 830 孔 | 1块 | 可选,用于固定和接线 |
7 | USB 数据线 | Mini USB(Arduino Nano 专用) | 1根 | 用于供电和烧录程序 |
工具:
序号 | 名称 | 型号/版本 | 数量 | 备注 |
1 | 电脑 | Windows / macOS / Linux | 1台 | 安装 Arduino IDE |
2 | Arduino IDE | 1.8.x 或 2.x 版本 | 1份 | 官方免费软件 |
3 | DS1302 库 | Ds1302 by Rafa Couto | 1份 | 通过库管理器安装 |
4 | DHT11 库 | DHT sensor library by Adafruit | 1份 | 通过库管理器安装 |
5 | OLED 显示库 | Adafruit SSD1306 + Adafruit GFX | 各 1 份 | 通过库管理器安装 |
引脚连接

- DHT11 的 DATA 与 VCC 之间需要接 4.7kΩ 上拉电阻。如果购买的模块已集成该电阻,则直接连接即可。
- DS1302 模块的 CR2032 电池要确保有电(电压 > 2.5V),否则断电后会丢失时间
软件配置

- 访问 Arduino 官网:https://www.arduino.cc/en/software
- 下载对应操作系统的安装包(Windows / macOS / Linux)
- 按提示完成安装
安装所需库
打开 Arduino IDE,依次安装以下 4 个库:
库名称 | 作者 | 用途 |
Adafruit SSD1306 | Adafruit | OLED 屏幕驱动 |
Adafruit GFX Library | Adafruit | OLED 图形绘制(依赖库) |
Ds1302 | Rafa Couto | DS1302 时钟模块驱动 |
DHT sensor library | Adafruit | DHT11 温湿度传感器驱动 |
完整程序代码

将以下代码复制到 Arduino IDE 中:
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Ds1302.h> // Rafa Couto 的库
#include <DHT.h> // Adafruit DHT 库
// ===== OLED 设置 =====
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// ===== DS1302 引脚定义 =====
#define DS1302_RST 8
#define DS1302_CLK 6
#define DS1302_DAT 7
// ===== DHT11 引脚定义 =====
#define DHTPIN 5
#define DHTTYPE DHT11
// 创建对象
Ds1302 rtc(DS1302_RST, DS1302_CLK, DS1302_DAT);
DHT dht(DHTPIN, DHTTYPE);
// 存储温湿度值
float temperature = 0;
float humidity = 0;
unsigned long lastDhtRead = 0;
const unsigned long dhtInterval = 2000; // 每2秒读取一次DHT11
void setup() {
Serial.begin(9600);
// ===== 初始化 OLED =====
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 初始化失败"));
for (;;);
}
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
// ===== 初始化 DS1302 =====
rtc.init();
// 强制写入时间(首次使用或需要校准时启用)
Serial.println("强制写入时间...");
Ds1302::DateTime dt = {
.year = 26, // 年份后两位,如 2026 年写 26
.month = Ds1302::MONTH_AUG,
.day = 8,
.hour = 16,
.minute = 24,
.second = 0,
.dow = Ds1302::DOW_SAT
};
rtc.setDateTime(&dt);
Serial.println("时间已写入");
// ===== 初始化 DHT11 =====
dht.begin();
Serial.println("DHT11 初始化完成");
}
void loop() {
// ===== 读取 DS1302 时间 =====
Ds1302::DateTime now;
rtc.getDateTime(&now);
// ===== 读取 DHT11 温湿度(每2秒读取一次) =====
if (millis() - lastDhtRead >= dhtInterval) {
lastDhtRead = millis();
float h = dht.readHumidity();
float t = dht.readTemperature();
if (isnan(h) || isnan(t)) {
Serial.println("DHT11 读取失败!");
} else {
humidity = h;
temperature = t;
Serial.print("温度: ");
Serial.print(temperature);
Serial.print("°C 湿度: ");
Serial.print(humidity);
Serial.println("%");
}
}
// ===== 串口调试输出时间 =====
Serial.print(now.year + 2000);
Serial.print("-");
Serial.print(now.month);
Serial.print("-");
Serial.print(now.day);
Serial.print(" ");
Serial.print(now.hour);
Serial.print(":");
Serial.print(now.minute);
Serial.print(":");
Serial.println(now.second);
// ===== 刷新 OLED 显示 =====
display.clearDisplay();
// ---- 左上角:日期(1号字体) ----
display.setTextSize(1);
display.setCursor(0, 0);
display.print(now.year + 2000);
display.print("-");
display.print(now.month);
display.print("-");
display.print(now.day);
// ---- 中央:时间(2号字体) ----
display.setTextSize(2);
display.setCursor(16, 22);
if (now.hour < 10) display.print("0");
display.print(now.hour);
display.print(":");
if (now.minute < 10) display.print("0");
display.print(now.minute);
display.print(":");
if (now.second < 10) display.print("0");
display.print(now.second);
// ---- 左下角:温度(2号字体) ----
display.setTextSize(2);
display.setCursor(0, 46);
display.print((int)temperature);
display.print("C");
// ---- 右下角:湿度(2号字体) ----
display.setTextSize(2);
display.setCursor(90, 46);
display.print((int)humidity);
display.print("%");
display.display();
delay(1000);
}
首次使用设置时间

通过程序写入
代码中已包含强制写入时间的部分。烧录前,修改以下内容为当前真实时间:
Ds1302::DateTime dt = {
.year = 26, // 当前年份后两位,如 2026 → 26
.month = Ds1302::MONTH_AUG, // 当前月份(注意月份是英文常量)
.day = 8, // 当前日期
.hour = 16, // 当前小时(24小时制)
.minute = 24, // 当前分钟
.second = 0, // 秒(置0即可)
.dow = Ds1302::DOW_SAT // 当前星期(1=周一 ... 7=周日)
};
烧录程序




1.连接硬件:按接线表将所有模块连接到 Arduino Nano
2.连接电脑:通过 Mini USB 线将 Arduino Nano 连接到电脑
3.选择开发板:工具 → 开发板 → Arduino Nano
4.选择处理器:工具 → 处理器 → ATmega328P (Old Bootloader) 或 ATmega328P(根据实际版本选择)
5.选择端口:工具 → 端口 → 选择对应的 COM 口(Windows)或 /dev/cu.usbserial-xxx(macOS)
6.烧录程序:点击菜单栏 → 箭头按钮(上传)或按 Ctrl+U
7.等待完成:底部状态栏显示 上传成功 即完成
屏幕显示布局

烧录成功后,OLED 屏幕显示效果如下:
2026-8-8 ← 左上:日期(1号字体)
16:24:00 ← 中央:时间(2号字体)
26C 68% ← 左下:温度(2号字体) 右下:湿度(2号字体)
最终效果

将模块排好布局,使用双面胶(热熔胶)固定好
0
0
0
qq空间
微博
复制链接
分享
0