×

如何将RTC DS1与Arduino结合使用来进行提醒

消耗积分:0 | 格式:zip | 大小:0.01 MB | 2023-01-03

张伟

分享资料个

描述

概述

在许多电子项目中,需要根据时间或日期运行一个操作,并且时间和日期的计算不应该在系统关闭时停止。为此,使用了实时时钟 (RTC) 模块。在本教程中,您将学习如何将 RTC DS1 与 Arduino 结合使用来进行提醒。

你将学到什么:

  • 什么是实时时钟
  • DS1307模块介绍
  • 如何在 Arduino 上使用 DS1307
  • 如何做一个智能提醒

 

 
poYBAGOrtkuAH6NgAACsKvtN9n8397.jpg
 

什么是实时时钟?

实时时钟或 RTC 是一种跟踪当前时间的系统,可用于任何需要保持准确时间的设备。

 

 
pYYBAGOrtk6AadniAAAzIYaIJMA516.jpg
 

您也可以在不使用 RTC 系统的情况下跟踪准确时间,但 RTC 具有一些重要的优势。以下是其中一些优点:

  • 低功耗
  • 从时间计算中释放系统时间(此功能很关键,因为在许多情况下 CPU 正在执行一些微妙的任务,例如接收传感器数据。如果您不使用 RTC,CPU 还必须跟踪时间,这可能会破坏处理器主任务。)
  • 高准确率

RTC 通常有备用电源,因此它们可以在主电源关闭或不可用时继续计时。RTC 通常使用 32.768 kHz 晶体振荡器。但为什么是 32、768?32768 等于 215,因此可以轻松生成 1 秒。另外,晶体必须小,宽度适当,功耗低,使用32876 Hz即可满足。较高的频率是较大且易碎的晶体,而较低的频率比 32、768KHz 具有更多的功耗。

您也可以在不使用 RTC 系统的情况下跟踪准确时间,但 RTC 具有一些重要的优势。以下是其中一些优点:

  • 低功耗
  • 从时间计算中释放系统时间(此功能很关键,因为在许多情况下 CPU 正在执行一些微妙的任务,例如接收传感器数据。如果您不使用 RTC,CPU 还必须跟踪时间,这可能会破坏处理器主任务。)
  • 高准确率

RTC 通常有备用电源,因此它们可以在主电源关闭或不可用时继续计时。RTC 通常使用 32.768 kHz 晶体振荡器。但为什么是 32、768?32768 等于 215,因此可以轻松生成 1 秒。另外,晶体必须小,宽度适当,功耗低,使用32876 Hz即可满足。较高的频率是较大且易碎的晶体,而较低的频率比 32、768KHz 具有更多的功耗。

DS1307 模块特性和规格

DS1307 模块是最实惠和最常见的 RTC 模块之一。它可以准确地记录秒、分、时、日、月和年。

DS1307 的一些重要特性是:

  • 产生可编程方波的能力
  • 低电流使用;在电池备份模式下低于 500nA
  • 将日期设置为 2100 年的能力
  • I2C 串行接口

DS1307 模块能够安装 3 伏 CR2023 备用电池。该模块上还有一个嵌入式 EEPROM 24c32 存储器,可以保存 32kb 的数据。此外,您还可以通过在内置位置安装一个DS18B20传感器来测量环境温度。您还可以从 BAT 引脚读取备用电池电压。

 

 
poYBAGOrtlCAQTYzAAA47qk4vQc935.jpg
 

 

 
pYYBAGOrtlKAVyuNAABt34nPbaM331.png
 

将 DS1307 与 Arduino 连接

该模块使用简单,RTC部分使用I2C协议与微控制器通信。

电路

 

 
pYYBAGOuPMSAVLHrAACvrZuQxhI561.jpg
 

代码

您需要 RTClib 库才能将 DS1307 与 Arduino 一起使用。

现在将以下代码上传到您的板上,并在串行监视器窗口中查看结果。

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
#include 
#include "RTClib.h"
RTC_DS1307 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
void setup () {
 while (!Serial); // for Leonardo/Micro/Zero
 Serial.begin(57600);
 if (! rtc.begin()) {
   Serial.println("Couldn't find RTC");
   while (1);
 }
 if (! rtc.isrunning()) {
   Serial.println("RTC is NOT running!");
   // following line sets the RTC to the date & time this sketch was compiled
   rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
   // This line sets the RTC with an explicit date & time, for example to set
   // January 21, 2014 at 3am you would call:
   // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
 }
}
void loop () {
 DateTime now = rtc.now();
 Serial.print(now.year(), DEC);
 Serial.print('/');
 Serial.print(now.month(), DEC);
 Serial.print('/');
 Serial.print(now.day(), DEC);
 Serial.print(" (");
 Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
 Serial.print(") ");
 Serial.print(now.hour(), DEC);
 Serial.print(':');
 Serial.print(now.minute(), DEC);
 Serial.print(':');
 Serial.print(now.second(), DEC);
 Serial.println();
 Serial.print(" since midnight 1/1/1970 = ");
 Serial.print(now.unixtime());
 Serial.print("s = ");
 Serial.print(now.unixtime() / 86400L);
 Serial.println("d");
 // calculate a date which is 7 days and 30 seconds into the future
 DateTime future (now + TimeSpan(7, 12, 30, 6));
 Serial.print(" now + 7d + 30s: ");
 Serial.print(future.year(), DEC);
 Serial.print('/');
 Serial.print(future.month(), DEC);
 Serial.print('/');
 Serial.print(future.day(), DEC);
 Serial.print(' ');
 Serial.print(future.hour(), DEC);
 Serial.print(':');
 Serial.print(future.minute(), DEC);
 Serial.print(':');
 Serial.print(future.second(), DEC);
 Serial.println();
 Serial.println();
 delay(3000);
}

您可以通过两种方式设置日期和时间。首先是使用以下代码在您的 PC 上设置它们:

rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); 

第二种方法是使用以下代码手动设置日期和时间:

rtc.adjust(DateTime(YEAR, MONTH, DAY, HOUR , MINUTE, SECOND));

注意您只需在项目中设置一次日期和时间,之后,您应该从代码中删除相关行。否则,每次打开系统时都会设置日期和时间,这可能会导致一些错误。

注意在您的 Arduino 上上传代码需要几秒钟,与实时相比,这可能会导致您的时间延迟几秒钟。所以我们建议您在上传代码之前将您的时间提前几秒。

奖励项目:做一个智能提醒

您可以使用 DS1307 模块制作一个简单而有用的提醒。

其他所需材料

LCD 键盘护罩

无源蜂鸣器

电路

 

 
pYYBAGOuPMaAReCAAADlRc4GyYs917.jpg
 

 

代码

将以下代码上传到您的 Arduino 板上,您的智能提醒已准备就绪!

/*
Arduino Reminder
modified on 13 March 2019
by Saeed Hosseini @ Electropeak
https://electropeak.com/learn/
*/
#include #include #include "RTClib.h"
#define NOTE_C4  262
#define NOTE_D4  294
#define NOTE_E4  330
#define NOTE_F4  349
#define NOTE_G4  392
#define NOTE_A4  440
#define NOTE_B4  494
#define NOTE_C5  523
#define NOTE_D5  587
#define NOTE_E5  659
#define NOTE_F5  698
#define NOTE_G5  784
#define NOTE_A5  880
#define NOTE_B5  988
//LCD Pin to Arduino
const int pin_RS = 8;
const int pin_EN = 9;
const int pin_d4 = 4;
const int pin_d5 = 5;
const int pin_d6 = 6;
const int pin_d7 = 7;
const int pin_BL = 10;
//BUZZER Pin to Arduino
const int buzzer = 2;  
LiquidCrystal lcd( pin_RS,  pin_EN,  pin_d4,  pin_d5,  pin_d6,  pin_d7);
RTC_DS1307 rtc;
byte smiley[8] = {
 B00000,
 B10001,
 B00000,
 B00000,
 B10001,
 B01110,
 B00000,
};
String menuItems[] = {"1-Medicin", "2-Wake up", "3-Go out"};
int songspeed = 1.5;
int flag = 0;
int menuPage = 0;
int maxMenuPages = round(((sizeof(menuItems) / sizeof(String)) / 2) + .5);
int cursorPosition = 0;
int btn;
int h = 0, m = 0;
int duration[] = {         //duration of each note (in ms) Quarter Note is set to 250 ms
 125, 125, 250, 125, 125,
 125, 125, 250, 125, 125,
 125, 125, 250, 125, 125,
 125, 125, 375, 125,
 125, 125, 250, 125, 125,
 125, 125, 250, 125, 125,
 125, 125, 250, 125, 125,
 125, 125, 375, 125,
 125, 125, 250, 125, 125,
 125, 125, 250, 125, 125,
 125, 125, 250, 125, 125,
 125, 125, 125, 250, 125,
 125, 125, 250, 125, 125,
 250, 125, 250, 125,
 125, 125, 250, 125, 125,
 125, 125, 375, 375,
 250, 125,
 //Rpeat of First Part
 125, 125, 250, 125, 125,
 125, 125, 250, 125, 125,
 125, 125, 375, 125,
 125, 125, 250, 125, 125,
 125, 125, 250, 125, 125,
 125, 125, 250, 125, 125,
 125, 125, 375, 125,
 125, 125, 250, 125, 125,
 125, 125, 250, 125, 125,
 125, 125, 250, 125, 125,
 125, 125, 125, 250, 125,
 125, 125, 250, 125, 125,
 250, 125, 250, 125,
 125, 125, 250, 125, 125,
 125, 125, 375, 375,
 //End of Repeat
 250, 125, 375, 250, 125, 375,
 125, 125, 125, 125, 125, 125, 125, 125, 375,
 250, 125, 375, 250, 125, 375,
 125, 125, 125, 125, 125, 500,
 250, 125, 375, 250, 125, 375,
 125, 125, 125, 125, 125, 125, 125, 125, 375,
 250, 125, 375, 250, 125, 375,
 125, 125, 125, 125, 125, 500
};
int notes[] = {       //Note of the song, 0 is a rest/pulse
 NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0,
 NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
 NOTE_C5, NOTE_D5, NOTE_B4, NOTE_B4, 0,
 NOTE_A4, NOTE_G4, NOTE_A4, 0,
 NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0,
 NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
 NOTE_C5, NOTE_D5, NOTE_B4, NOTE_B4, 0,
 NOTE_A4, NOTE_G4, NOTE_A4, 0,
 NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0,
 NOTE_A4, NOTE_C5, NOTE_D5, NOTE_D5, 0,
 NOTE_D5, NOTE_E5, NOTE_F5, NOTE_F5, 0,
 NOTE_E5, NOTE_D5, NOTE_E5, NOTE_A4, 0,
 NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
 NOTE_D5, NOTE_E5, NOTE_A4, 0,
 NOTE_A4, NOTE_C5, NOTE_B4, NOTE_B4, 0,
 NOTE_C5, NOTE_A4, NOTE_B4, 0,
 NOTE_A4, NOTE_A4,
 //Repeat of first part
 NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
 NOTE_C5, NOTE_D5, NOTE_B4, NOTE_B4, 0,
 NOTE_A4, NOTE_G4, NOTE_A4, 0,
 NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0,
 NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
 NOTE_C5, NOTE_D5, NOTE_B4, NOTE_B4, 0,
 NOTE_A4, NOTE_G4, NOTE_A4, 0,
 NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0,
 NOTE_A4, NOTE_C5, NOTE_D5, NOTE_D5, 0,
 NOTE_D5, NOTE_E5, NOTE_F5, NOTE_F5, 0,
 NOTE_E5, NOTE_D5, NOTE_E5, NOTE_A4, 0,
 NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
 NOTE_D5, NOTE_E5, NOTE_A4, 0,
 NOTE_A4, NOTE_C5, NOTE_B4, NOTE_B4, 0,
 NOTE_C5, NOTE_A4, NOTE_B4, 0,
 //End of Repeat
 NOTE_E5, 0, 0, NOTE_F5, 0, 0,
 NOTE_E5, NOTE_E5, 0, NOTE_G5, 0, NOTE_E5, NOTE_D5, 0, 0,
 NOTE_D5, 0, 0, NOTE_C5, 0, 0,
 NOTE_B4, NOTE_C5, 0, NOTE_B4, 0, NOTE_A4,
 NOTE_E5, 0, 0, NOTE_F5, 0, 0,
 NOTE_E5, NOTE_E5, 0, NOTE_G5, 0, NOTE_E5, NOTE_D5, 0, 0,
 NOTE_D5, 0, 0, NOTE_C5, 0, 0,
 NOTE_B4, NOTE_C5, 0, NOTE_B4, 0, NOTE_A4
};
void show_time()
{
 lcd.clear();
 DateTime now = rtc.now();
 lcd.setCursor(0, 0);
 lcd.print("* Electropeak *");
 lcd.setCursor(5, 0);
 lcd.print(now.hour(), DEC);
 lcd.print(":");
 lcd.print(now.minute(), DEC);
 if (now.hour() == h && now.minute() == m)
 {
   lcd.clear();
   lcd.setCursor(0 , 0);
   switch (flag)
   {
     case 1:
       lcd.print("** ءedicine Time **");
       break;
     case 2:
       lcd.print("You'r late!!");
       lcd.setCursor(0, 1);
       lcd.print("Come onnnnnnn");
       break;
     case 3:
       lcd.print("Befor you go:");
       lcd.setCursor(0, 1);
       lcd.print("Wallet,Keys,...");
       break;
   }
   for (int i = 0; i < 203; i++) {       //203 is the total number of music notes in the song
     int wait = duration[i] * songspeed;
     tone(buzzer, notes[i], wait);        //tone(pin,frequency,duration)
     delay(wait);
   }
 }
 delay(2000);
}
void welcome_menu(int show_delay)
{
 lcd.setCursor(0, 0);
 lcd.print("Arduino reminder");
 lcd.createChar(1, smiley);
 lcd.setCursor(7, 1);
 lcd.write(1);
 delay(show_delay);
 lcd.clear();
}
int detect_button() {
 int readkey = 0;
 int result = 0;
 int activeButton = 0;
 while (activeButton == 0) {
   readkey = analogRead(0);
   if (readkey < 790) {
     delay(100);
     readkey = analogRead(0);
     if (readkey < 60) {
       result = 1; // right
     } else if (readkey < 200) {
       result = 2; // up
     } else if (readkey < 400) {
       result = 3; // down
     } else if (readkey < 600) {
       result = 4; // down
     } else if (readkey < 800) { result = 5; // select } return result; } } activeButton = 1; } int choose_menu() { lcd.clear(); lcd.print("Remmeber what?"); while (btn != 5) { btn = detect_button(); if (btn == 1) { if (menuPage > maxMenuPages) menuPage = 0;
     lcd.clear();
     lcd.print("Remmeber what?");
     lcd.setCursor(0, 1);
     lcd.print(menuItems[menuPage]);
     menuPage = menuPage + 1;
   }
 }
 return menuPage;
}
void set_alarm() {
 int sit = 0;
 lcd.clear();
 lcd.setCursor(1, 0);
 lcd.print("**Set Alarm**");
 lcd.setCursor(5, 1);
 lcd.print("00:00");
 while (sit != 1)
 {
   sit = detect_button();
   if (sit == 2)
   {
     lcd.clear();
     lcd.setCursor(1, 0);
     lcd.print("**Set Alarm**");
     h++;
     if (h > 23)
     {
       h = 0;
     }
     lcd.setCursor(5, 1);
     lcd.print(h);
     lcd.print(":00");
   }
   else if (sit == 3)
   {
     lcd.clear();
     lcd.setCursor(1, 0);
     lcd.print("**Set Alarm**");
     h--;
     if (h < 0) { h = 23; } lcd.setCursor(5, 1); lcd.print(h); lcd.print(":00"); } } while (sit != 5) { sit = detect_button(); if (sit == 2) { lcd.clear(); lcd.setCursor(1, 0); lcd.print("**Set Alarm**"); m++; if (m > 59)
     {
       m = 0;
     }
     lcd.setCursor(5, 1);
     lcd.print(h);
     lcd.print(":");
     lcd.print(m);
   }
   else if (sit == 3)
   {
     lcd.clear();
     lcd.setCursor(1, 0);
     lcd.print("**Set Alarm**");
     m--;
     if (m < 0)
     {
       m = 59;
     }
     lcd.setCursor(5, 1);
     lcd.print(h);
     lcd.print(":");
     lcd.print(m);
   }
 }
 lcd.clear();
 lcd.setCursor(0, 0);
 lcd.print("Alarm set");
 lcd.setCursor(0, 1);
 lcd.print("I'll be on time");
 delay(1500);
}
void setup() {
 lcd.begin(16, 2);
 rtc.begin();
 pinMode(buzzer, OUTPUT);
 welcome_menu(1000);
 flag = choose_menu();
 set_alarm();
}
void loop()
{
 show_time();
} 

 

如果您需要有关 LCD Keypad Shield 的更多信息,请阅读Using 1602 LCD Keypad Shield w/ Arduino [+Practical Projects]。

打开设备后,LCD 上会显示一个菜单。选择您的提醒模式(您可以通过右键在选项之间移动并通过按选择键选择您想要的模式。)然后设置您的闹钟时间(通过向上和向下键设置小时,然后通过向右转到分钟并设置它.) 现在开始您的日常工作,不用担心!

下一步是什么?

  • 试着做一个叫醒闹钟
  • 在 DS1307 模块上安装温度传感器,尝试用 TFT LCD 制作一个显示环境温度的酷炫图形时钟 2, 4

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !