风筝
发表于: 2019-8-18 22:48:23 | 显示全部楼层

在许多电子项目中,必须根据时间或日期运行操作。当系统关闭时,不应停止计算时间和日期。为此,使用实时时钟(RTC)模块。在本篇文章中,您将学习如何使用RTC DS1307模块和Arduino开发板制作一个提醒器。

ds1307-arduino-800x600.jpg


什么是实时时钟?

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

DS1307-arduino-tutorial.jpg

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

●    功耗低

●    从时间计算中释放系统时间(此功能至关重要,因为在许多情况下CPU正在执行一些精细的任务,如接收传感器数据。如果您不使用RTC,CPU还必须跟踪时间并且它可能会中断处理器主任务。)

●    高精确度


RTC通常具有备用电源,因此它们可以在主电源关闭或不可用时继续保持时间。 RTC通常使用32.768 kHz晶体振荡器。但为什么32,768? 32768等于2的15次方,因此可以轻松生成1秒。此外,晶体必须小,宽度适中,功耗低,使用32876 Hz即可满足要求。频率越高,晶体越脆弱,频率越低,功耗就越大。


DS1307模块功能和规格

DS1307模块是最经济实惠且最常见的RTC模块之一。它可以准确地跟踪秒、分、小时、日、月和年。


DS1307的一些重要功能包括:

●    生成可编程方波的能力

●    低电流使用;电池备份模式下低于500nA

●    能够将日期设置为2100年

●    I2C串行接口


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

DS1307-pinout.jpg


连接DS1307到Arduino开发板

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


所需的材料

●    Arduino Uno R3开发板

●    DS1307模块

●    跳线

●    Arduino IDE


电路

ds1307_simple.jpg


代码

您需要Adafruit的RTClib库才能将DS1307与Arduino配合使用。现在在电路板上上传以下代码,并在串行监视器窗口中查看结果。

以下代码是库的示例。

  1. // Date and time functions using a DS1307 RTC connected via I2C and Wire lib
  2. #include <Wire.h>
  3. #include "RTClib.h"

  4. RTC_DS1307 rtc;

  5. char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

  6. void setup () {
  7.   while (!Serial); // for Leonardo/Micro/Zero

  8.   Serial.begin(57600);
  9.   if (! rtc.begin()) {
  10.     Serial.println("Couldn't find RTC");
  11.     while (1);
  12.   }

  13.   if (! rtc.isrunning()) {
  14.     Serial.println("RTC is NOT running!");
  15.     // following line sets the RTC to the date & time this sketch was compiled
  16.     rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  17.     // This line sets the RTC with an explicit date & time, for example to set
  18.     // January 21, 2014 at 3am you would call:
  19.     // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  20.   }
  21. }

  22. void loop () {
  23.   DateTime now = rtc.now();

  24.   Serial.print(now.year(), DEC);
  25.   Serial.print('/');
  26.   Serial.print(now.month(), DEC);
  27.   Serial.print('/');
  28.   Serial.print(now.day(), DEC);
  29.   Serial.print(" (");
  30.   Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
  31.   Serial.print(") ");
  32.   Serial.print(now.hour(), DEC);
  33.   Serial.print(':');
  34.   Serial.print(now.minute(), DEC);
  35.   Serial.print(':');
  36.   Serial.print(now.second(), DEC);
  37.   Serial.println();

  38.   Serial.print(" since midnight 1/1/1970 = ");
  39.   Serial.print(now.unixtime());
  40.   Serial.print("s = ");
  41.   Serial.print(now.unixtime() / 86400L);
  42.   Serial.println("d");

  43.   // calculate a date which is 7 days and 30 seconds into the future
  44.   DateTime future (now + TimeSpan(7, 12, 30, 6));

  45.   Serial.print(" now + 7d + 30s: ");
  46.   Serial.print(future.year(), DEC);
  47.   Serial.print('/');
  48.   Serial.print(future.month(), DEC);
  49.   Serial.print('/');
  50.   Serial.print(future.day(), DEC);
  51.   Serial.print(' ');
  52.   Serial.print(future.hour(), DEC);
  53.   Serial.print(':');
  54.   Serial.print(future.minute(), DEC);
  55.   Serial.print(':');
  56.   Serial.print(future.second(), DEC);
  57.   Serial.println();

  58.   Serial.println();
  59.   delay(3000);
  60. }
复制代码

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

  1. rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
复制代码

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

  1. rtc.adjust(DateTime(YEAR, MONTH, DAY, HOUR , MINUTE, SECOND));
复制代码

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


制作一个智能的提醒器

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


所需的材料

●    Arduino Uno R3开发板

●    DS1307模块

●    LCD键盘模块

●    被动式蜂鸣器

●    跳线

●    Arduino IDE


电路

reminder.jpg


代码

在您的Arduino开发板上传以下代码后,您的智能提醒器准备就绪!

  1. /*

  2. Arduino Reminder

  3. modified on 13 March 2019
  4. by Saeed Hosseini @ Electropeak
  5. https://electropeak.com/learn/

  6. */

  7. #include <LiquidCrystal.h>
  8. #include <Wire.h>
  9. #include "RTClib.h"


  10. #define NOTE_C4  262
  11. #define NOTE_D4  294
  12. #define NOTE_E4  330
  13. #define NOTE_F4  349
  14. #define NOTE_G4  392
  15. #define NOTE_A4  440
  16. #define NOTE_B4  494
  17. #define NOTE_C5  523
  18. #define NOTE_D5  587
  19. #define NOTE_E5  659
  20. #define NOTE_F5  698
  21. #define NOTE_G5  784
  22. #define NOTE_A5  880
  23. #define NOTE_B5  988

  24. //LCD Pin to Arduino
  25. const int pin_RS = 8;
  26. const int pin_EN = 9;
  27. const int pin_d4 = 4;
  28. const int pin_d5 = 5;
  29. const int pin_d6 = 6;
  30. const int pin_d7 = 7;
  31. const int pin_BL = 10;
  32. //BUZZER Pin to Arduino
  33. const int buzzer = 2;  
  34.                        
  35. LiquidCrystal lcd( pin_RS,  pin_EN,  pin_d4,  pin_d5,  pin_d6,  pin_d7);
  36. RTC_DS1307 rtc;

  37. byte smiley[8] = {
  38.   B00000,
  39.   B10001,
  40.   B00000,
  41.   B00000,
  42.   B10001,
  43.   B01110,
  44.   B00000,
  45. };


  46. String menuItems[] = {"1-Medicin", "2-Wake up", "3-Go out"};

  47. int songspeed = 1.5;

  48. int flag = 0;
  49. int menuPage = 0;
  50. int maxMenuPages = round(((sizeof(menuItems) / sizeof(String)) / 2) + .5);
  51. int cursorPosition = 0;
  52. int btn;
  53. int h = 0, m = 0;

  54. int duration[] = {         //duration of each note (in ms) Quarter Note is set to 250 ms
  55.   125, 125, 250, 125, 125,
  56.   125, 125, 250, 125, 125,
  57.   125, 125, 250, 125, 125,
  58.   125, 125, 375, 125,

  59.   125, 125, 250, 125, 125,
  60.   125, 125, 250, 125, 125,
  61.   125, 125, 250, 125, 125,
  62.   125, 125, 375, 125,

  63.   125, 125, 250, 125, 125,
  64.   125, 125, 250, 125, 125,
  65.   125, 125, 250, 125, 125,
  66.   125, 125, 125, 250, 125,

  67.   125, 125, 250, 125, 125,
  68.   250, 125, 250, 125,
  69.   125, 125, 250, 125, 125,
  70.   125, 125, 375, 375,

  71.   250, 125,
  72.   //Rpeat of First Part
  73.   125, 125, 250, 125, 125,
  74.   125, 125, 250, 125, 125,
  75.   125, 125, 375, 125,

  76.   125, 125, 250, 125, 125,
  77.   125, 125, 250, 125, 125,
  78.   125, 125, 250, 125, 125,
  79.   125, 125, 375, 125,

  80.   125, 125, 250, 125, 125,
  81.   125, 125, 250, 125, 125,
  82.   125, 125, 250, 125, 125,
  83.   125, 125, 125, 250, 125,

  84.   125, 125, 250, 125, 125,
  85.   250, 125, 250, 125,
  86.   125, 125, 250, 125, 125,
  87.   125, 125, 375, 375,
  88.   //End of Repeat

  89.   250, 125, 375, 250, 125, 375,
  90.   125, 125, 125, 125, 125, 125, 125, 125, 375,
  91.   250, 125, 375, 250, 125, 375,
  92.   125, 125, 125, 125, 125, 500,

  93.   250, 125, 375, 250, 125, 375,
  94.   125, 125, 125, 125, 125, 125, 125, 125, 375,
  95.   250, 125, 375, 250, 125, 375,
  96.   125, 125, 125, 125, 125, 500
  97. };


  98. int notes[] = {       //Note of the song, 0 is a rest/pulse
  99.   NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0,
  100.   NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
  101.   NOTE_C5, NOTE_D5, NOTE_B4, NOTE_B4, 0,
  102.   NOTE_A4, NOTE_G4, NOTE_A4, 0,

  103.   NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0,
  104.   NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
  105.   NOTE_C5, NOTE_D5, NOTE_B4, NOTE_B4, 0,
  106.   NOTE_A4, NOTE_G4, NOTE_A4, 0,

  107.   NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0,
  108.   NOTE_A4, NOTE_C5, NOTE_D5, NOTE_D5, 0,
  109.   NOTE_D5, NOTE_E5, NOTE_F5, NOTE_F5, 0,
  110.   NOTE_E5, NOTE_D5, NOTE_E5, NOTE_A4, 0,

  111.   NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
  112.   NOTE_D5, NOTE_E5, NOTE_A4, 0,
  113.   NOTE_A4, NOTE_C5, NOTE_B4, NOTE_B4, 0,
  114.   NOTE_C5, NOTE_A4, NOTE_B4, 0,

  115.   NOTE_A4, NOTE_A4,
  116.   //Repeat of first part
  117.   NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
  118.   NOTE_C5, NOTE_D5, NOTE_B4, NOTE_B4, 0,
  119.   NOTE_A4, NOTE_G4, NOTE_A4, 0,

  120.   NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0,
  121.   NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
  122.   NOTE_C5, NOTE_D5, NOTE_B4, NOTE_B4, 0,
  123.   NOTE_A4, NOTE_G4, NOTE_A4, 0,

  124.   NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0,
  125.   NOTE_A4, NOTE_C5, NOTE_D5, NOTE_D5, 0,
  126.   NOTE_D5, NOTE_E5, NOTE_F5, NOTE_F5, 0,
  127.   NOTE_E5, NOTE_D5, NOTE_E5, NOTE_A4, 0,

  128.   NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0,
  129.   NOTE_D5, NOTE_E5, NOTE_A4, 0,
  130.   NOTE_A4, NOTE_C5, NOTE_B4, NOTE_B4, 0,
  131.   NOTE_C5, NOTE_A4, NOTE_B4, 0,
  132.   //End of Repeat

  133.   NOTE_E5, 0, 0, NOTE_F5, 0, 0,
  134.   NOTE_E5, NOTE_E5, 0, NOTE_G5, 0, NOTE_E5, NOTE_D5, 0, 0,
  135.   NOTE_D5, 0, 0, NOTE_C5, 0, 0,
  136.   NOTE_B4, NOTE_C5, 0, NOTE_B4, 0, NOTE_A4,

  137.   NOTE_E5, 0, 0, NOTE_F5, 0, 0,
  138.   NOTE_E5, NOTE_E5, 0, NOTE_G5, 0, NOTE_E5, NOTE_D5, 0, 0,
  139.   NOTE_D5, 0, 0, NOTE_C5, 0, 0,
  140.   NOTE_B4, NOTE_C5, 0, NOTE_B4, 0, NOTE_A4
  141. };

  142. void show_time()
  143. {
  144.   lcd.clear();
  145.   DateTime now = rtc.now();
  146.   lcd.setCursor(0, 0);
  147.   lcd.print("* Electropeak *");
  148.   lcd.setCursor(5, 0);
  149.   lcd.print(now.hour(), DEC);
  150.   lcd.print(":");
  151.   lcd.print(now.minute(), DEC);
  152.   if (now.hour() == h && now.minute() == m)
  153.   {
  154.     lcd.clear();
  155.     lcd.setCursor(0 , 0);
  156.     switch (flag)
  157.     {
  158.       case 1:
  159.         lcd.print("** ءedicine Time **");
  160.         break;
  161.       case 2:
  162.         lcd.print("You'r late!!");
  163.         lcd.setCursor(0, 1);
  164.         lcd.print("Come onnnnnnn");
  165.         break;
  166.       case 3:
  167.         lcd.print("Befor you go:");
  168.         lcd.setCursor(0, 1);
  169.         lcd.print("Wallet,Keys,...");
  170.         break;
  171.     }
  172.     for (int i = 0; i < 203; i++) {       //203 is the total number of music notes in the song
  173.       int wait = duration[i] * songspeed;
  174.       tone(buzzer, notes[i], wait);        //tone(pin,frequency,duration)
  175.       delay(wait);
  176.     }
  177.   }
  178.   delay(2000);
  179. }

  180. void welcome_menu(int show_delay)
  181. {
  182.   lcd.setCursor(0, 0);
  183.   lcd.print("Arduino reminder");
  184.   lcd.createChar(1, smiley);
  185.   lcd.setCursor(7, 1);
  186.   lcd.write(1);
  187.   delay(show_delay);
  188.   lcd.clear();
  189. }

  190. int detect_button() {

  191.   int readkey = 0;
  192.   int result = 0;
  193.   int activeButton = 0;

  194.   while (activeButton == 0) {
  195.     readkey = analogRead(0);
  196.     if (readkey < 790) {
  197.       delay(100);
  198.       readkey = analogRead(0);
  199.       if (readkey < 60) {
  200.         result = 1; // right
  201.       } else if (readkey < 200) {
  202.         result = 2; // up
  203.       } else if (readkey < 400) {
  204.         result = 3; // down
  205.       } else if (readkey < 600) {
  206.         result = 4; // down
  207.       } 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;
  208.       lcd.clear();
  209.       lcd.print("Remmeber what?");
  210.       lcd.setCursor(0, 1);
  211.       lcd.print(menuItems[menuPage]);
  212.       menuPage = menuPage + 1;
  213.     }
  214.   }

  215.   return menuPage;
  216. }


  217. void set_alarm() {
  218.   int sit = 0;
  219.   lcd.clear();
  220.   lcd.setCursor(1, 0);
  221.   lcd.print("**Set Alarm**");
  222.   lcd.setCursor(5, 1);
  223.   lcd.print("00:00");
  224.   while (sit != 1)
  225.   {
  226.     sit = detect_button();

  227.     if (sit == 2)
  228.     {
  229.       lcd.clear();
  230.       lcd.setCursor(1, 0);
  231.       lcd.print("**Set Alarm**");
  232.       h++;
  233.       if (h > 23)
  234.       {
  235.         h = 0;
  236.       }
  237.       lcd.setCursor(5, 1);
  238.       lcd.print(h);
  239.       lcd.print(":00");

  240.     }
  241.     else if (sit == 3)
  242.     {
  243.       lcd.clear();
  244.       lcd.setCursor(1, 0);
  245.       lcd.print("**Set Alarm**");
  246.       h--;
  247.       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)
  248.       {
  249.         m = 0;
  250.       }
  251.       lcd.setCursor(5, 1);
  252.       lcd.print(h);
  253.       lcd.print(":");
  254.       lcd.print(m);

  255.     }
  256.     else if (sit == 3)
  257.     {
  258.       lcd.clear();
  259.       lcd.setCursor(1, 0);
  260.       lcd.print("**Set Alarm**");
  261.       m--;
  262.       if (m < 0)
  263.       {
  264.         m = 59;
  265.       }
  266.       lcd.setCursor(5, 1);
  267.       lcd.print(h);
  268.       lcd.print(":");
  269.       lcd.print(m);

  270.     }
  271.   }
  272.   lcd.clear();
  273.   lcd.setCursor(0, 0);
  274.   lcd.print("Alarm set");
  275.   lcd.setCursor(0, 1);
  276.   lcd.print("I'll be on time");
  277.   delay(1500);

  278. }


  279. void setup() {

  280.   lcd.begin(16, 2);
  281.   rtc.begin();
  282.   pinMode(buzzer, OUTPUT);
  283.   welcome_menu(1000);
  284.   flag = choose_menu();
  285.   set_alarm();



  286. }
  287. void loop()
  288. {

  289.   show_time();

  290. }
复制代码

打开设备后,LCD上将显示一个菜单。 选择提醒器模式(您可以通过右键在选项之间移动,然后按选择键选择所需的模式。)然后设置您的闹钟时间(通过向上和向下键设置小时,然后按向右键设置小时并设置它 。)现在可以毫无顾虑地完成您的日常工作!


以上就是本篇文章的全部内容。如果遇到问题,请随时在本帖下面进行回复。

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 705 | 回复: 1492



手机版|

GMT+8, 2024-11-24 11:06 , Processed in 0.063843 second(s), 8 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表