在这篇文章中,我们将使用RTC或实时时钟模块来构建一个数字时钟。我们将了解什么是“RTC”模块,如何与Arduino接口和它做什么。
由:
RTC模块是一种精确跟踪电流时间的电路。它有两个功能,它与微控制器和微处理器通信,给出电流时间,并作为备用电路,在停电时维持时间,因为它有内置的电池备份系统。
我们可以在任何电子设备中找到RTC,在这些设备中,时间是一个重要的功能。
例如,我们的电脑或笔记本电脑即使在切断电源或拔掉电池后也能保持工作时间。在任何计算机的主板上,我们都能找到CMOS电池,它为RTC电路供电。
类似的电路我们将在这个项目中使用。
RTC模块是一个便宜的设备,可以在任何电子商务网站和你当地的电子项目商店找到。
典型的RTC模块DS1307示例:
在购买时,大多数RTC模块都配有电池(CR2032)。有不同的尺寸和型号,上面的插图可能不一样。但是要确定型号是DS1307。本文中编写的代码只与DS1307兼容。
现在你对rtc有了一些了解。现在让我们来看看数字时钟的设计。在继续这个项目之前,你需要从以下链接下载库,并安装在你的IDE上:
•DS1307RTC.h
链接:github.com/PaulStoffregen/DS1307RTC
•TimeLib.h
链接:github.com/PaulStoffregen/Time
如果您使用的是最新版本,那么其他两个库应该已经预装在Arduino IDE上。
•LiquidCrystal.h
•Wire.h
电路:
arduino与LCD显示之间的电路连接是标准的,我们可以在其他基于LCD的项目中找到类似的连接。唯一的附加组件是RTC。
为了减少原型过程中的线路拥塞,可以将RTC直接插入arduino的模拟引脚。将SCl、SDA、Vcc和GND与公头引脚焊接,并将其插入A2到A5引脚,如图所示。
作者的原型:
如何在Arduino上正确插入RTC:
如果你的RTC有不同的引脚位置,不能复制如上所示,你总是可以使用电线连接。现在您的硬件设置已经完成,让我们进入项目的软件部分。
如何设置时间:
一旦RTC模块被编程,它保持时间,即使它从arduino。电池至少可以使用几年。
没有调整时间的按钮;下面的程序将在RTC中设置时间。在编译代码时,时间会自动与你的电脑时间同步,所以在上传程序之前,请确保你的电脑设置为正确的时间。
上传“SetTime”代码来设置RTC插入时的时间:
# include < Wire.h ># include < TimeLib.h ># include < DS1307RTC.h >intP = A3;/ /分配权力针为清债信托公司intN = A2;常量字符* monthName [12]={“1月”,“2月”,“3”,“4月”,“可能”,“君”,“7”,“8月”,“9”,“10月”,“11月”,“12月”};tmElements_ttm;无效设置(){pinMode (P输出);pinMode (N、输出);digitalWrite (P、高);digitalWrite (N,低);保龄球解析= false;保龄球配置= false;//得到的日期和时间的编译器是运行如果(获取当前日期(__DATE__)& &取得时间(__TIME__)){解析=真正的;//和配置的清债信托公司与这信息如果(RTC.write (tm)){配置=真正的;}}Serial.begin (9600);而(!系列);//等待为Arduino串行监控延迟(200);如果(解析& &配置){系列。打印(“DS1307配置时间= ");系列。打印(__TIME__);系列。打印(”,日期= ");以__DATE__);}其他的如果(解析){以"DS1307通信错误:-{");以“请检查电路”);}其他的{系列。打印("无法从编译器解析信息,时间= ");系列。打印(__TIME__);系列。打印(“\”,日期= \”“);系列。打印(__DATE__);以“\”“);}}无效循环(){}保龄球取得时间(const字符*str){int小时,分钟,证券交易委员会;如果(sscanf (str,“% d: % d: % d”,小时,分钟,证券交易委员会)! =3.)返回虚假的;tm。Hour=小时;tm。最小值ute=最小值;tm。年代econd=证券交易委员会;返回真正的;}保龄球获取当前日期(const字符*str){字符月(12];int一天,一年;uint8_tmonthIndex;如果(sscanf (str,“% s % d % d”,月,后,年)! =3.)返回虚假的;为(monthIndex=0;monthIndex<12;monthIndex + +){如果(比较字符串(月、monthName [monthIndex])==0)打破;}如果(monthIndex>=12)返回虚假的;tm。一天=一天;tm。米onth=monthIndex+1;tm。一年=CalendarYrToTm(年);返回真正的;}
这段代码上传后,打开串行监视器,应该会弹出一条成功消息,说明时间已经设置。
这表示RTC和arduino之间的连接是正确的,并且设置了时间。
现在,上传以下代码,在LCD上显示时间。
//------------ 程序发达通过R.Girish——/ /# include < Wire.h ># include < TimeLib.h ># include < DS1307RTC.h ># include < LiquidCrystal.h >LiquidCrystal液晶显示器(12,11,5,4,3.,2);intP = A3;intN = A2;无效设置(){lcd.begin (16,2);pinMode (P输出);pinMode (N、输出);digitalWrite (P、高);digitalWrite (N,低);}无效循环(){tmElements_ttm;lcd.clear ();如果(RTC.read (tm)){如果(tm。小时>=12){lcd.setCursor (14,0);液晶显示器。打印(“点”);}如果(tm。小时<12){lcd.setCursor (14,0);液晶显示器。打印(“我”);}lcd.setCursor (0,0);液晶显示器。打印(“:”);如果(tm。小时>12)//24小时来12小时/ /转换{如果(tm。小时==13)液晶显示器。打印(“01”);如果(tm。小时==14)液晶显示器。打印(“2”);如果(tm。小时==15)液晶显示器。打印(“03”);如果(tm。小时==16)液晶显示器。打印(“04”);如果(tm。小时==17)液晶显示器。打印(“05”);如果(tm。小时==18)液晶显示器。打印(“06”);如果(tm。小时==19)液晶显示器。打印(“7”);如果(tm。小时==20.)液晶显示器。打印(“08”);如果(tm。小时==21)液晶显示器。打印(“09”);如果(tm。小时==22)液晶显示器。打印(“10”);如果(tm。小时==23)液晶显示器。打印(“十一”);}其他的{液晶显示器。打印(tm.Hour);}液晶显示器。打印(":");液晶显示器。打印(tm.Minute);液晶显示器。打印(":");液晶显示器。打印(tm.Second);lcd.setCursor (0,1);液晶显示器。打印("日期:");液晶显示器。打印(tm.Day);液晶显示器。打印(“/”);液晶显示器。打印(tm.Month);液晶显示器。打印(“/”);液晶显示器。打印(tmYearToCalendar (tm.Year));}其他的{如果(RTC.chipPresent ()){lcd.setCursor (0,0);液晶显示器。打印(“RTC停了! !”);lcd.setCursor (0,1);液晶显示器。打印(“运行设置系统时间代码”);}其他的{lcd.clear ();lcd.setCursor (0,0);液晶显示器。打印(“读取错误!”);lcd.setCursor (0,1);液晶显示器。打印(“检查电路!”);}延迟(500);}延迟(500);}//------------ 程序发达通过R.Girish——/ /
一旦完成,您应该看到时间和日期显示在LCD上并运行。
注意:“SetTime”代码是由DS1307RTC的样例代码修改而来,优化RTC模块的接线,上传原始代码不会设置时间。
Arduino数字闹钟
在上面我们学习了如何使用RTC模块构建基本的Arduino时钟,在下一节中我们研究如何使用Arduino将其升级为数字闹钟电路。
有些人不需要闹钟,他们自然醒来,有些人醒来后闹钟响了好几次,有些人按下小睡按钮很多次,然后用一些借口为他们的大学/工作到很晚。
这个有趣的小闹钟项目可能会在早上醒来时遇到懒惰的问题。大多数闹钟都有贪睡按钮,如果用户没有回复,还会预先设定截止时间。
我们设计的这个闹钟没有偷懒按钮(贪睡按钮),只有用户按下按钮,闹钟才会关闭。
该时钟可以显示12小时格式的时间和DD/MM/YYYY格式的日期。
时间和日期将显示在16 x 2液晶显示屏上。RTC或实时时钟时间模块将负责跟踪时间,即使在长时间断电后也能保持正确的时间。
这里提供了5个按钮,稍后将解释其功能。Arduino项目的大脑可以选择任何模型,我们推荐Arduino pro mini或Arduino nano,因为它体积小巧。
现在让我们深入研究原理图。

以上是Arduino显示连接的原理图,通过旋转10K电位器来调整显示对比度。
下面是电路的其余部分:
该电路可供电9V 500mA壁适配器。

5个按键功能:
S1 -这是用来停止警报(它也是复位按钮)。
S2 -告警设置。长按S2,进入报警设置菜单。
S3—用于增加小时数。
S4—用于增加分钟数。
S5 -切换告警状态。如果“*”存在,则告警状态为on,如果“*”不存在,则告警状态为OFF。
关于如何设置警报的更多细节将在文章的底部进行解释。
下载下列图书馆档案:
Link1: github.com/PaulStoffregen/DS1307RTC
Link2: github.com/PaulStoffregen/Time
现在,我们需要设置时间到RTC模块,时间会从你的PC同步到RTC模块。
上传以下代码设置时间并打开串口监视器:
//------------------------------------------------//# include < Wire.h ># include < TimeLib.h ># include < DS1307RTC.h >常量字符* monthName [12]={“1月”,“2月”,“3”,“4月”,“可能”,“君”,“7”,“8月”,“9”,“10月”,“11月”,“12月”};tmElements_ttm;无效设置(){保龄球解析= false;保龄球配置= false;//得到的日期和时间的编译器是运行如果(获取当前日期(__DATE__)& &取得时间(__TIME__)){解析=真正的;//和配置的清债信托公司与这信息如果(RTC.write (tm)){配置=真正的;}}Serial.begin (9600);而(串行);//等待为Arduino串行监控延迟(200);如果(解析& &配置){系列。打印(“DS1307配置时间= ");系列。打印(__TIME__);系列。打印(”,日期= ");以__DATE__);}其他的如果(解析){以"DS1307通信错误:-{");以“请检查电路”);}其他的{系列。打印("无法从编译器解析信息,时间= ");系列。打印(__TIME__);系列。打印(“\”,日期= \”“);系列。打印(__DATE__);以“\”“);}}无效循环(){}保龄球取得时间(const字符* str){int小时,分钟,证券交易委员会;如果(sscanf (str,“% d: % d: % d”,小时,分钟,证券交易委员会)! =3.)返回虚假的;tm。Hour=小时;tm。最小值ute=最小值;tm。年代econd=证券交易委员会;返回真正的;}保龄球获取当前日期(const字符* str){字符月(12];int一天,一年;uint8_tmonthIndex;如果(sscanf (str,“% s % d % d”,月,后,年)! =3.)返回虚假的;为(monthIndex=0;monthIndex<12;monthIndex + +){如果(比较字符串(月、monthName [monthIndex])==0)打破;}如果(monthIndex>=12)返回虚假的;tm。一天=一天;tm。米onth=monthIndex+1;tm。一年=CalendarYrToTm(年);返回真正的;}//----------------------------------------//
现在,您已经成功地将时间设置为RTC
接下来,需要上传以下主要代码:
//------------ 程序发达通过R.Girish——/ /# include < LiquidCrystal.h ># include < DS1307RTC.h ># include < TimeLib.h ># include < Wire.h ># include < EEPROM.h >常量intrs=7;常量int在=6;常量intd4=5;常量intd5=4;常量intd6=3.;常量intd7=2;常量int蜂鸣器=8;布尔报警=虚假的;布尔outloop=真正的;常量intsetAlarm=A0;常量int小时=A1;常量int最小值=A2;常量int好吧=A3;常量intHrsADD=0;常量intMinADD=1;常量intALsave=2;intHrsVal=0;intMinVal=0;intH=0;int米=0;int年代=0;int我=0;intj=0;intk=0;LiquidCrystal液晶显示器(rs,恩,d4,d5,d6,d7);无效设置(){Serial.begin (9600);lcd.begin (16,2);pinMode(蜂鸣器,输出);pinMode (setAlarm输入);pinMode(小时、输入);pinMode(最小值,输入);pinMode(好吧,输入);digitalWrite (setAlarm高);digitalWrite(小时、高);digitalWrite(最小值,高);digitalWrite(好吧,高);}无效循环(){tmElements_ttm;lcd.clear ();如果(EEPROM.read (ALsave)==假){lcd.setCursor (15,1);液晶显示器。打印("");}如果(EEPROM.read (ALsave)==真正的){lcd.setCursor (15,1);液晶显示器。打印(F (“*”));}如果(RTC.read (tm)){如果(tm。小时>=12){lcd.setCursor (14,0);液晶显示器。打印(“点”);}如果(tm。小时<12){lcd.setCursor (14,0);液晶显示器。打印(“我”);}lcd.setCursor (0,0);液晶显示器。打印(“:”);H=tm.Hour;如果(tm。小时>12){如果(tm。小时==13){液晶显示器。打印(“01”);}如果(tm。小时==14){液晶显示器。打印(“2”);}如果(tm。小时==15){液晶显示器。打印(“03”);}如果(tm。小时==16){液晶显示器。打印(“04”);}如果(tm。小时==17){液晶显示器。打印(“05”);}如果(tm。小时==18){液晶显示器。打印(“06”);}如果(tm。小时==19){液晶显示器。打印(“7”);}如果(tm。小时==20.){液晶显示器。打印(“08”);}如果(tm。小时==21){液晶显示器。打印(“09”);}如果(tm。小时==22){液晶显示器。打印(“10”);}如果(tm。小时==23){液晶显示器。打印(“十一”);}}其他的{液晶显示器。打印(tm.Hour);}米=tm.Minute;年代=tm.Second;液晶显示器。打印(":");液晶显示器。打印(tm.Minute);液晶显示器。打印(":");液晶显示器。打印(tm.Second);lcd.setCursor (0,1);液晶显示器。打印("日期:");液晶显示器。打印(tm.Day);液晶显示器。打印(“/”);液晶显示器。打印(tm.Month);液晶显示器。打印(“/”);液晶显示器。打印(tmYearToCalendar (tm.Year));}其他的{如果(RTC.chipPresent ()){lcd.setCursor (0,0);液晶显示器。打印(“RTC停了! !”);lcd.setCursor (0,1);液晶显示器。打印(“运行设置系统时间代码”);}其他的{lcd.clear ();lcd.setCursor (0,0);液晶显示器。打印(“读取错误!”);lcd.setCursor (0,1);液晶显示器。打印(“检查电路!”);}}如果(digitalRead (setAlarm)==低){setALARM ();}如果(H==EEPROM.read (HrsADD)& &米==EEPROM.read (MinADD)& &年代==0){如果(EEPROM.read (ALsave)==真正的){声音();}}如果(digitalRead(好)==低){如果(EEPROM.read (ALsave)==真正的){EEPROM.write (ALsave0);报警=虚假的;延迟(1000);返回;}如果(EEPROM.read (ALsave)==假){EEPROM.write (ALsave1);报警=真正的;延迟(1000);返回;}}延迟(1000);}无效setALARM (){HrsVal=EEPROM.read (HrsADD);MinVal=EEPROM.read (MinADD);lcd.clear ();lcd.setCursor (0,0);液晶显示器。打印(F (”> > > >设置报警< < <”));lcd.setCursor (0,1);液晶显示器。打印(F (小时:“));液晶显示器。打印(EEPROM.read (HrsADD));液晶显示器。打印(F (”敏:“));液晶显示器。打印(EEPROM.read (MinADD));延迟(600);而(outloop){如果(HrsVal>23){HrsVal=0;lcd.clear ();lcd.setCursor (0,0);液晶显示器。打印(F (”> > > >设置报警< < <”));lcd.setCursor (0,1);液晶显示器。打印(F (小时:“));液晶显示器。打印(HrsVal);液晶显示器。打印(F (”敏:“));液晶显示器。打印(MinVal);}如果(MinVal>59){MinVal=0;lcd.clear ();lcd.setCursor (0,0);液晶显示器。打印(F (”> > > >设置报警< < <”));lcd.setCursor (0,1);液晶显示器。打印(F (小时:“));液晶显示器。打印(HrsVal);液晶显示器。打印(F (”敏:“));液晶显示器。打印(MinVal);}如果(digitalRead(小时)==低){HrsVal=HrsVal+1;lcd.clear ();lcd.setCursor (0,0);液晶显示器。打印(F (”> > > >设置报警< < <”));lcd.setCursor (0,1);液晶显示器。打印(F (小时:“));液晶显示器。打印(HrsVal);液晶显示器。打印(F (”敏:“));液晶显示器。打印(MinVal);延迟(250);}如果(digitalRead(分钟)==低){MinVal=MinVal+1;lcd.clear ();lcd.setCursor (0,0);液晶显示器。打印(F (”> > > >设置报警< < <”));lcd.setCursor (0,1);液晶显示器。打印(F (小时:“));液晶显示器。打印(HrsVal);液晶显示器。打印(F (”敏:“));液晶显示器。打印(MinVal);延迟(250);}如果(digitalRead (setAlarm)==低){EEPROM.write (HrsADDHrsVal);EEPROM.write (MinADDMinVal);lcd.clear ();lcd.setCursor (0,0);液晶显示器。打印(F (“闹钟设置为”));lcd.setCursor (0,1);液晶显示器。打印(EEPROM.read (HrsADD));液晶显示器。打印(F (":"));液晶显示器。打印(EEPROM.read (MinADD));液晶显示器。打印(F (“小时”));延迟(1000);outloop=虚假的;}}outloop=真正的;}无效声音(){lcd.clear ();lcd.setCursor (0,0);液晶显示器。打印(“醒来吧醒来吧! !”);lcd.setCursor (0,1);液晶显示器。打印(“它现在……”);为(j=0;j<10;j + +){为(我=0;我<2;我+ +){digitalWrite(蜂鸣器,高);延迟(150);digitalWrite(蜂鸣器,低);延迟(150);}延迟(400);}为(k=0;k<10;k + +){为(我=0;我<4;我+ +){digitalWrite(蜂鸣器,高);延迟(150);digitalWrite(蜂鸣器,低);延迟(150);}延迟(250);}而(真正的){digitalWrite(蜂鸣器,高);延迟(150);digitalWrite(蜂鸣器,低);延迟(150);}}//------------ 程序发达通过R.Girish——/ /
上传上述代码后,您必须看到正确的时间和日期运行在显示器上。
现在让我们看看如何设置闹钟:
•长按S2,直到看到报警菜单。
•按S3、S4调节小时、分钟。
•设置好所需时间后,再次按S2键。它会说“The alarm is set for xx:xx hours”。
•当报警状态为“ON”时,显示屏上显示“*”符号,当报警状态为“OFF”时,则没有“*”符号。
•按S5半秒即可打开/关闭闹钟。不要长按,直到“*”消失(它又回来了),只要按半秒钟,以切换警报状态。
重要提示:
在设置闹钟时,最常见的错误是无意切换AM / PM,这会导致闹钟在我们想要的时间响不起来。
为了解决这个问题,本文提出的闹钟设置采用24小时的时钟格式。
LCD上显示的时间将是12小时的AM / PM格式,但是,当您设置这个项目的闹钟时,您必须设置从0到23小时的24小时格式。
例如:如果你想把闹钟设置在晚上9点,你必须设置21小时零分钟。早上5点:5小时0分钟,以此类推。
作者的原型:

你喜欢这个项目吗?有任何关于这个项目的问题,请随意在评论中表达,您可能会收到快速的回复。
视频: