X-Git-Url: https://code.citadel.org/?p=the_perfect_clock.git;a=blobdiff_plain;f=the_perfect_clock.ino;h=48050670dffc522ee099456ce8bb1f0316e419be;hp=f120ad15fe7b3944adec79193e4cb246882ce93d;hb=HEAD;hpb=12e279aa4623865444f03d5d4626767ce8989648 diff --git a/the_perfect_clock.ino b/the_perfect_clock.ino index f120ad1..2529492 100644 --- a/the_perfect_clock.ino +++ b/the_perfect_clock.ino @@ -1,6 +1,6 @@ // "The Perfect Clock" -// Copyright (C) 2019-2022 by Art Cancro +// Copyright (C) 2019-2023 by Art Cancro // 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 @@ -19,11 +19,12 @@ // 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) @@ -54,10 +55,9 @@ int time_is_set = 0; // nonzero when time has been set at least once 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 @@ -87,8 +87,12 @@ void setup() { // 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) { @@ -102,12 +106,17 @@ void loop() { } } } - } + } 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(); @@ -115,13 +124,13 @@ void loop() { 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 { @@ -146,10 +155,10 @@ void loop() { } 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)) { @@ -179,10 +188,10 @@ void loop() { } 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); } }