219浏览
楼主: 驴友花雕

[项目] 【花雕学编程】Arduino动手做(245)--DS3231模块11个小实验

[复制链接]

驴友花雕  中级技神
 楼主|

发表于 前天 10:17

【花雕学编程】Arduino动手做(245)--DS3231高精度时钟模块

  【Arduino】189种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验二百四十五:DS3231 高精度时钟模块  IIC/I2C接口 实时计时传感器
项目之四:计算 从 1970 年 1 月 1 日午夜以来的时间(Unix 时间戳)

实验开源代码

  1. /*
  2.   【Arduino】189种传感器模块系列实验(资料代码+仿真编程+图形编程)
  3.   实验二百四十五:DS3231 高精度时钟模块  IIC/I2C接口 实时计时传感器
  4.   项目之四:计算 从 1970 年 1 月 1 日午夜以来的时间(Unix 时间戳)
  5. */
  6. #include <Wire.h>
  7. #include <DS3231.h>
  8. RTClib myRTC;
  9. void setup () {
  10.     Serial.begin(57600);
  11.     Wire.begin();
  12.     delay(500);
  13.     Serial.println("Nano Ready!");
  14. }
  15. void loop () {
  16.    
  17.     delay(2000);
  18.    
  19.     DateTime now = myRTC.now();
  20.    
  21.     Serial.print(now.year(), DEC);
  22.     Serial.print('/');
  23.     Serial.print(now.month(), DEC);
  24.     Serial.print('/');
  25.     Serial.print(now.day(), DEC);
  26.     Serial.print(' ');
  27.     Serial.print(now.hour(), DEC);
  28.     Serial.print(':');
  29.     Serial.print(now.minute(), DEC);
  30.     Serial.print(':');
  31.     Serial.print(now.second(), DEC);
  32.     Serial.println();
  33.    
  34.     Serial.print(" 自1970年1月1日午夜以来 = ");
  35.     Serial.print(now.unixtime());
  36.     Serial.print("秒 = ");
  37.     Serial.print(now.unixtime() / 86400L);
  38.     Serial.println(" 天");
  39. }
复制代码


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 前天 10:20

【花雕学编程】Arduino动手做(245)--DS3231高精度时钟模块

代码解读

这段代码使用 DS3231 实时时钟(RTC)模块 获取 当前时间和日期,并计算 从 1970 年 1 月 1 日午夜以来的时间(Unix 时间戳),核心逻辑如下:

1. 引入库
✅ #include <Wire.h> → 用于 I2C 通信 ✅ #include <DS3231.h> → 用于 DS3231 RTC 控制 ✅ RTClib myRTC; → 创建 RTC 对象,用于管理时间数据

2. 初始化
✅ Serial.begin(57600); → 设置串口通信速率为 57600 ✅ Wire.begin(); → 初始化 I2C 通信 ✅ Serial.println("Nano Ready!"); → 打印启动消息 ✅ delay(500); → 等待 500 毫秒,确保 RTC 启动

3. 读取并显示时间
✅ DateTime now = myRTC.now(); → 获取当前时间 ✅ Serial.print(now.year(), DEC); → 显示年份 ✅ Serial.print(now.month(), DEC); → 显示月份 ✅ Serial.print(now.day(), DEC); → 显示日期 ✅ Serial.print(now.hour(), DEC); → 显示小时 ✅ Serial.print(now.minute(), DEC); → 显示分钟 ✅ Serial.print(now.second(), DEC); → 显示秒

4. 计算 Unix 时间
✅ Serial.print(now.unixtime()); → 获取 Unix 时间戳(秒数) ✅ Serial.print(now.unixtime() / 86400L); → 计算从 1970 年 1 月 1 日以来的天数

5. 采集间隔
✅ delay(2000); → 每 2 秒更新一次数据

这段代码让 DS3231 RTC 模块不断读取时间,并计算 Unix 时间戳。





回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 前天 10:26

【花雕学编程】Arduino动手做(245)--DS3231高精度时钟模块

实验串口返回情况

【花雕学编程】Arduino动手做(245)--DS3231模块11个小实验图1
回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 前天 11:02

【花雕学编程】Arduino动手做(245)--DS3231高精度时钟模块

  【Arduino】189种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百四十五:DS3231 高精度时钟模块  IIC/I2C接口 实时计时传感器
  项目之五:生成 9 单位的矩形波

实验开源代码

  1. /*
  2.   【Arduino】189种传感器模块系列实验(资料代码+仿真编程+图形编程)
  3.   实验二百四十五:DS3231 高精度时钟模块  IIC/I2C接口 实时计时传感器
  4.   项目之五:生成 9 单位的矩形波
  5. */
  6. #include <Wire.h>
  7. #include <DS3231.h>
  8. DS3231 rtc;  // 创建 DS3231 RTC 实例
  9. void setup() {
  10.     Serial.begin(9600);  // 初始化串口通信
  11.     Wire.begin();  // 初始化 I2C 通信
  12. }
  13. void loop() {
  14.     rtc.getTemperature();  // 刷新 RTC 数据
  15.     int second = rtc.getSecond();  // 获取当前秒数
  16.     int signal = (second % 2 == 0) ? 9 : 0;  // 每秒切换 0 和 9,生成矩形波
  17.    
  18.     Serial.println(signal);  // 发送数据到串口绘图器
  19.     delay(100);  // 确保绘图器稳定显示波形
  20. }
复制代码


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 前天 11:07

【花雕学编程】Arduino动手做(245)--DS3231高精度时钟模块

代码解读

这段代码使用 DS3231 实时时钟(RTC)模块 通过 I2C 通信 获取 当前秒数,并在串口绘图器生成矩形波,核心逻辑如下:

1. 初始化 RTC
✅ DS3231 rtc; → 创建 DS3231 实例(使用默认 I2C 地址)
✅ Wire.begin(); → 启动 I2C 通信
✅ Serial.begin(9600); → 初始化串口通信

2. 读取秒数据
✅ rtc.getSecond(); → 获取当前秒数
✅ second % 2 == 0 ? 9 : 0; → 偶数秒输出 9,奇数秒输出 0,形成矩形波

3. 发送数据
✅ Serial.println(signal); → 将数据发送至串口绘图器,用于实时显示波形

4. 采集间隔
✅ delay(100); → 每 100 毫秒更新一次数据,确保波形稳定

这段代码让 DS3231 模块精准控制矩形波,并在串口绘图器显示。




回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 前天 11:12

【花雕学编程】Arduino动手做(245)--DS3231高精度时钟模块

实验串口返回情况

【花雕学编程】Arduino动手做(245)--DS3231模块11个小实验图1
回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 前天 11:25

【花雕学编程】Arduino动手做(245)--DS3231高精度时钟模块

实验串口绘图器返回情况

【花雕学编程】Arduino动手做(245)--DS3231模块11个小实验图2

【花雕学编程】Arduino动手做(245)--DS3231模块11个小实验图1
回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 前天 11:28

【花雕学编程】Arduino动手做(245)--DS3231高精度时钟模块

  【Arduino】189种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百四十五:DS3231 高精度时钟模块  IIC/I2C接口 实时计时传感器
  项目之六:通过串口监视器输出报警状态

实验开源代码

  1. /*
  2.   【Arduino】189种传感器模块系列实验(资料代码+仿真编程+图形编程)
  3.   实验二百四十五:DS3231 高精度时钟模块  IIC/I2C接口 实时计时传感器
  4.   项目之六:通过串口监视器输出报警状态
  5. */
  6. #include <DS3231.h>  // 引入 DS3231 实时时钟库
  7. #include <Wire.h>    // 引入 I2C 通信库
  8. // **创建 DS3231 RTC 对象**
  9. DS3231 myRTC;
  10. void setup() {
  11.   // **初始化 I2C 通信**
  12.   Wire.begin();
  13.   // **初始化串口通信,波特率为 57600**
  14.   Serial.begin(57600);
  15.   // **设置 "报警1",每分钟触发**
  16.   // 关闭 Alarm1,不需要手动打开
  17.   myRTC.turnOffAlarm(1);
  18.   myRTC.setA1Time(0, 0, 0, 0, 0b01111110, false, false, false);
  19.   myRTC.checkIfAlarm(1);
  20.   // **设置 "报警2",每分钟触发**
  21.   // 关闭 Alarm2,不需要手动打开
  22.   myRTC.turnOffAlarm(2);
  23.   myRTC.setA2Time(0, 0, 0, 0b01111110, false, false, false);
  24.   myRTC.checkIfAlarm(2);
  25. }
  26. void loop() {
  27.   // **初始化 AlarmBits(报警状态位)**
  28.   byte AlarmBits = 0x0;
  29.   Serial.print("初始化 AlarmBits: ");
  30.   Serial.println(AlarmBits, BIN);  // 以二进制格式打印
  31.   // **初始化时间变量**
  32.   byte ADay, AHour, AMinute, ASecond;
  33.   bool ADy, Ah12, APM;
  34.   // **获取 "报警1" 时间(不清除报警标志)**
  35.   myRTC.getA1Time(ADay, AHour, AMinute, ASecond, AlarmBits, ADy, Ah12, APM);
  36.   Serial.print("获取 A1 时间: ");
  37.   Serial.println(AlarmBits, BIN);  // 预期值:0x(0000)1110
  38.   // **获取 "报警2" 时间(不清除报警标志)**
  39.   myRTC.getA2Time(ADay, AHour, AMinute, AlarmBits, ADy, Ah12, APM);
  40.   Serial.print("获取 A2 时间: ");
  41.   Serial.println(AlarmBits, BIN);  // 预期值:0x01111110
  42.   // **获取 "报警1" 时间(清除报警标志)**
  43.   myRTC.getA1Time(ADay, AHour, AMinute, ASecond, AlarmBits, ADy, Ah12, APM, true);
  44.   Serial.print("清除后获取 A1 时间: ");
  45.   Serial.println(AlarmBits, BIN);  // 预期值:0x(0000)1110
  46.   // **获取 "报警2" 时间(清除报警标志)**
  47.   myRTC.getA2Time(ADay, AHour, AMinute, AlarmBits, ADy, Ah12, APM, true);
  48.   Serial.print("清除后获取 A2 时间: ");
  49.   Serial.println(AlarmBits, BIN);  // 预期值:0x01110000
  50.   delay(5000);  // **每 5 秒更新一次数据**
  51. }
复制代码


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 前天 11:32

【花雕学编程】Arduino动手做(245)--DS3231高精度时钟模块

代码解读

这段代码使用 DS3231 实时时钟(RTC)模块 管理 报警系统,并通过 串口监视器输出报警状态,核心逻辑如下:

1. 初始化 RTC
✅ DS3231 myRTC; → 创建 DS3231 RTC 实例
✅ Wire.begin(); → 启动 I2C 通信
✅ Serial.begin(57600); → 设置串口波特率为 57600

2. 设置报警
✅ turnOffAlarm(1); → 关闭 Alarm1
✅ setA1Time(0, 0, 0, 0, 0b01111110, false, false, false); → 设置 Alarm1,每分钟触发
✅ turnOffAlarm(2); → 关闭 Alarm2
✅ setA2Time(0, 0, 0, 0b01111110, false, false, false); → 设置 Alarm2,每分钟触发

3. 读取报警状态
✅ getA1Time() → 获取 Alarm1 的时间数据
✅ getA2Time() → 获取 Alarm2 的时间数据
✅ Serial.println(AlarmBits, BIN); → 以二进制格式显示报警状态

4. 采集间隔
✅ delay(5000); → 每 5 秒更新一次数据

这段代码让 DS3231 模块管理报警,并在串口监视器查看报警状态。




回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 前天 11:34

【花雕学编程】Arduino动手做(245)--DS3231高精度时钟模块

实验串口返回情况

【花雕学编程】Arduino动手做(245)--DS3231模块11个小实验图1
回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 前天 13:42

【花雕学编程】Arduino动手做(245)--DS3231高精度时钟模块

  【Arduino】189种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百四十五:DS3231 高精度时钟模块  IIC/I2C接口 实时计时传感器
  项目之七:通过 Unix 时间戳设置 DS3231 时间

实验开源代码

  1. /*
  2.   【Arduino】189种传感器模块系列实验(资料代码+仿真编程+图形编程)
  3.   实验二百四十五:DS3231 高精度时钟模块  IIC/I2C接口 实时计时传感器
  4.   项目之七:通过 Unix 时间戳设置 DS3231 时间
  5. */
  6. #include <Wire.h>  // 引入 I2C 通信库
  7. #include <DS3231.h>  // 引入 DS3231 RTC 库
  8. // **格式化时间并输出**
  9. void showTimeFormated(time_t t) {
  10. #if defined (__AVR__)  // 如果是 AVR 平台,调整时间戳
  11.   t -= 946684800UL;  // 修正 Unix 时间(基于 2000 年)
  12. #endif
  13.   char buffer[50];  // 创建存储格式化时间的字符数组
  14.   struct tm *ptm;
  15.   ptm = gmtime(&t);  // 将时间转换为 UTC 时间结构
  16.   const char *timeformat = "%a %F %X - weekday %w; CW %W";  // 时间格式
  17.   strftime(buffer, sizeof(buffer), timeformat, ptm);  // 格式化时间
  18.   Serial.print(buffer);
  19.   Serial.print("\n");
  20. }
  21. // **Unix 时间戳(1660644000 对应 2022-08-16 10:00:00 UTC)**
  22. constexpr time_t tstmp {1660644000UL};
  23. // **创建 RTC 实例**
  24. RTClib myRTC;
  25. DS3231 Clock;
  26. void setup() {
  27.   Serial.begin(115200);  // 初始化串口通信,波特率 115200
  28.   Wire.begin();  // 启动 I2C 通信
  29.   delay(500);  // 确保 RTC 启动稳定
  30.   Serial.println("\n\n\n测试 DS3231 - setEpoch()\n\n\n");
  31. #if defined (__AVR__)
  32.   Serial.println("AVR 微控制器就绪!");
  33.   Wire.begin();
  34.   //#elif defined (ESP8266)
  35.   //Serial.println("ESP8266 微控制器就绪!");
  36.   //Wire.begin(0U, 2U);  // 设置 ESP8266 的 I2C 连接:SDA = GPIO0,SCL = GPIO2
  37. #endif
  38.   // **设置 DS3231 的时间**
  39.   Serial.println("设置 DS3231 的时间为:2022-08-16 10:00:00 (UTC)");
  40.   Serial.println("Unix 时间戳 - 1660644000");
  41.   Clock.setEpoch(tstmp, false);  // 通过 Unix 时间戳设置 DS3231 时间
  42.   Clock.setClockMode(false);  // 设定为 24 小时制
  43.   // **验证 DS3231 数据**
  44.   bool century = false;
  45.   bool h12Flag;
  46.   bool pmFlag;
  47.   DateTime now = myRTC.now();  // 获取当前 RTC 时间
  48.   Serial.print("\n\n");
  49.   Serial.print(" DS3231 的当前时间:     ");
  50.   Serial.print(Clock.getYear(), DEC);
  51.   Serial.print("-");
  52.   Serial.print(Clock.getMonth(century), DEC);
  53.   Serial.print("-");
  54.   Serial.print(Clock.getDate(), DEC);
  55.   Serial.print(" ");
  56.   Serial.print(Clock.getHour(h12Flag, pmFlag), DEC);
  57.   Serial.print(":");
  58.   Serial.print(Clock.getMinute(), DEC);
  59.   Serial.print(":");
  60.   Serial.print(Clock.getSecond(), DEC);
  61.   Serial.print("  -  星期 ");
  62.   Serial.print(Clock.getDoW(), DEC);
  63.   Serial.println();
  64.   Serial.print("\n\n");
  65.   Serial.print(" RTC 当前时间:          ");
  66.   Serial.print(now.year(), DEC);
  67.   Serial.print("-");
  68.   Serial.print(now.month(), DEC);
  69.   Serial.print("-");
  70.   Serial.print(now.day(), DEC);
  71.   Serial.print(" ");
  72.   Serial.print(now.hour(), DEC);
  73.   Serial.print(":");
  74.   Serial.print(now.minute(), DEC);
  75.   Serial.print(":");
  76.   Serial.print(now.second(), DEC);
  77.   Serial.println();
  78.   Serial.print("\n\n **格式化 Struct tm 输出:  ");
  79.   showTimeFormated(tstmp);  // 以格式化方式输出时间
  80. }
  81. void loop() {
  82.   // 该代码仅在 setup() 运行一次,因此 loop() 不执行任何操作
  83. }
复制代码


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 前天 13:47

【花雕学编程】Arduino动手做(245)--DS3231高精度时钟模块

代码简单解读

这段代码使用 DS3231 实时时钟(RTC)模块 通过 I2C 通信 设置并读取时间,核心逻辑如下:

1. 初始化 RTC
✅ DS3231 Clock; → 创建 DS3231 RTC 对象
✅ Wire.begin(); → 启动 I2C 通信
✅ Serial.begin(115200); → 初始化串口通信,波特率 115200

2. 设置时间
✅ Clock.setEpoch(tstmp, false); → 使用 Unix 时间戳设置 DS3231 时间
✅ Clock.setClockMode(false); → 设定为 24 小时制

3. 读取并打印时间
✅ Clock.getYear(), Clock.getMonth(century), Clock.getDate(); → 获取年月日
✅ Clock.getHour(h12Flag, pmFlag), Clock.getMinute(), Clock.getSecond(); → 获取小时、分钟、秒
✅ Clock.getDoW(); → 获取星期

4. 格式化时间
✅ showTimeFormated(tstmp); → 格式化时间并打印

5. 采集间隔
✅ loop() 为空 → 代码只在 setup() 运行一次,不循环执行

这段代码让 DS3231 模块精准管理时间,并格式化输出到串口。





回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 前天 13:50

【花雕学编程】Arduino动手做(245)--DS3231高精度时钟模块

实验串口返回情况

【花雕学编程】Arduino动手做(245)--DS3231模块11个小实验图1
回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 前天 14:26

【花雕学编程】Arduino动手做(245)--DS3231高精度时钟模块

  【Arduino】189种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百四十五:DS3231 高精度时钟模块  IIC/I2C接口 实时计时传感器
  项目之八:通过 I2C 通信 接收用户输入的时间数据并更新时钟

实验开源代码

  1. /*
  2.   【Arduino】189种传感器模块系列实验(资料代码+仿真编程+图形编程)
  3.   实验二百四十五:DS3231 高精度时钟模块  IIC/I2C接口 实时计时传感器
  4.   项目之八:通过 I2C 通信 接收用户输入的时间数据并更新时钟
  5. */
  6. #include <DS3231.h>  // 引入 DS3231 RTC 库
  7. #include <Wire.h>    // 引入 I2C 通信库
  8. // **创建 DS3231 RTC 对象**
  9. DS3231 myRTC;
  10. // **定义时间变量**
  11. byte year, month, date, dow;  // 年、月、日、星期
  12. byte hour, minute, second;    // 时、分、秒
  13. bool century = false;  // 用于跨世纪判断
  14. bool h12Flag;          // 12 小时制标志
  15. bool pmFlag;           // PM 标志(仅用于 12 小时制)
  16. /*****************************************************************************************************
  17. * **初始化**
  18. *  - 开启串口和 I2C 通信
  19. *  - 解释程序的使用方法
  20. *****************************************************************************************************/
  21. void setup() {
  22.     Serial.begin(57600);  // **初始化串口,波特率 57600**
  23.     Wire.begin();  // **启动 I2C 通信**
  24.    
  25.     // **等待 4 秒,确保 RTC 启动稳定**
  26.     delay(4000);
  27.     // **向用户解释时间格式**
  28.     Serial.println("时间格式:YYMMDDwhhmmssx");
  29.     Serial.println("其中:");
  30.     Serial.println("  YY = 年(如 20 表示 2020 年)");
  31.     Serial.println("  MM = 月(如 04 表示 4 月)");
  32.     Serial.println("  DD = 日期(如 09 表示 9 号)");
  33.     Serial.println("  w  = 星期(1-7,1=星期天,5=星期四)");
  34.     Serial.println("  hh = 24 小时制小时数(如 09 表示上午 9 点,21 表示晚上 9 点)");
  35.     Serial.println("  mm = 分钟(如 02)");
  36.     Serial.println("  ss = 秒(如 42)");
  37.     Serial.println("例如输入:2004095090242x");
  38.     Serial.println("-----------------------------------------------------------------------------");
  39.     Serial.println("请在串口输入时间,并以 'x' 结尾以设置 DS3231 的时间:");
  40. }
  41. /*****************************************************************************************************
  42. * **主循环**
  43. *  - 监听串口输入的时间校正数据
  44. *  - 根据输入设置 DS3231 的时钟
  45. *  - 在 5 秒内回显 DS3231 时间
  46. *****************************************************************************************************/
  47. void loop() {
  48.     // **如果串口收到输入数据,则进行时间校正**
  49.     if (Serial.available()) {
  50.         inputDateFromSerial();  // 读取串口数据并解析时间
  51.         myRTC.setClockMode(false);  // **设置 24 小时模式**
  52.         
  53.         // **将输入的时间写入 DS3231**
  54.         myRTC.setYear(year);
  55.         myRTC.setMonth(month);
  56.         myRTC.setDate(date);
  57.         myRTC.setDoW(dow);
  58.         myRTC.setHour(hour);
  59.         myRTC.setMinute(minute);
  60.         myRTC.setSecond(second);
  61.         // **连续 5 秒,每秒打印 DS3231 当前时间**
  62.         for (uint8_t i = 0; i < 5; i++) {
  63.             delay(1000);
  64.             Serial.print(myRTC.getYear(), DEC);
  65.             Serial.print("-");
  66.             Serial.print(myRTC.getMonth(century), DEC);
  67.             Serial.print("-");
  68.             Serial.print(myRTC.getDate(), DEC);
  69.             Serial.print(" ");
  70.             Serial.print(myRTC.getHour(h12Flag, pmFlag), DEC);  // 24 小时制
  71.             Serial.print(":");
  72.             Serial.print(myRTC.getMinute(), DEC);
  73.             Serial.print(":");
  74.             Serial.println(myRTC.getSecond(), DEC);
  75.         }
  76.         // **提示用户输入新时间**
  77.         Serial.println("请在串口输入新的时间,并以 'x' 结尾以设置 DS3231:");
  78.     }
  79.     delay(1000);  // 每秒刷新一次
  80. }
  81. /*****************************************************************************************************
  82. * **inputDateFromSerial**
  83. *  - 读取用户串口输入的时间数据
  84. *  - 解析并存储到全局变量
  85. *****************************************************************************************************/
  86. void inputDateFromSerial() {
  87.     // **检查串口数据是否完整(结束字符为 'x')**
  88.     boolean isStrComplete = false;
  89.     char inputChar;
  90.     byte temp1, temp2;
  91.     char inputStr[20];  // 存储输入的时间字符串
  92.     uint8_t currentPos = 0;
  93.     while (!isStrComplete) {
  94.         if (Serial.available()) {
  95.             inputChar = Serial.read();
  96.             inputStr[currentPos] = inputChar;
  97.             currentPos += 1;
  98.             // **检查输入是否以 'x' 结尾**
  99.             if (inputChar == 'x') {
  100.                 isStrComplete = true;
  101.             }
  102.         }
  103.     }
  104.     Serial.println(inputStr);  // **打印用户输入的数据**
  105.     // **查找字符串中的 'x' 位置**
  106.     int posX = -1;
  107.     for (uint8_t i = 0; i < 20; i++) {
  108.         if (inputStr[i] == 'x') {
  109.             posX = i;
  110.             break;
  111.         }
  112.     }
  113.     // **ASCII 码 '0' 的值(用于转换字符为数字)**
  114.     uint8_t zeroAscii = '0';
  115.     // **解析年**
  116.     temp1 = (byte)inputStr[posX - 13] - zeroAscii;
  117.     temp2 = (byte)inputStr[posX - 12] - zeroAscii;
  118.     year = temp1 * 10 + temp2;
  119.     // **解析月**
  120.     temp1 = (byte)inputStr[posX - 11] - zeroAscii;
  121.     temp2 = (byte)inputStr[posX - 10] - zeroAscii;
  122.     month = temp1 * 10 + temp2;
  123.     // **解析日期**
  124.     temp1 = (byte)inputStr[posX - 9] - zeroAscii;
  125.     temp2 = (byte)inputStr[posX - 8] - zeroAscii;
  126.     date = temp1 * 10 + temp2;
  127.     // **解析星期**
  128.     dow = (byte)inputStr[posX - 7] - zeroAscii;
  129.     // **解析小时**
  130.     temp1 = (byte)inputStr[posX - 6] - zeroAscii;
  131.     temp2 = (byte)inputStr[posX - 5] - zeroAscii;
  132.     hour = temp1 * 10 + temp2;
  133.     // **解析分钟**
  134.     temp1 = (byte)inputStr[posX - 4] - zeroAscii;
  135.     temp2 = (byte)inputStr[posX - 3] - zeroAscii;
  136.     minute = temp1 * 10 + temp2;
  137.     // **解析秒**
  138.     temp1 = (byte)inputStr[posX - 2] - zeroAscii;
  139.     temp2 = (byte)inputStr[posX - 1] - zeroAscii;
  140.     second = temp1 * 10 + temp2;
  141. }
复制代码


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 前天 14:32

【花雕学编程】Arduino动手做(245)--DS3231高精度时钟模块

代码简单解读

这段代码使用 DS3231 RTC(实时时钟)模块 通过 I2C 通信 接收用户输入的时间数据,并更新 DS3231 的时钟,核心逻辑如下:

1. 初始化 RTC
✅ DS3231 myRTC; → 创建 DS3231 RTC 对象
✅ Wire.begin(); → 启动 I2C 通信
✅ Serial.begin(57600); → 初始化串口,波特率 57600

2. 解释时间格式
✅ Serial.println() → 向用户展示输入格式(YYMMDDwhhmmssx)
✅ 示例输入 → "2004095090242x" 代表 2020 年 4 月 9 日星期四 09:02:42

3. 监听串口输入并解析时间
✅ inputDateFromSerial(); → 读取串口输入数据并转换为 RTC 兼容格式
✅ 解析年、月、日、星期、时、分、秒
✅ myRTC.setClockMode(false); → 设置为 24 小时制
✅ myRTC.setYear(year); → 设置年份
✅ myRTC.setMonth(month); → 设置月份
✅ myRTC.setDate(date); → 设置日期
✅ myRTC.setDoW(dow); → 设置星期
✅ myRTC.setHour(hour); → 设置小时
✅ myRTC.setMinute(minute); → 设置分钟
✅ myRTC.setSecond(second); → 设置秒

4. 每 5 秒回显当前时间
✅ 每秒打印 DS3231 当前时间,以确保时间正确

5. 采集间隔
✅ delay(1000); → 每秒监听串口输入,等待新时间数据

这段代码让 用户通过串口输入时间,并更新 DS3231 的时钟。





回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 前天 14:36

【花雕学编程】Arduino动手做(245)--DS3231高精度时钟模块

实验串口返回情况

【花雕学编程】Arduino动手做(245)--DS3231模块11个小实验图1
回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 前天 17:13

【花雕学编程】Arduino动手做(245)--DS3231高精度时钟模块

  【Arduino】189种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百四十五:DS3231 高精度时钟模块  IIC/I2C接口 实时计时传感器
  项目之九:读取当前时间、温度和闹钟状态

实验开源代码

  1. /*
  2.   【Arduino】189种传感器模块系列实验(资料代码+仿真编程+图形编程)
  3.   实验二百四十五:DS3231 高精度时钟模块  IIC/I2C接口 实时计时传感器
  4.   项目之九:读取当前时间、温度和闹钟状态
  5. */
  6. #include <DS3231.h>  // 引入DS3231时钟库
  7. #include <Wire.h>     // 引入I2C通信库
  8. DS3231 myRTC;        // 创建DS3231对象
  9. bool century = false; // 世纪标志位(20xx年为false,21xx年为true)
  10. bool h12Flag;         // 12小时制标志
  11. bool pmFlag;          // 下午标志(仅在12小时制下有效)
  12. byte alarmDay, alarmHour, alarmMinute, alarmSecond, alarmBits; // 闹钟参数
  13. bool alarmDy, alarmH12Flag, alarmPmFlag; // 闹钟日期/星期标志和12小时制标志
  14. void setup() {
  15.   // 初始化I2C通信(SDA:A4, SCL:A5)
  16.   Wire.begin();
  17.   
  18.   // 初始化串口通信,波特率57600
  19.   Serial.begin(57600);
  20. }
  21. void loop() {
  22.   // 向串口监视器发送当前时钟信息
  23.   
  24.   // 显示年份(20xx格式)
  25.   Serial.print("2");
  26.   if (century) {      // 21世纪(此标志在未来89年内不会用到)
  27.     Serial.print("1");
  28.   } else {
  29.     Serial.print("0");
  30.   }
  31.   Serial.print(myRTC.getYear(), DEC);  // 显示年份后两位
  32.   Serial.print(' ');
  33.   
  34.   // 显示月份
  35.   Serial.print(myRTC.getMonth(century), DEC);
  36.   Serial.print(" ");
  37.   
  38.   // 显示日期
  39.   Serial.print(myRTC.getDate(), DEC);
  40.   Serial.print(" ");
  41.   
  42.   // 显示星期(1-7对应周日到周六)
  43.   Serial.print(myRTC.getDoW(), DEC);
  44.   Serial.print(" ");
  45.   
  46.   // 显示时分秒
  47.   Serial.print(myRTC.getHour(h12Flag, pmFlag), DEC);
  48.   Serial.print(" ");
  49.   Serial.print(myRTC.getMinute(), DEC);
  50.   Serial.print(" ");
  51.   Serial.print(myRTC.getSecond(), DEC);
  52.   
  53.   // 添加AM/PM指示(仅在12小时制下有效)
  54.   if (h12Flag) {
  55.     if (pmFlag) {
  56.       Serial.print(" PM ");
  57.     } else {
  58.       Serial.print(" AM ");
  59.     }
  60.   } else {
  61.     Serial.print(" 24h ");  // 24小时制显示
  62.   }
  63.   
  64.   // 显示温度(DS3231内置高精度温度传感器)
  65.   Serial.print("T=");
  66.   Serial.print(myRTC.getTemperature(), 2);  // 显示温度,保留两位小数
  67.   
  68.   // 显示振荡器状态(O+表示正常,O-表示振荡器可能停止)
  69.   if (myRTC.oscillatorCheck()) {
  70.     Serial.print(" O+");  // 振荡器正常工作
  71.   } else {
  72.     Serial.print(" O-");  // 振荡器可能停止,时间可能不准确
  73.   }
  74.   
  75.   // 显示闹钟触发状态
  76.   if (myRTC.checkIfAlarm(1)) {
  77.     Serial.print(" A1!");  // 闹钟1触发
  78.   }
  79.   
  80.   if (myRTC.checkIfAlarm(2)) {
  81.     Serial.print(" A2!");  // 闹钟2触发
  82.   }
  83.   
  84.   // 换行
  85.   Serial.println();
  86.   
  87.   // 显示闹钟1设置信息
  88.   Serial.print("Alarm 1: ");
  89.   myRTC.getA1Time(alarmDay, alarmHour, alarmMinute, alarmSecond, alarmBits, alarmDy, alarmH12Flag, alarmPmFlag);
  90.   Serial.print(alarmDay, DEC);
  91.   if (alarmDy) {
  92.     Serial.print(" DoW");  // 按星期触发
  93.   } else {
  94.     Serial.print(" Date"); // 按日期触发
  95.   }
  96.   Serial.print(' ');
  97.   Serial.print(alarmHour, DEC);
  98.   Serial.print(' ');
  99.   Serial.print(alarmMinute, DEC);
  100.   Serial.print(' ');
  101.   Serial.print(alarmSecond, DEC);
  102.   Serial.print(' ');
  103.   if (alarmH12Flag) {
  104.     if (alarmPmFlag) {
  105.       Serial.print("pm ");
  106.     } else {
  107.       Serial.print("am ");
  108.     }
  109.   }
  110.   if (myRTC.checkAlarmEnabled(1)) {
  111.     Serial.print("enabled");  // 闹钟1已启用
  112.   }
  113.   Serial.println();
  114.   
  115.   // 显示闹钟2设置信息
  116.   Serial.print("Alarm 2: ");
  117.   myRTC.getA2Time(alarmDay, alarmHour, alarmMinute, alarmBits, alarmDy, alarmH12Flag, alarmPmFlag);
  118.   Serial.print(alarmDay, DEC);
  119.   if (alarmDy) {
  120.     Serial.print(" DoW");  // 按星期触发
  121.   } else {
  122.     Serial.print(" Date"); // 按日期触发
  123.   }
  124.   Serial.print(" ");
  125.   Serial.print(alarmHour, DEC);
  126.   Serial.print(" ");
  127.   Serial.print(alarmMinute, DEC);
  128.   Serial.print(" ");
  129.   if (alarmH12Flag) {
  130.     if (alarmPmFlag) {
  131.       Serial.print("pm");
  132.     } else {
  133.       Serial.print("am");
  134.     }
  135.   }
  136.   if (myRTC.checkAlarmEnabled(2)) {
  137.     Serial.print("enabled");  // 闹钟2已启用
  138.   }
  139.   
  140.   // 显示闹钟触发条件位(二进制格式)
  141.   Serial.println();
  142.   Serial.print("Alarm bits: ");
  143.   Serial.println(alarmBits, BIN);
  144.   
  145.   // 空行分隔,每秒更新一次
  146.   Serial.println();
  147.   delay(1000);
  148. }   
复制代码


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 前天 17:16

【花雕学编程】Arduino动手做(245)--DS3231高精度时钟模块

代码简单解读

这段代码使用 DS3231 实时时钟(RTC)模块 通过 I2C 通信 读取当前时间、温度和闹钟状态,并在 串口监视器 输出,核心逻辑如下:

1. 初始化 RTC
✅ DS3231 myRTC; → 创建 DS3231 实例
✅ Wire.begin(); → 启动 I2C 通信
✅ Serial.begin(57600); → 初始化串口通信,波特率 57600

2. 读取时间数据
✅ myRTC.getYear(); → 获取年份
✅ myRTC.getMonth(); → 获取月份
✅ myRTC.getDate(); → 获取日期
✅ myRTC.getDoW(); → 获取星期
✅ myRTC.getHour(h12Flag, pmFlag); → 获取小时(支持 AM/PM 显示)
✅ myRTC.getMinute(); → 获取分钟
✅ myRTC.getSecond(); → 获取秒数

3. 读取温度数据
✅ myRTC.getTemperature(); → 获取 DS3231 内部温度传感器数据

4. 监测 RTC 运行状态
✅ myRTC.oscillatorCheck(); → 检查 RTC 振荡器是否正常工作
✅ myRTC.checkIfAlarm(1); → 检查 Alarm 1 是否触发
✅ myRTC.checkIfAlarm(2); → 检查 Alarm 2 是否触发

5. 读取闹钟设定
✅ myRTC.getA1Time(); → 获取 Alarm 1 的设定时间
✅ myRTC.getA2Time(); → 获取 Alarm 2 的设定时间
✅ myRTC.checkAlarmEnabled(1); → 检查 Alarm 1 是否启用
✅ myRTC.checkAlarmEnabled(2); → 检查 Alarm 2 是否启用

6. 采集间隔
✅ delay(1000); → 每秒更新一次数据

这段代码让 DS3231 RTC 模块不断读取时间、日期、温度和闹钟状态,并在串口监视器显示。




回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 前天 17:19

【花雕学编程】Arduino动手做(245)--DS3231高精度时钟模块

实验串口返回情况

【花雕学编程】Arduino动手做(245)--DS3231模块11个小实验图1
回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 前天 18:22

【花雕学编程】Arduino动手做(245)--DS3231高精度时钟模块

  【Arduino】189种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百四十五:DS3231 高精度时钟模块  IIC/I2C接口 实时计时传感器
  项目之十:将时间居中显示在 OLED 屏幕上

安装RTClib.h库 (https://github.com/adafruit/RTClib

【花雕学编程】Arduino动手做(245)--DS3231模块11个小实验图1

回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 前天 18:25

【花雕学编程】Arduino动手做(245)--DS3231高精度时钟模块

  【Arduino】189种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百四十五:DS3231 高精度时钟模块  IIC/I2C接口 实时计时传感器
  项目之十:将时间居中显示在 OLED 屏幕上

实验开源代码

  1. /*
  2.   【Arduino】189种传感器模块系列实验(资料代码+仿真编程+图形编程)
  3.   实验二百四十五:DS3231 高精度时钟模块  IIC/I2C接口 实时计时传感器
  4.   项目之十:将时间居中显示在 OLED 屏幕上
  5. */
  6. #include <Wire.h>               // **引入 I2C 通信库**
  7. #include <Adafruit_GFX.h>       // **引入 Adafruit GFX 图形库**
  8. #include <Adafruit_SSD1306.h>   // **引入 Adafruit SSD1306 OLED 显示库**
  9. #include <RTClib.h>             // **引入 DS3231 RTC 库**
  10. #define SCREEN_WIDTH 128  // **OLED 屏幕宽度(单位:像素)**
  11. #define SCREEN_HEIGHT 64  // **OLED 屏幕高度(单位:像素)**
  12. // **创建 SSD1306 OLED 显示对象,使用 I2C 进行通信**
  13. Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
  14. // **创建 DS3231 RTC 对象**
  15. RTC_DS3231 rtc;
  16. // **用于存储时间字符串**
  17. String time;
  18. void setup() {
  19.     Serial.begin(9600);  // **初始化串口通信**
  20.    
  21.     // **初始化 OLED 显示屏**
  22.     if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {  // **设置 I2C 地址为 0x3C**
  23.         Serial.println(F("SSD1306 显示屏初始化失败"));
  24.         while (true);  // **进入死循环,防止继续执行错误代码**
  25.     }
  26.     delay(2000);  // **等待 2 秒,确保 OLED 组件启动**
  27.     oled.clearDisplay();  // **清空 OLED 屏幕**
  28.     oled.setTextSize(1);  // **设置文本大小**
  29.     oled.setTextColor(WHITE);  // **设置文本颜色**
  30.     oled.setCursor(0, 10);  // **设置文本显示位置**
  31.     // **初始化 DS3231 RTC 模块**
  32.     if (!rtc.begin()) {  
  33.         Serial.println("找不到 RTC 模块");
  34.         Serial.flush();
  35.         while (true);  // **进入死循环,避免继续执行错误代码**
  36.     }
  37.     // **同步 RTC 时间,设置为编译时的日期和时间**
  38.     rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));  
  39.     // **预留 10 个字节内存,优化 String 变量存储,避免碎片化**
  40.     time.reserve(10);  
  41. }
  42. void loop() {
  43.     // **从 RTC 读取当前时间**
  44.     DateTime now = rtc.now();  
  45.     time = "";  // **清空字符串**
  46.     time += now.hour();  // **获取小时**
  47.     time += ':';  
  48.     time += now.minute();  // **获取分钟**
  49.     time += ':';
  50.     time += now.second();  // **获取秒数**
  51.     oledDisplayCenter(time);  // **调用 OLED 显示函数**
  52. }
  53. /*****************************************************************************************************
  54. * **oledDisplayCenter**
  55. *  - 计算文本大小,使其居中显示在 OLED 屏幕上
  56. *  - 然后将时间数据显示在屏幕中央
  57. *****************************************************************************************************/
  58. void oledDisplayCenter(String text) {
  59.     int16_t x1, y1;
  60.     uint16_t width, height;
  61.     // **获取文本的宽度和高度**
  62.     oled.getTextBounds(text, 0, 0, &x1, &y1, &width, &height);
  63.     // **清屏**
  64.     oled.clearDisplay();
  65.     // **计算居中位置**
  66.     oled.setCursor((SCREEN_WIDTH - width) / 2, (SCREEN_HEIGHT - height) / 2);
  67.    
  68.     // **显示时间字符串**
  69.     oled.println(text);
  70.     oled.display();  // **刷新 OLED 屏幕**
  71. }
复制代码


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail