// "The Perfect Clock"
-// Copyright (C) 2019-2022 by Art Cancro <ajc@citadel.org>
+// Copyright (C) 2019-2023 by Art Cancro <ajc@citadel.org>
// My perfect clock has no buttons and cannot be set manually. This version uses a WWVB receiver module
// attached to pin D9 of the Arduino, and sets the clock any time it receives a complete frame. The clock
// 5. Under no circumstances may you use this program and also maintain a Facebook account.
// Aside from these conditions, the program is made available to you under the terms of the GNU General Public License.
+// On my clock, there is a green LED on 2, a yellow LED on 3, and a red LED on 4.
+
const uint8_t wwvb = 9; // pin on which WWVB signal will be received
-const uint8_t greenled = 2; // An LED attached to this pin will illuminate if the time has been set within the last 24 hours
-const uint8_t yellowled = 3; // An LED attached to this pin will illuminate if we are currently receiving a clean frame
-const uint8_t redled = 4; // An LED attached to this pin will pulse for 1 ms every second
-const uint8_t boardled = LED_BUILTIN;
+const uint8_t last24led = 2; // An LED attached to this pin will illuminate if the time has been set within the last 24 hours
+const uint8_t cleantimecodeled = LED_BUILTIN; // An LED attached to this pin will illuminate if we are currently receiving a clean frame
+const uint8_t timecodeled = 3;
const uint8_t photocell = A0; // Attach a photocell with a 10K voltage divider to this pin
const uint8_t addr = 0x70; // I2C address of HT16K33 (using Adafruit backpack with digits on 0,1,3,4; dots on 2)
void setup() {
int i;
- pinMode(boardled, OUTPUT); // The built-in LED will display the raw WWVB signal pulses
- pinMode(greenled, OUTPUT); // This LED will illuminate if the time has been set within the last 24 hours
- pinMode(yellowled, OUTPUT); // This LED will illuminate if we are currently receiving a clean frame
- pinMode(redled, OUTPUT); // This LED pulses for 1 ms every second
+ pinMode(timecodeled, OUTPUT); // The built-in LED will display the raw WWVB signal pulses
+ pinMode(last24led, OUTPUT); // This LED will illuminate if the time has been set within the last 24 hours
+ pinMode(cleantimecodeled, OUTPUT); // This LED will illuminate if we are currently receiving a clean frame
pinMode(wwvb, INPUT); // Input pin for WWVB receiver signal
pinMode(photocell, INPUT); // Input pin for photocell
// Note: only write to the display when the readout needs to be updated.
// Speaking I2C on every loop iteration jams the WWVB receiver.
void loop() {
+
+ // Reading it three times and taking the average gives us some hysteresis
+ int signal = (digitalRead(wwvb) + digitalRead(wwvb) + digitalRead(wwvb)) / 3;
+
+ // has the timer ticked?
unsigned long m = millis();
- digitalWrite(redled, (m % 1000) ? LOW : HIGH);
if (m != previous_millis) {
millisecond += (m - previous_millis);
if (millisecond >= millis_per_minute) {
}
}
}
- }
+ }
previous_millis = m;
int pulse_length;
- int signal = digitalRead(wwvb); // is the input high or low right now?
- digitalWrite(boardled, signal); // use the onboard LED to show the signal
+
+ if (signal) {
+ analogWrite(timecodeled, 5); // it's too bright on my board so we dim it; change to digitalWrite() if not needed
+ }
+ else {
+ digitalWrite(timecodeled, LOW);
+ }
if (signal && (!previous_signal)) { // leading edge of pulse detected
start_of_pulse = millis();
else if ((!signal) && (previous_signal)) { // trailing edge of pulse detected
pulse_length = millis() - start_of_pulse;
- if (pulse_length > 175 && pulse_length < 225) { // "0" bit ~= 200 ms (represented as "0")
+ if (pulse_length > 150 && pulse_length < 250) { // "0" bit ~= 200 ms (represented as "0")
this_pulse = 0;
}
- else if (pulse_length > 475 && pulse_length < 525) { // "1" bit ~= 500 ms (represented as "1")
+ else if (pulse_length > 450 && pulse_length < 550) { // "1" bit ~= 500 ms (represented as "1")
this_pulse = 1;
}
- else if (pulse_length > 775 && pulse_length < 825) { // marker bit ~= 800 ms (represented as "2")
+ else if (pulse_length > 750 && pulse_length < 850) { // marker bit ~= 800 ms (represented as "2")
this_pulse = 2;
}
else {
}
if (framesync) { // yellow LED = we currently have frame sync
- analogWrite(yellowled, 10); // (we run it at a low intensity)
+ digitalWrite(cleantimecodeled, HIGH); // (we run it at a low intensity)
}
else {
- digitalWrite(yellowled, LOW);
+ digitalWrite(cleantimecodeled, LOW);
}
if ((framesync) && (position_in_frame < 60)) {
}
if ((m - last_sync) < 86400000) { // green LED = got a good sync in the last 24 hours
- digitalWrite(greenled, HIGH);
+ digitalWrite(last24led, HIGH);
}
else {
- digitalWrite(greenled, LOW);
+ digitalWrite(last24led, LOW);
}
}