-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
192 lines (165 loc) · 6.17 KB
/
main.cpp
File metadata and controls
192 lines (165 loc) · 6.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/**
* An Arduino Volt Meter Analog Clock based on a TinyRTC real time clock.
*
* For more info about this project, check out my blog for the full story
* images, and the endresult of the project:
* http://michaelteeuw.nl/post/174972004187/what-time-is-it-fathers-day
*
* LICENSE: Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"). For more info see LICENSE file.
*
* @category CategoryName
* @package PackageName
* @author Michael Teeuw
* @copyright 2018
* @license https://opensource.org/licenses/MIT
* @link http://michaelteeuw.nl
*/
#include <Arduino.h>
#include <Wire.h>
#include "RTClib.h" // https://github.com/adafruit/RTClib
// Define the Pins we are using.
#define PIN_BUTTON_HOUR 7
#define PIN_BUTTON_MIN 8
#define PIN_METER_HOUR 3
#define PIN_METER_MIN 5
#define PIN_METER_SEC 6
// Define the minimum and maximum PWM values for all the meters.
// These values can be used to calibrate the meters.
#define MINIMUM_PWM_VALUE_HOUR 5 //originally 15
#define MAXIMUM_PWM_VALUE_HOUR 235 //originally 240
#define MINIMUM_PWM_VALUE_MIN 5 //originally 15
#define MAXIMUM_PWM_VALUE_MIN 218 //originally 254
#define MINIMUM_PWM_VALUE_SEC 3 //originally 15
#define MAXIMUM_PWM_VALUE_SEC 235 //originally 240
// Create the real time clock instance.
RTC_DS1307 rtc;
/**
* Slowly animate one meter to the maximum value and back.
* This animation is used in the start sequence. Not only does it look
* cool. It's also a way to test the meters.
*
* @param uint8_t pin The pin of the meter.
* @param uint8_t min The meter's minimum PWM value.
* @param uint8_t max The meter's maximum PWM value.
*/
void animateMeter(uint8_t pin, uint8_t min, uint8_t max) {
uint8_t v;
for (v = min; v <= max; v++) {
analogWrite(pin, v);
delay(2);
}
delay(100);
for (v = max; v >= min; v--) {
analogWrite(pin, v);
delay(2);
}
delay(100);
}
void startMeter(uint8_t pin, uint8_t min, uint8_t max) {
uint8_t v;
for (v = min; v <= max; v++) {
analogWrite(pin, v);
delay(4);
}
delay(100);
}
/**
* Run the startup sequence by animating all three meters sequentially.
*/
void startSequence() {
animateMeter(PIN_METER_HOUR, MINIMUM_PWM_VALUE_HOUR, MAXIMUM_PWM_VALUE_HOUR);
animateMeter(PIN_METER_MIN, MINIMUM_PWM_VALUE_MIN, MAXIMUM_PWM_VALUE_MIN);
animateMeter(PIN_METER_SEC, MINIMUM_PWM_VALUE_SEC, MAXIMUM_PWM_VALUE_SEC);
startMeter(PIN_METER_HOUR, MINIMUM_PWM_VALUE_HOUR, MAXIMUM_PWM_VALUE_HOUR);
startMeter(PIN_METER_MIN, MINIMUM_PWM_VALUE_MIN, MAXIMUM_PWM_VALUE_MIN);
startMeter(PIN_METER_SEC, MINIMUM_PWM_VALUE_SEC, MAXIMUM_PWM_VALUE_SEC);
}
/**
* The method to update the time displayed on the the meter.
*/
void displayTime() {
// Retrieve the time from the real time clock.
DateTime now = rtc.now();
// Since the real time clock returns a 24 hour format,
// we need to convert the hour value to 12 hour format.
// For minutes and seconds we can just directly use the
// properties on the 'now' object. No need to store those
// in a temporary variable.
int8_t h = (now.hour() == 0 || now.hour() == 12) ? 12 : now.hour() % 12;
// Convert the time values to PWM values by using map ...
// and set that value as the PWM value using analogWrite.
analogWrite(PIN_METER_HOUR, map(h, 1, 12, MINIMUM_PWM_VALUE_HOUR, MAXIMUM_PWM_VALUE_HOUR));
analogWrite(PIN_METER_MIN, map(now.minute(), 0, 60, MINIMUM_PWM_VALUE_MIN, MAXIMUM_PWM_VALUE_MIN));
analogWrite(PIN_METER_SEC, map(now.second(), 0, 60, MINIMUM_PWM_VALUE_SEC, MAXIMUM_PWM_VALUE_SEC));
// For debuging purposes, write the time to the
// Serial port as well.
Serial.print(h);
Serial.print(":");
Serial.print(now.minute());
Serial.print(":");
Serial.println(now.second());
}
/**
* The setup method used by the Arduino.
*/
void setup () {
// Initiate the serial port for debugging purposes.
Serial.begin(9600);
// Configure all the pin modes for all connected pins.
pinMode(PIN_BUTTON_HOUR, INPUT_PULLUP);
pinMode(PIN_BUTTON_MIN, INPUT_PULLUP);
pinMode(PIN_METER_HOUR, OUTPUT);
pinMode(PIN_METER_MIN, OUTPUT);
pinMode(PIN_METER_SEC, OUTPUT);
// Start the real time clock.
rtc.begin();
// If the real time clock is not running,
// for example after the battery was replaced,
// start it by setting the time.
if (!rtc.isrunning()) {
rtc.adjust(DateTime(2018, 6, 17, 0, 0, 0));
}
// Initiate the power-on self test by running the start sequence.
startSequence();
}
/**
* The main runloop used by the Arduino.
*/
void loop () {
// Update the meters by calling the `displayTime()` method.
displayTime();
// Check if we pressed the button to adjust the hour ...
// Repeat the following loop for as long as we hold this button.
while (!digitalRead(PIN_BUTTON_HOUR)) {
// Grab the current time.
DateTime now = rtc.now();
// Set the RTC time by using the current time and increaing the hour by one.
// By using the % 24, it will automaticly overflow to 0 when it reaches 24.
// The seconds are simply reset.
rtc.adjust(DateTime(now.year(), now.month(), now.day(), (now.hour() + 1) % 24, now.minute(), 0));
// Update the display to reflect the changes.
displayTime();
// Wait half a second before we check again to see
// if the button is still pressed.
delay(500);
}
// Check if we pressed the button to adjust the minutes ...
// Repeat the following loop for as long as we hold this button.
while (!digitalRead(PIN_BUTTON_MIN)) {
// Grab the current time.
DateTime now = rtc.now();
// Set the RTC time by using the current time and increaing the minutes by one.
// By using the % 60, it will automaticly overflow to 0 when it reaches 60.
// The seconds are simply reset.
rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), (now.minute() + 1) % 60, 0));
// Update the display to reflect the changes.
displayTime();
// Wait a quarter of a second before we check again to see
// if the button is still pressed.
delay(250);
}
// Wait for 1 second before we start all over again.
delay(1000);
}