Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 2eb1581

Browse files
authored
arduino alarm clock added
1 parent d9c82e9 commit 2eb1581

File tree

12 files changed

+826
-0
lines changed

12 files changed

+826
-0
lines changed

‎alarm-clock/AlarmTone.cpp‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#include <Arduino.h>
2+
#include "AlarmTone.h"
3+
4+
#define TONE_TIME 500 /* ms */
5+
#define TONE_SPACING 100 /* ms */
6+
7+
static const uint16_t TONES[] = {
8+
500,
9+
800,
10+
};
11+
const uint16_t NUM_TONES = sizeof(TONES) / sizeof(TONES[0]);
12+
13+
AlarmTone::AlarmTone()
14+
: _playing(false)
15+
, _tone_index(0)
16+
, _last_tone_time(0) {
17+
}
18+
19+
void AlarmTone::begin(uint8_t pin) {
20+
_pin = pin;
21+
pinMode(_pin, OUTPUT);
22+
}
23+
24+
void AlarmTone::play() {
25+
if (!_playing || _last_tone_time + TONE_TIME + TONE_SPACING < millis()) {
26+
tone(_pin, TONES[_tone_index], TONE_TIME);
27+
_tone_index = (_tone_index + 1) % NUM_TONES;
28+
_last_tone_time = millis();
29+
}
30+
_playing = true;
31+
}
32+
33+
void AlarmTone::stop() {
34+
noTone(_pin);
35+
_tone_index = 0;
36+
_playing = false;
37+
}

‎alarm-clock/AlarmTone.h‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#ifndef __ALARM_TONE_H__
2+
#define __ALARM_TONE_H__
3+
4+
class AlarmTone {
5+
public:
6+
AlarmTone();
7+
void begin(uint8_t pin);
8+
void play();
9+
void stop();
10+
11+
private:
12+
uint8_t _pin;
13+
bool _playing;
14+
uint8_t _tone_index;
15+
unsigned long _last_tone_time;
16+
};
17+
18+
#endif /* __ALARM_TONE_H */

‎alarm-clock/Button.cpp‎

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/*
2+
Button - a small library for Arduino to handle button debouncing
3+
4+
MIT licensed.
5+
*/
6+
7+
#include "Button.h"
8+
#include <Arduino.h>
9+
10+
Button::Button(uint8_t pin, uint16_t debounce_ms)
11+
: _pin(pin)
12+
, _delay(debounce_ms)
13+
, _state(HIGH)
14+
, _ignore_until(0)
15+
, _has_changed(false)
16+
, _reported_repeats(0)
17+
, _repeat_delay_ms(-1)
18+
, _repeat_ms(-1)
19+
{
20+
}
21+
22+
void Button::begin()
23+
{
24+
pinMode(_pin, INPUT_PULLUP);
25+
}
26+
27+
//
28+
// public methods
29+
//
30+
31+
bool Button::read()
32+
{
33+
// ignore pin changes until after this delay time
34+
if (_ignore_until > millis())
35+
{
36+
// ignore any changes during this period
37+
}
38+
39+
// pin has changed
40+
else if (digitalRead(_pin) != _state)
41+
{
42+
_state = !_state;
43+
44+
if (_state == RELEASED)
45+
{
46+
_reported_repeats = repeats_since_press();
47+
}
48+
49+
else
50+
{
51+
_reported_repeats = 0;
52+
}
53+
54+
_ignore_until = millis() + _delay;
55+
_has_changed = true;
56+
}
57+
58+
return _state;
59+
}
60+
61+
// has the button been toggled from on -> off, or vice versa
62+
bool Button::toggled()
63+
{
64+
read();
65+
return has_changed();
66+
}
67+
68+
// mostly internal, tells you if a button has changed after calling the read() function
69+
bool Button::has_changed()
70+
{
71+
if (_has_changed)
72+
{
73+
_has_changed = false;
74+
return true;
75+
}
76+
return false;
77+
}
78+
79+
// how many repeated press events occured since the button was pressed
80+
uint16_t Button::repeat_count()
81+
{
82+
return _state == PRESSED ? repeats_since_press() : _reported_repeats;
83+
}
84+
85+
// has the button gone from off -> on or pressed repeatedly
86+
bool Button::pressed()
87+
{
88+
if (read() == PRESSED)
89+
{
90+
uint16_t old_repeats = _reported_repeats;
91+
_reported_repeats = repeats_since_press();
92+
return (has_changed() || old_repeats != _reported_repeats);
93+
}
94+
else
95+
{
96+
return false;
97+
}
98+
}
99+
100+
// has the button gone from on -> off
101+
bool Button::released()
102+
{
103+
return (read() == RELEASED && has_changed());
104+
}
105+
106+
void Button::set_repeat(int16_t delay_ms, int16_t repeat_ms)
107+
{
108+
_repeat_delay_ms = delay_ms > _delay ? delay_ms - _delay : 0;
109+
_repeat_ms = repeat_ms;
110+
}
111+
112+
uint16_t Button::repeats_since_press()
113+
{
114+
if (_repeat_delay_ms == -1 || millis() < _ignore_until + _repeat_delay_ms)
115+
{
116+
return 0;
117+
}
118+
119+
if (_repeat_ms <= 0)
120+
{
121+
return 1;
122+
}
123+
124+
uint32_t press_time = millis() - _ignore_until;
125+
return 1 + (press_time - _repeat_delay_ms) / _repeat_ms;
126+
}

‎alarm-clock/Button.h‎

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
Button - a small library for Arduino to handle button debouncing
3+
4+
MIT licensed.
5+
*/
6+
7+
#ifndef Button_h
8+
#define Button_h
9+
#include "Arduino.h"
10+
11+
class Button
12+
{
13+
public:
14+
Button(uint8_t pin, uint16_t debounce_ms = 100);
15+
void begin();
16+
bool read();
17+
bool toggled();
18+
bool pressed();
19+
bool released();
20+
bool has_changed();
21+
uint16_t repeat_count();
22+
void set_repeat(int16_t delay_ms, int16_t repeat_ms);
23+
24+
const static bool PRESSED = LOW;
25+
const static bool RELEASED = HIGH;
26+
27+
private:
28+
uint16_t repeats_since_press();
29+
30+
uint8_t _pin;
31+
uint16_t _delay;
32+
bool _state;
33+
uint32_t _ignore_until;
34+
bool _has_changed;
35+
uint16_t _reported_repeats;
36+
int16_t _repeat_delay_ms;
37+
int16_t _repeat_ms;
38+
};
39+
40+
#endif

‎alarm-clock/Clock.cpp‎

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
#include <Arduino.h>
2+
#include "Clock.h"
3+
4+
#define MINUTE 60 * 1000L /* ms */
5+
#define TIMESPAN_DAY TimeSpan(1, 0, 0, 0)
6+
7+
#define NVRAM_ADDR_ALARM_ENABLED 0
8+
#define NVRAM_ADDR_ALARM_HOUR 1
9+
#define NVRAM_ADDR_ALARM_MINUTE 2
10+
11+
12+
Clock::Clock()
13+
: _alarm_state(ALARM_OFF)
14+
, _alarm_snooze_time(0)
15+
, _alarm_hour(DEFAULT_ALARM_HOUR)
16+
, _alarm_minute(0) {
17+
}
18+
19+
void Clock::begin() {
20+
# if USE_RTC
21+
if (!_rtc.begin()) {
22+
Serial.println("Couldn't find RTC");
23+
abort();
24+
}
25+
_alarm_state = _rtc.readnvram(NVRAM_ADDR_ALARM_ENABLED) ? ALARM_OFF : ALARM_DISABLED;
26+
_alarm_hour = _rtc.readnvram(NVRAM_ADDR_ALARM_HOUR) % 24;
27+
_alarm_minute = _rtc.readnvram(NVRAM_ADDR_ALARM_MINUTE) % 60;
28+
# else /* USE_RTC */
29+
DateTime zeroTime;
30+
_rtc.begin(zeroTime);
31+
# endif
32+
}
33+
34+
/***** Clock management *****/
35+
36+
DateTime Clock::now() {
37+
return _rtc.now();
38+
}
39+
40+
void Clock::incrementMinute() {
41+
DateTime now = _rtc.now();
42+
DateTime newTime = DateTime(now.year(), now.month(), now.day(), now.hour(),
43+
(now.minute() + 1) % 60);
44+
_rtc.adjust(newTime);
45+
}
46+
47+
void Clock::incrementHour() {
48+
DateTime now = _rtc.now();
49+
DateTime newTime = DateTime(now.year(), now.month(), now.day(),
50+
(now.hour() + 1) % 24, now.minute());
51+
_rtc.adjust(newTime);
52+
}
53+
54+
/***** Alarm management *****/
55+
bool Clock::_isAlarmDueTime() {
56+
auto currentTime = now();
57+
auto alarm = alarmTime();
58+
return ((currentTime.hour() == alarm.hour())
59+
&& (currentTime.minute() == alarm.minute()));
60+
}
61+
62+
bool Clock::alarmEnabled() {
63+
return _alarm_state != ALARM_DISABLED;
64+
}
65+
66+
bool Clock::alarmActive() {
67+
switch (_alarm_state) {
68+
case ALARM_DISABLED:
69+
return false;
70+
71+
case ALARM_OFF:
72+
if (_isAlarmDueTime()) {
73+
_alarm_state = ALARM_ACTIVE;
74+
return true;
75+
}
76+
return false;
77+
78+
case ALARM_ACTIVE:
79+
return true;
80+
81+
case ALARM_SNOOZED:
82+
if (millis() >= _alarm_snooze_time) {
83+
_alarm_state = ALARM_ACTIVE;
84+
return true;
85+
}
86+
return false;
87+
88+
case ALARM_STOPPED:
89+
if (!_isAlarmDueTime()) {
90+
_alarm_state = ALARM_OFF;
91+
}
92+
return false;
93+
94+
default:
95+
return false;
96+
}
97+
}
98+
99+
100+
void Clock::toggleAlarm() {
101+
bool enabled = !alarmEnabled();
102+
_alarm_state = enabled ? ALARM_OFF : ALARM_DISABLED;
103+
_rtc.writenvram(NVRAM_ADDR_ALARM_ENABLED, enabled);
104+
}
105+
106+
DateTime Clock::alarmTime() {
107+
DateTime now = _rtc.now();
108+
DateTime alarm = DateTime(now.year(), now.month(), now.day(), _alarm_hour, _alarm_minute);
109+
return alarm >= now ? alarm : alarm + TIMESPAN_DAY;
110+
}
111+
112+
void Clock::snooze() {
113+
_alarm_state = ALARM_SNOOZED;
114+
_alarm_snooze_time = millis() + SNOOZE_TIME * MINUTE;
115+
}
116+
117+
void Clock::stopAlarm() {
118+
_alarm_state = ALARM_STOPPED;
119+
}
120+
121+
void Clock::incrementAlarmHour() {
122+
_alarm_hour = (_alarm_hour + 1) % 24;
123+
_alarm_state = ALARM_OFF;
124+
_rtc.writenvram(NVRAM_ADDR_ALARM_HOUR, _alarm_hour);
125+
}
126+
127+
void Clock::incrementAlarmMinute() {
128+
_alarm_minute = (_alarm_minute + 1) % 60;
129+
_alarm_state = ALARM_OFF;
130+
_rtc.writenvram(NVRAM_ADDR_ALARM_MINUTE, _alarm_minute);
131+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /