arduino教程 您所在的位置:网站首页 arduino简易时钟 arduino教程

arduino教程

2024-05-26 12:10| 来源: 网络整理| 查看: 265

5.UNO闹钟

点击此处alarm-clock.ino - Wokwi Arduino and ESP32 Simulator开始在线仿真 在这里插入图片描述

该数字闹钟在4位7段显示屏上显示时间。它具有以下特点:

两个按钮用于设置当前时间(小时/分钟)具有贪睡功能的可编程警报报警声音可以在代码中轻松自定义,甚至可以播放旋律冒号闪烁以指示秒数可选RTC,使时钟更精确断电恢复:当前时间和报警设置存储在RTC中 如何使用时钟

要设置时间,请按分钟/小时按钮。

按下警报按钮可启用/禁用警报。屏幕将通过显示单词"打开"或"关闭"来显示警报状态。

启用报警后,当前报警时间将显示几秒钟。您可以使用分钟/小时按钮来调整闹钟时间。要完成操作,请再次按"闹钟"按钮,或等待几秒钟。

当闹钟响起时,短按闹钟按钮可将其暂停 9 分钟。屏幕将显示四个圆圈,让您知道闹钟已打盹。

要停止闹钟,请按住闹钟按钮一秒钟或更长时间。

项目结构

该代码分为几个模块:

config.h - 时钟的配置选项:是否使用RTC芯片,贪睡时间等。当程序中有多个模块时,使用配置文件是一种常见的做法。alarm-clock.ino - 主程序代码。它管理用户界面:7段显示器和按钮。时钟 - 类管理当前时间和警报状态机。它使用RTClib库与RTC芯片通信并跟踪时间。Clock闹钟铃声 - 班级播放闹钟声音。您可以更改数组的值,并自定义闹钟并播放不同的音调和旋律。AlarmTone``TONES``TONE_TIME``TONE_SPACING 硬件 项目数量笔记Arduino Uno R314 位 7 段4通用阳极,14 引脚220Ω 电阻器8连接到 7 段段引脚PNP 晶体管4可选,推荐4.7kΩ 电阻器4如果您使用PNP晶体管12 毫米按钮3压电蜂鸣器1用于报警DS1307 RTC1自选 您还可以使用共阴极7段显示器,只需在config.h中调整常数,然后切换到NPN晶体管。DISPLAY_TYPE

为了将时钟硬件保持在最低限度,Arduino使用SevSeg库直接控制7段显示。但是,这种方法有一个缺点:它使用12个GPIO引脚!

如果要节省Arduino引脚,可以使用74HC595移位寄存器将引脚使用量减少到6个,甚至可以使用带有集成控制器芯片的7段显示器,例如TM1637,HT16K33或MAX7219。在这种情况下,您需要更改代码以使用不同的显示库(SevSeg 不支持这种情况),但这超出了本项目的范围。

引脚连接 Arduino Uno PinDeviceDevice Pin27-Segment14 (Dig 1)37-Segment11 (Dig 2)47-Segment10 (Dig 3)57-Segment6 (Dig 4)67-Segment13 (A)77-Segment9 (B)87-Segment4 ©97-Segment2 (D)107-Segment1 (E)117-Segment12 (F)127-Segment5 (G)137-Segment8 (Colon)A0Hour Button-A1Minute Button-A2Alarm Button-A3Buzzer / Speaker-A4DS1307 RTCSDAA5DS1307 RTCSCL The pin numbers for your 7-segment display may differ. Please consult the datasheet relevant to your device to find out the relevant pin numbers. 代码 /** Arduino Digital Alarm Clock Copyright (C) 2020, Uri Shaked. Released under the MIT License. */ #include //数码管函数库 #include "Button.h" #include "AlarmTone.h" #include "Clock.h" #include "config.h" const int COLON_PIN = 13; const int SPEAKER_PIN = A3; Button hourButton(A0); Button minuteButton(A1); Button alarmButton(A2); AlarmTone alarmTone;//闹钟音 Clock clock;// SevSeg sevseg;// enum DisplayState {//枚举显示时钟,时间等参数 DisplayClock, DisplayAlarmStatus, DisplayAlarmTime, DisplayAlarmActive, DisplaySnooze, }; DisplayState displayState = DisplayClock; long lastStateChange = 0; void changeDisplayState(DisplayState newValue) { displayState = newValue; lastStateChange = millis(); }//改变显示时间 long millisSinceStateChange() { return millis() - lastStateChange; } void setColon(bool value) { digitalWrite(COLON_PIN, value ? LOW : HIGH); }//设置冒号 void displayTime() { DateTime now = clock.now(); bool blinkState = now.second() % 2 == 0; sevseg.setNumber(now.hour() * 100 + now.minute()); setColon(blinkState); } void clockState() { displayTime(); if (alarmButton.read() == Button::RELEASED && clock.alarmActive()) { //读取alarmButton has_changed()以清除其状态 alarmButton.has_changed(); changeDisplayState(DisplayAlarmActive); return; } if (hourButton.pressed()) { clock.incrementHour(); }//按键按下增加小时 if (minuteButton.pressed()) { clock.incrementMinute(); } if (alarmButton.pressed()) { clock.toggleAlarm(); changeDisplayState(DisplayAlarmStatus); } } void alarmStatusState() { setColon(false); sevseg.setChars(clock.alarmEnabled() ? " on" : " off"); if (millisSinceStateChange() > ALARM_STATUS_DISPLAY_TIME) { changeDisplayState(clock.alarmEnabled() ? DisplayAlarmTime : DisplayClock); return; } }//闹钟开关 void alarmTimeState() { DateTime alarm = clock.alarmTime(); sevseg.setNumber(alarm.hour() * 100 + alarm.minute(), -1); if (millisSinceStateChange() > ALARM_HOUR_DISPLAY_TIME || alarmButton.pressed()) { changeDisplayState(DisplayClock); return; } if (hourButton.pressed()) { clock.incrementAlarmHour(); lastStateChange = millis(); } if (minuteButton.pressed()) { clock.incrementAlarmMinute(); lastStateChange = millis(); } if (alarmButton.pressed()) { changeDisplayState(DisplayClock); } } void alarmState() { displayTime();//显示时间 if (alarmButton.read() == Button::RELEASED) { alarmTone.play();//启动报警 } if (alarmButton.pressed()) { alarmTone.stop();//按键按下报警结束 } if (alarmButton.released()) { alarmTone.stop();//按键释放报警结束 bool longPress = alarmButton.repeat_count() > 0; if (longPress) {//长按 clock.stopAlarm(); changeDisplayState(DisplayClock); } else { clock.snooze();//小盹模式 changeDisplayState(DisplaySnooze); } } } void snoozeState() {//小盹模式 sevseg.setChars("****"); if (millisSinceStateChange() > SNOOZE_DISPLAY_TIME) { changeDisplayState(DisplayClock); return; } } void setup() { Serial.begin(115200); clock.begin(); hourButton.begin(); hourButton.set_repeat(500, 200); minuteButton.begin(); minuteButton.set_repeat(500, 200); alarmButton.begin(); alarmButton.set_repeat(1000, -1); alarmTone.begin(SPEAKER_PIN); pinMode(COLON_PIN, OUTPUT); byte digits = 4; byte digitPins[] = {2, 3, 4, 5}; byte segmentPins[] = {6, 7, 8, 9, 10, 11, 12}; bool resistorsOnSegments = false; bool updateWithDelays = false; bool leadingZeros = true; bool disableDecPoint = true; sevseg.begin(DISPLAY_TYPE, digits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros, disableDecPoint); sevseg.setBrightness(90); } void loop() { sevseg.refreshDisplay(); switch (displayState) { case DisplayClock: clockState(); break; case DisplayAlarmStatus: alarmStatusState(); break; case DisplayAlarmTime: alarmTimeState(); break; case DisplayAlarmActive: alarmState(); break; case DisplaySnooze: snoozeState(); break; } } 结束

知命者不怨天,知己者不怨人。 – 淮南子 《淮南子》 在这里插入图片描述



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有