remove mcu code, move to new repo
This commit is contained in:
parent
ae9c16e405
commit
a13c18f93d
@ -1,131 +0,0 @@
|
|||||||
#define SSD1306_NO_SPLASH
|
|
||||||
|
|
||||||
// OLED display width and height, in pixels
|
|
||||||
#define SCREEN_WIDTH 128
|
|
||||||
#define SCREEN_HEIGHT 32
|
|
||||||
#define OLED_RESET -1
|
|
||||||
// i2c address for oled
|
|
||||||
///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
|
|
||||||
#define SCREEN_ADDRESS 0x3C
|
|
||||||
|
|
||||||
#include <Adafruit_SSD1306.h>
|
|
||||||
#include <splash.h>
|
|
||||||
#include <Adafruit_GrayOLED.h>
|
|
||||||
#include <gfxfont.h>
|
|
||||||
#include <Adafruit_GFX.h>
|
|
||||||
#include <Adafruit_SPITFT.h>
|
|
||||||
#include <Adafruit_SPITFT_Macros.h>
|
|
||||||
#include <LiquidCrystal_I2C.h>
|
|
||||||
|
|
||||||
// set the LCD address to 0x27 for a 16 chars and 2 line display
|
|
||||||
LiquidCrystal_I2C lcd(0x27, 16, 2);
|
|
||||||
|
|
||||||
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
lcd.init();
|
|
||||||
lcd.backlight();
|
|
||||||
lcd.setCursor(0, 0);
|
|
||||||
lcd.print("0x123456789abcde");
|
|
||||||
lcd.setCursor(0, 1);
|
|
||||||
lcd.print("fghijklmnopqrstu");
|
|
||||||
|
|
||||||
Serial.begin(115200);
|
|
||||||
|
|
||||||
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
|
|
||||||
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
|
|
||||||
Serial.println(F("SSD1306 allocation failed"));
|
|
||||||
for (;;); // Don't proceed, loop forever
|
|
||||||
}
|
|
||||||
|
|
||||||
display.display();
|
|
||||||
delay(50); // Pause for 2 seconds
|
|
||||||
|
|
||||||
// Clear the buffer
|
|
||||||
display.clearDisplay();
|
|
||||||
|
|
||||||
testdrawstyles(); // Draw 'stylized' characters
|
|
||||||
|
|
||||||
panic();
|
|
||||||
//
|
|
||||||
// // Invert and restore display, pausing in-between
|
|
||||||
// display.invertDisplay(true);
|
|
||||||
// delay(1000);
|
|
||||||
// display.invertDisplay(false);
|
|
||||||
// delay(1000);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void panic() {
|
|
||||||
for (;;) {
|
|
||||||
display.invertDisplay(true);
|
|
||||||
delay(1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void loop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#define LINE_HEIGHT_PX 9
|
|
||||||
|
|
||||||
void testdrawstyles(void) {
|
|
||||||
display.clearDisplay();
|
|
||||||
display.setTextSize(1); // Normal 1:1 pixel scale
|
|
||||||
display.setTextColor(SSD1306_WHITE); // Draw white text
|
|
||||||
display.setCursor(0, 0 * LINE_HEIGHT_PX);
|
|
||||||
display.println(F("123456789112345678921"));
|
|
||||||
display.setCursor(0, 1 * LINE_HEIGHT_PX);
|
|
||||||
display.println(F("234567893123456789412"));
|
|
||||||
display.setCursor(0, 2 * LINE_HEIGHT_PX);
|
|
||||||
display.println(F("345678951234567896123"));
|
|
||||||
display.display();
|
|
||||||
|
|
||||||
display.startscrollright(0x00, 0xFF);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Draw 'inverse' text
|
|
||||||
display.println(3.141592);
|
|
||||||
|
|
||||||
display.setTextSize(2); // Draw 2X-scale text
|
|
||||||
display.setTextColor(SSD1306_WHITE);
|
|
||||||
display.print(F("0x")); display.println(0xDEADBEEF, HEX);
|
|
||||||
|
|
||||||
display.display();
|
|
||||||
delay(2000);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
void testscrolltext(void) {
|
|
||||||
display.clearDisplay();
|
|
||||||
|
|
||||||
display.setTextSize(1.5); // Draw 2X-scale text
|
|
||||||
display.setTextColor(SSD1306_WHITE);
|
|
||||||
display.setCursor(10, 0);
|
|
||||||
display.println(F("1337CAFE"));
|
|
||||||
display.display(); // Show initial text
|
|
||||||
delay(70);
|
|
||||||
|
|
||||||
// Scroll in various directions, pausing in-between:
|
|
||||||
display.startscrollright(0x00, 0x0F);
|
|
||||||
delay(2000);
|
|
||||||
display.stopscroll();
|
|
||||||
delay(1000);
|
|
||||||
display.startscrollleft(0x00, 0x0F);
|
|
||||||
delay(2000);
|
|
||||||
display.stopscroll();
|
|
||||||
delay(1000);
|
|
||||||
display.startscrolldiagright(0x00, 0x07);
|
|
||||||
delay(2000);
|
|
||||||
display.startscrolldiagleft(0x00, 0x07);
|
|
||||||
delay(2000);
|
|
||||||
display.stopscroll();
|
|
||||||
delay(1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
ESP8266 BlinkWithoutDelay by Simon Peter
|
|
||||||
Blink the blue LED on the ESP-01 module
|
|
||||||
Based on the Arduino Blink without Delay example
|
|
||||||
This example code is in the public domain
|
|
||||||
|
|
||||||
The blue LED on the ESP-01 module is connected to GPIO1
|
|
||||||
(which is also the TXD pin; so we cannot use Serial.print() at the same time)
|
|
||||||
|
|
||||||
Note that this sketch uses LED_BUILTIN to find the pin with the internal LED
|
|
||||||
*/
|
|
||||||
#define IR_RX_PIN 14
|
|
||||||
#define IR_TX_PIN 12
|
|
||||||
#define SERIAL_BPS 115200
|
|
||||||
|
|
||||||
#define POWER_BUTTON 0xFFEA15
|
|
||||||
#define EDIT_BUTTON 0xFF7887
|
|
||||||
#define EXIT_BUTTON 0xFF38C7
|
|
||||||
#define ONE_BUTTON 0xFF08F7
|
|
||||||
#define TWO_BUTTON 0xFF8877
|
|
||||||
#define THREE_BUTTON 0xFF48B7
|
|
||||||
#define FOUR_BUTTON 0xFFC837
|
|
||||||
#define FIVE_BUTTON 0xFF28D7
|
|
||||||
#define SIX_BUTTON 0xFFA857
|
|
||||||
#define SEVEN_BUTTON 0xFFE817
|
|
||||||
#define EIGHT_BUTTON 0xFF18E7
|
|
||||||
#define NINE_BUTTON 0xFF9867
|
|
||||||
#define ZERO_BUTTON 0xFFB847
|
|
||||||
|
|
||||||
#include <IRremote.h>
|
|
||||||
|
|
||||||
IRrecv irrecv(IR_RX_PIN);
|
|
||||||
decode_results results;
|
|
||||||
|
|
||||||
int ledState = LOW;
|
|
||||||
volatile byte IRInputState;
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
IrReceiver.begin(IR_RX_PIN, ENABLE_LED_FEEDBACK); // Start the receiver
|
|
||||||
pinMode(LED_BUILTIN, OUTPUT);
|
|
||||||
Serial.begin(SERIAL_BPS);
|
|
||||||
Serial.print("herro booted\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
if (IrReceiver.decode()) {
|
|
||||||
Serial.println(IrReceiver.decodedIRData.decodedRawData, HEX);
|
|
||||||
IrReceiver.printIRResultShort(&Serial); // optional use new print version
|
|
||||||
IrReceiver.resume(); // Enable receiving of the next value
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,82 +0,0 @@
|
|||||||
// Demo the quad alphanumeric display LED backpack kit
|
|
||||||
// scrolls through every character, then scrolls Serial
|
|
||||||
// input onto the display
|
|
||||||
|
|
||||||
#include <Wire.h>
|
|
||||||
#include <Adafruit_GFX.h>
|
|
||||||
#include "Adafruit_LEDBackpack.h"
|
|
||||||
|
|
||||||
Adafruit_AlphaNum4 one = Adafruit_AlphaNum4();
|
|
||||||
Adafruit_AlphaNum4 two = Adafruit_AlphaNum4();
|
|
||||||
|
|
||||||
unsigned long ticks;
|
|
||||||
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
Serial.begin(9600);
|
|
||||||
|
|
||||||
one.begin(0x71); // pass in the address
|
|
||||||
two.begin(0x70);
|
|
||||||
|
|
||||||
one.writeDigitRaw(3, 0x0);
|
|
||||||
one.writeDigitRaw(0, 0xFFFF);
|
|
||||||
one.writeDisplay();
|
|
||||||
delay(200);
|
|
||||||
one.writeDigitRaw(0, 0x0);
|
|
||||||
one.writeDigitRaw(1, 0xFFFF);
|
|
||||||
one.writeDisplay();
|
|
||||||
delay(200);
|
|
||||||
one.writeDigitRaw(1, 0x0);
|
|
||||||
one.writeDigitRaw(2, 0xFFFF);
|
|
||||||
one.writeDisplay();
|
|
||||||
delay(200);
|
|
||||||
one.writeDigitRaw(2, 0x0);
|
|
||||||
one.writeDigitRaw(3, 0xFFFF);
|
|
||||||
one.writeDisplay();
|
|
||||||
delay(200);
|
|
||||||
|
|
||||||
one.clear();
|
|
||||||
one.writeDisplay();
|
|
||||||
|
|
||||||
two.clear();
|
|
||||||
two.writeDisplay();
|
|
||||||
|
|
||||||
one.writeDigitAscii(0, '1');
|
|
||||||
one.writeDigitAscii(1, '2');
|
|
||||||
one.writeDigitAscii(2, '0');
|
|
||||||
one.writeDigitAscii(3, '0');
|
|
||||||
two.writeDigitAscii(0, '0');
|
|
||||||
two.writeDigitAscii(1, '1');
|
|
||||||
two.writeDigitAscii(2, '2');
|
|
||||||
two.writeDigitAscii(3, '3');
|
|
||||||
one.writeDisplay();
|
|
||||||
two.writeDisplay();
|
|
||||||
|
|
||||||
delay(300);
|
|
||||||
|
|
||||||
Serial.println("Start typing to display!");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
char displaybuffer[4] = {' ', ' ', ' ', ' '};
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
|
|
||||||
ticks = millis();
|
|
||||||
|
|
||||||
|
|
||||||
sprintf(displaybuffer, "%02d", ticks/1000);
|
|
||||||
sprintf(displaybuffer+2, "%02d", ticks-(ticks/1000)*1000);
|
|
||||||
|
|
||||||
Serial.println(displaybuffer);
|
|
||||||
|
|
||||||
// set every digit to the buffer
|
|
||||||
two.writeDigitAscii(0, displaybuffer[0]);
|
|
||||||
two.writeDigitAscii(1, displaybuffer[1]);
|
|
||||||
two.writeDigitAscii(2, displaybuffer[2]);
|
|
||||||
two.writeDigitAscii(3, displaybuffer[3]);
|
|
||||||
|
|
||||||
// write it out!
|
|
||||||
two.writeDisplay();
|
|
||||||
delay(10);
|
|
||||||
}
|
|
@ -1,853 +0,0 @@
|
|||||||
/* WWVB Clock v 1.0
|
|
||||||
*
|
|
||||||
* A WWVB (NIST Time Code Broadcast) receiving clock powered by an
|
|
||||||
* Arduino (ATMega328), a DS1307 Real Time Clock, and a C-Max
|
|
||||||
* C-Max CMMR-6P-60 WWVB receiver module.
|
|
||||||
*
|
|
||||||
* This code builds on Capt.Tagon's code at duinolab.blogspot.com
|
|
||||||
* which was a great reference. Specifically, I used almost without change
|
|
||||||
* his struct / unsigned long long overlay for the received WWVB Buffer,
|
|
||||||
* which apparently in turn draws on DCF77 decoding code by Rudi Niemeijer,
|
|
||||||
* Mathias Dalheimer, and "Captain."
|
|
||||||
*
|
|
||||||
* The RTC (DS1307) interface code builds in part on code by
|
|
||||||
* Jon McPhalen (www.jonmcphalen.com)
|
|
||||||
*
|
|
||||||
* There you have it.
|
|
||||||
*
|
|
||||||
* This code supports the "Atomic Clock" article in the April 2010 issue
|
|
||||||
* of Popular Science. There is also a schematic for this project. There
|
|
||||||
* is also WWVB signal simulator code, to facilitate debugging and
|
|
||||||
* hacking on this project when the reception of the WWVB signal
|
|
||||||
* itself is less than stellar.
|
|
||||||
*
|
|
||||||
* The code for both the clock and the WWVB simulator, and the schematic
|
|
||||||
* are available online at:
|
|
||||||
* http://www.popsci.com/diy/article/2010-03/build-clock-uses-atomic-timekeeping
|
|
||||||
*
|
|
||||||
* and on GitHub at: http://github.com/vinmarshall/WWVB-Clock
|
|
||||||
*
|
|
||||||
* Version 1.0
|
|
||||||
* Notes:
|
|
||||||
* - No timezone support in this version. UTC only.
|
|
||||||
* - No explicit leapsecond (3 frame marker bits) support in this version.
|
|
||||||
* - 24 hour mode only
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Copyright (c) 2010 Vin Marshall (vlm@2552.com, www.2552.com)
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person
|
|
||||||
* obtaining a copy of this software and associated documentation
|
|
||||||
* files (the "Software"), to deal in the Software without
|
|
||||||
* restriction, including without limitation the rights to use,
|
|
||||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following
|
|
||||||
* conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
||||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
||||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
||||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <LiquidCrystal.h>
|
|
||||||
#include <Wire.h>
|
|
||||||
|
|
||||||
//
|
|
||||||
// Initializations
|
|
||||||
|
|
||||||
// Debugging mode - prints debugging information on the Serial port.
|
|
||||||
boolean debug = true;
|
|
||||||
|
|
||||||
// Front Panel Light
|
|
||||||
int lightPin = 13;
|
|
||||||
|
|
||||||
// WWVB Receiver Pin
|
|
||||||
int wwvbInPin = 2;
|
|
||||||
|
|
||||||
// LCD init
|
|
||||||
LiquidCrystal lcd(12, 11, 6, 5, 4, 3);
|
|
||||||
|
|
||||||
// RTC init
|
|
||||||
// RTC uses pins Analog4 = SDA, Analog5 = SCL
|
|
||||||
|
|
||||||
// RTC I2C Slave Address
|
|
||||||
#define DS1307 0xD0 >> 1
|
|
||||||
|
|
||||||
// RTC Memory Registers
|
|
||||||
#define RTC_SECS 0
|
|
||||||
#define RTC_MINS 1
|
|
||||||
#define RTC_HRS 2
|
|
||||||
#define RTC_DAY 3
|
|
||||||
#define RTC_DATE 4
|
|
||||||
#define RTC_MONTH 5
|
|
||||||
#define RTC_YEAR 6
|
|
||||||
#define RTC_SQW 7
|
|
||||||
|
|
||||||
// Month abbreviations
|
|
||||||
char *months[12] = {
|
|
||||||
"Jan",
|
|
||||||
"Feb",
|
|
||||||
"Mar",
|
|
||||||
"Apr",
|
|
||||||
"May",
|
|
||||||
"Jun",
|
|
||||||
"Jul",
|
|
||||||
"Aug",
|
|
||||||
"Sep",
|
|
||||||
"Oct",
|
|
||||||
"Nov",
|
|
||||||
"Dec"
|
|
||||||
};
|
|
||||||
|
|
||||||
// Day of Year to month translation (thanks to Capt.Tagon)
|
|
||||||
// End of Month - to calculate Month and Day from Day of Year
|
|
||||||
int eomYear[14][2] = {
|
|
||||||
{0,0}, // Begin
|
|
||||||
{31,31}, // Jan
|
|
||||||
{59,60}, // Feb
|
|
||||||
{90,91}, // Mar
|
|
||||||
{120,121}, // Apr
|
|
||||||
{151,152}, // May
|
|
||||||
{181,182}, // Jun
|
|
||||||
{212,213}, // Jul
|
|
||||||
{243,244}, // Aug
|
|
||||||
{273,274}, // Sep
|
|
||||||
{304,305}, // Oct
|
|
||||||
{334,335}, // Nov
|
|
||||||
{365,366}, // Dec
|
|
||||||
{366,367} // overflow
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Globals
|
|
||||||
|
|
||||||
// Timing and error recording
|
|
||||||
unsigned long pulseStartTime = 0;
|
|
||||||
unsigned long pulseEndTime = 0;
|
|
||||||
unsigned long frameEndTime = 0;
|
|
||||||
unsigned long lastRtcUpdateTime = 0;
|
|
||||||
boolean bitReceived = false;
|
|
||||||
boolean wasMark = false;
|
|
||||||
int framePosition = 0;
|
|
||||||
int bitPosition = 1;
|
|
||||||
char lastTimeUpdate[17];
|
|
||||||
char lastBit = ' ';
|
|
||||||
int errors[10] = { 1,1,1,1,1,1,1,1,1,1 };
|
|
||||||
int errIdx = 0;
|
|
||||||
int bitError = 0;
|
|
||||||
boolean frameError = false;
|
|
||||||
|
|
||||||
// RTC clock variables
|
|
||||||
byte second = 0x00;
|
|
||||||
byte minute = 0x00;
|
|
||||||
byte hour = 0x00;
|
|
||||||
byte day = 0x00;
|
|
||||||
byte date = 0x01;
|
|
||||||
byte month = 0x01;
|
|
||||||
byte year = 0x00;
|
|
||||||
byte ctrl = 0x00;
|
|
||||||
|
|
||||||
// WWVB time variables
|
|
||||||
byte wwvb_hour = 0;
|
|
||||||
byte wwvb_minute = 0;
|
|
||||||
byte wwvb_day = 0;
|
|
||||||
byte wwvb_year = 0;
|
|
||||||
|
|
||||||
|
|
||||||
/* WWVB time format struct - acts as an overlay on wwvbRxBuffer to extract time/date data.
|
|
||||||
* This points to a 64 bit buffer wwvbRxBuffer that the bits get inserted into as the
|
|
||||||
* incoming data stream is received. (Thanks to Capt.Tagon @ duinolab.blogspot.com)
|
|
||||||
*/
|
|
||||||
struct wwvbBuffer {
|
|
||||||
unsigned long long U12 :4; // no value, empty four bits only 60 of 64 bits used
|
|
||||||
unsigned long long Frame :2; // framing
|
|
||||||
unsigned long long Dst :2; // dst flags
|
|
||||||
unsigned long long Leapsec :1; // leapsecond
|
|
||||||
unsigned long long Leapyear :1; // leapyear
|
|
||||||
unsigned long long U11 :1; // no value
|
|
||||||
unsigned long long YearOne :4; // year (5 -> 2005)
|
|
||||||
unsigned long long U10 :1; // no value
|
|
||||||
unsigned long long YearTen :4; // year (5 -> 2005)
|
|
||||||
unsigned long long U09 :1; // no value
|
|
||||||
unsigned long long OffVal :4; // offset value
|
|
||||||
unsigned long long U08 :1; // no value
|
|
||||||
unsigned long long OffSign :3; // offset sign
|
|
||||||
unsigned long long U07 :2; // no value
|
|
||||||
unsigned long long DayOne :4; // day ones
|
|
||||||
unsigned long long U06 :1; // no value
|
|
||||||
unsigned long long DayTen :4; // day tens
|
|
||||||
unsigned long long U05 :1; // no value
|
|
||||||
unsigned long long DayHun :2; // day hundreds
|
|
||||||
unsigned long long U04 :3; // no value
|
|
||||||
unsigned long long HourOne :4; // hours ones
|
|
||||||
unsigned long long U03 :1; // no value
|
|
||||||
unsigned long long HourTen :2; // hours tens
|
|
||||||
unsigned long long U02 :3; // no value
|
|
||||||
unsigned long long MinOne :4; // minutes ones
|
|
||||||
unsigned long long U01 :1; // no value
|
|
||||||
unsigned long long MinTen :3; // minutes tens
|
|
||||||
};
|
|
||||||
|
|
||||||
struct wwvbBuffer * wwvbFrame;
|
|
||||||
unsigned long long receiveBuffer;
|
|
||||||
unsigned long long lastFrameBuffer;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* setup()
|
|
||||||
*
|
|
||||||
* uC Initialization
|
|
||||||
*/
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
|
|
||||||
// Debugging information prints to the serial line
|
|
||||||
if (debug) { Serial.begin(9600); }
|
|
||||||
if (debug) { Serial.println("Ready."); }
|
|
||||||
|
|
||||||
// Initialize the I2C Two Wire Communication for the RTC
|
|
||||||
Wire.begin();
|
|
||||||
|
|
||||||
// Set up the LCD's number of rows and columns:
|
|
||||||
lcd.begin(16, 2);
|
|
||||||
|
|
||||||
// Setup the light pin
|
|
||||||
pinMode(lightPin, OUTPUT);
|
|
||||||
digitalWrite(lightPin, HIGH);
|
|
||||||
|
|
||||||
// Print a message to the LCD.
|
|
||||||
lcd.clear();
|
|
||||||
lcd.setCursor(0, 0);
|
|
||||||
lcd.print("WWVB Clock v 1.0");
|
|
||||||
lcd.setCursor(0, 1);
|
|
||||||
lcd.print("PopSci Apr. 2010");
|
|
||||||
delay(5000);
|
|
||||||
|
|
||||||
// Front panel light lights for 10 seconds on a successful frame rcpt.
|
|
||||||
digitalWrite(lightPin, LOW);
|
|
||||||
|
|
||||||
// Setup the WWVB Signal In Handling
|
|
||||||
pinMode(wwvbInPin, INPUT);
|
|
||||||
attachInterrupt(0, wwvbChange, CHANGE);
|
|
||||||
|
|
||||||
// Setup the WWVB Buffer
|
|
||||||
lastFrameBuffer = 0;
|
|
||||||
receiveBuffer = 0;
|
|
||||||
wwvbFrame = (struct wwvbBuffer *) &lastFrameBuffer;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* loop()
|
|
||||||
*
|
|
||||||
* Main program loop
|
|
||||||
*/
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
|
|
||||||
// If we've received another bit, process it
|
|
||||||
if (bitReceived == true) {
|
|
||||||
processBit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read from the RTC and update the display 4x per second
|
|
||||||
if (millis() - lastRtcUpdateTime > 250) {
|
|
||||||
|
|
||||||
// Snag the RTC time and store it locally
|
|
||||||
getRTC();
|
|
||||||
|
|
||||||
// And record the time of this last update.
|
|
||||||
lastRtcUpdateTime = millis();
|
|
||||||
|
|
||||||
// Update RTC if there has been a successfully received WWVB Frame
|
|
||||||
if (frameEndTime != 0) {
|
|
||||||
updateRTC();
|
|
||||||
frameEndTime = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the display
|
|
||||||
updateDisplay();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* updateDisplay()
|
|
||||||
*
|
|
||||||
* Update the 2 line x 16 char LCD display
|
|
||||||
*/
|
|
||||||
|
|
||||||
void updateDisplay() {
|
|
||||||
|
|
||||||
// Turn off the front panel light marking a successfully
|
|
||||||
// received frame after 10 seconds of being on.
|
|
||||||
if (bcd2dec(second) >= 10) {
|
|
||||||
digitalWrite(lightPin, LOW);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the LCD
|
|
||||||
lcd.clear();
|
|
||||||
|
|
||||||
// Update the first row
|
|
||||||
lcd.setCursor(0,0);
|
|
||||||
char *time = buildTimeString();
|
|
||||||
lcd.print(time);
|
|
||||||
|
|
||||||
// Update the second row
|
|
||||||
// Cycle through our list of status messages
|
|
||||||
lcd.setCursor(0,1);
|
|
||||||
int cycle = bcd2dec(second) / 10; // This gives us 6 slots for messages
|
|
||||||
char msg[17]; // 16 chars per line on display
|
|
||||||
|
|
||||||
switch (cycle) {
|
|
||||||
|
|
||||||
// Show the Date
|
|
||||||
case 0:
|
|
||||||
{
|
|
||||||
sprintf(msg, "%s %0.2i 20%0.2i",
|
|
||||||
months[bcd2dec(month)-1], bcd2dec(date), bcd2dec(year));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show the WWVB signal strength based on the # of recent frame errors
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
int signal = (10 - sumFrameErrors()) / 2;
|
|
||||||
sprintf(msg, "WWVB Signal: %i", signal);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show LeapYear and LeapSecond Warning bits
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
const char *leapyear = ( ((byte) wwvbFrame->Leapyear) == 1)?"Yes":"No";
|
|
||||||
const char *leapsec = ( ((byte) wwvbFrame->Leapsec) == 1)?"Yes":"No";
|
|
||||||
sprintf(msg, "LY: %s LS: %s", leapyear, leapsec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show our Daylight Savings Time status
|
|
||||||
case 3:
|
|
||||||
{
|
|
||||||
switch((byte)wwvbFrame->Dst) {
|
|
||||||
case 0:
|
|
||||||
sprintf(msg, "DST: No");
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
sprintf(msg, "DST: Ending");
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
sprintf(msg, "DST: Starting");
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
sprintf(msg, "DST: Yes");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show the UT1 correction sign and amount
|
|
||||||
case 4:
|
|
||||||
{
|
|
||||||
char sign;
|
|
||||||
if ((byte)wwvbFrame->OffSign == 2) {
|
|
||||||
sign = '-';
|
|
||||||
} else if ((byte)wwvbFrame->OffSign == 5) {
|
|
||||||
sign = '+';
|
|
||||||
} else {
|
|
||||||
sign = '?';
|
|
||||||
}
|
|
||||||
sprintf(msg, "UT1 %c 0.%i", sign, (byte) wwvbFrame->OffVal);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show the time and date of the last successfully received
|
|
||||||
// wwvb frame
|
|
||||||
case 5:
|
|
||||||
{
|
|
||||||
sprintf(msg, "[%s]", lastTimeUpdate);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lcd.print(msg);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* buildTimeString
|
|
||||||
*
|
|
||||||
* Prepare the string for displaying the time on line 1 of the LCD
|
|
||||||
*/
|
|
||||||
|
|
||||||
char* buildTimeString() {
|
|
||||||
char rv[255];
|
|
||||||
sprintf(rv,"%0.2i:%0.2i:%0.2i UTC %c",
|
|
||||||
bcd2dec(hour),
|
|
||||||
bcd2dec(minute),
|
|
||||||
bcd2dec(second),
|
|
||||||
lastBit);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* getRTC
|
|
||||||
*
|
|
||||||
* Read data from the DS1307 RTC over the I2C 2 wire interface.
|
|
||||||
* Data is stored in the uC's global clock variables.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void getRTC() {
|
|
||||||
|
|
||||||
// Begin the Transmission
|
|
||||||
Wire.beginTransmission(DS1307);
|
|
||||||
|
|
||||||
// Point the request at the first register (seconds)
|
|
||||||
Wire.send(RTC_SECS);
|
|
||||||
|
|
||||||
// End the Transmission and Start Listening
|
|
||||||
Wire.endTransmission();
|
|
||||||
Wire.requestFrom(DS1307, 8);
|
|
||||||
second = Wire.receive();
|
|
||||||
minute = Wire.receive();
|
|
||||||
hour = Wire.receive();
|
|
||||||
day = Wire.receive();
|
|
||||||
date = Wire.receive();
|
|
||||||
month = Wire.receive();
|
|
||||||
year = Wire.receive();
|
|
||||||
ctrl = Wire.receive();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* setRTC
|
|
||||||
*
|
|
||||||
* Set the DS1307 RTC over the I2C 2 wire interface.
|
|
||||||
* Data is read from the uC's global clock variables.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void setRTC() {
|
|
||||||
|
|
||||||
// Begin the Transmission
|
|
||||||
Wire.beginTransmission(DS1307);
|
|
||||||
|
|
||||||
// Start at the beginning
|
|
||||||
Wire.send(RTC_SECS);
|
|
||||||
|
|
||||||
// Send data for each register in order
|
|
||||||
Wire.send(second);
|
|
||||||
Wire.send(minute);
|
|
||||||
Wire.send(hour);
|
|
||||||
Wire.send(day);
|
|
||||||
Wire.send(date);
|
|
||||||
Wire.send(month);
|
|
||||||
Wire.send(year);
|
|
||||||
Wire.send(ctrl);
|
|
||||||
|
|
||||||
// End the transmission
|
|
||||||
Wire.endTransmission();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* updateRTC
|
|
||||||
*
|
|
||||||
* Update the time stored in the RTC to match the received WWVB frame.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void updateRTC() {
|
|
||||||
|
|
||||||
// Find out how long since the frame's On Time Marker (OTM)
|
|
||||||
// We'll need this adjustment when we set the time.
|
|
||||||
unsigned int timeSinceFrame = millis() - frameEndTime;
|
|
||||||
byte secondsSinceFrame = timeSinceFrame / 1000;
|
|
||||||
if (timeSinceFrame % 1000 > 500) {
|
|
||||||
secondsSinceFrame++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The OTM for a minute comes at the beginning of the frame, meaning that
|
|
||||||
// the WWVB time we have is now 1 minute + `secondsSinceFrame` seconds old.
|
|
||||||
incrementWwvbMinute();
|
|
||||||
|
|
||||||
// Set up data for the RTC clock write
|
|
||||||
second = secondsSinceFrame;
|
|
||||||
minute = ((byte) wwvbFrame->MinTen << 4) + (byte) wwvbFrame->MinOne;
|
|
||||||
hour = ((byte) wwvbFrame->HourTen << 4) + (byte) wwvbFrame->HourOne;
|
|
||||||
day = 0; // we're not using day of week at this time.
|
|
||||||
|
|
||||||
// Translate wwvb day of year into a month and a day of month
|
|
||||||
// This routine is courtesy of Capt.Tagon
|
|
||||||
int doy = ((byte) wwvbFrame->DayHun * 100) +
|
|
||||||
((byte) wwvbFrame->DayTen * 10) +
|
|
||||||
((byte) wwvbFrame->DayOne);
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
byte isLeapyear = (byte) wwvbFrame->Leapyear;
|
|
||||||
while ( (i < 14) && (eomYear[i][isLeapyear] < doy) ) {
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
if (i>0) {
|
|
||||||
date = dec2bcd(doy - eomYear[i-1][isLeapyear]);
|
|
||||||
month = dec2bcd((i > 12)?1:i);
|
|
||||||
}
|
|
||||||
|
|
||||||
year = ((byte) wwvbFrame->YearTen << 4) + (byte) wwvbFrame->YearOne;
|
|
||||||
|
|
||||||
// And write the update to the RTC
|
|
||||||
setRTC();
|
|
||||||
|
|
||||||
// Store the time of update for the display status line
|
|
||||||
sprintf(lastTimeUpdate, "%0.2i:%0.2i %0.2i/%0.2i/%0.2i",
|
|
||||||
bcd2dec(hour), bcd2dec(minute), bcd2dec(month),
|
|
||||||
bcd2dec(date), bcd2dec(year));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* processBit()
|
|
||||||
*
|
|
||||||
* Decode a received pulse. Pulses are decoded according to the
|
|
||||||
* length of time the pulse was in the low state.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void processBit() {
|
|
||||||
|
|
||||||
// Clear the bitReceived flag, as we're processing that bit.
|
|
||||||
bitReceived = false;
|
|
||||||
|
|
||||||
// determine the width of the received pulse
|
|
||||||
unsigned int pulseWidth = pulseEndTime - pulseStartTime;
|
|
||||||
|
|
||||||
// Attempt to decode the pulse into an Unweighted bit (0),
|
|
||||||
// a Weighted bit (1), or a Frame marker.
|
|
||||||
|
|
||||||
// Pulses < 0.2 sec are an error in reception.
|
|
||||||
if (pulseWidth < 100) {
|
|
||||||
buffer(-2);
|
|
||||||
bitError++;
|
|
||||||
wasMark = false;
|
|
||||||
|
|
||||||
// 0.2 sec pulses are an Unweighted bit (0)
|
|
||||||
} else if (pulseWidth < 400) {
|
|
||||||
buffer(0);
|
|
||||||
wasMark = false;
|
|
||||||
|
|
||||||
// 0.5 sec pulses are a Weighted bit (1)
|
|
||||||
} else if (pulseWidth < 700) {
|
|
||||||
buffer(1);
|
|
||||||
wasMark = false;
|
|
||||||
|
|
||||||
// 0.8 sec pulses are a Frame Marker
|
|
||||||
} else if (pulseWidth < 900) {
|
|
||||||
|
|
||||||
// Two Frame Position markers in a row indicate an
|
|
||||||
// end/beginning of frame marker
|
|
||||||
if (wasMark) {
|
|
||||||
|
|
||||||
// For the display update
|
|
||||||
lastBit = '*';
|
|
||||||
if (debug) { Serial.print("*"); }
|
|
||||||
|
|
||||||
// Verify that our position data jives with this being
|
|
||||||
// a Frame start/end marker
|
|
||||||
if ( (framePosition == 6) &&
|
|
||||||
(bitPosition == 60) &&
|
|
||||||
(bitError == 0)) {
|
|
||||||
|
|
||||||
// Process a received frame
|
|
||||||
frameEndTime = pulseStartTime;
|
|
||||||
lastFrameBuffer = receiveBuffer;
|
|
||||||
digitalWrite(lightPin, HIGH);
|
|
||||||
logFrameError(false);
|
|
||||||
|
|
||||||
if (debug) {
|
|
||||||
debugPrintFrame();
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
frameError = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset the position counters
|
|
||||||
framePosition = 0;
|
|
||||||
bitPosition = 1;
|
|
||||||
wasMark = false;
|
|
||||||
bitError = 0;
|
|
||||||
receiveBuffer = 0;
|
|
||||||
|
|
||||||
// Otherwise, this was just a regular frame position marker
|
|
||||||
} else {
|
|
||||||
|
|
||||||
buffer(-1);
|
|
||||||
wasMark = true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pulses > 0.8 sec are an error in reception
|
|
||||||
} else {
|
|
||||||
buffer(-2);
|
|
||||||
bitError++;
|
|
||||||
wasMark = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset everything if we have more than 60 bits in the frame. This means
|
|
||||||
// the frame markers went missing somewhere along the line
|
|
||||||
if (frameError == true || bitPosition > 60) {
|
|
||||||
|
|
||||||
// Debugging
|
|
||||||
if (debug) { Serial.print(" Frame Error\n"); }
|
|
||||||
|
|
||||||
// Reset all of the frame pointers and flags
|
|
||||||
frameError = false;
|
|
||||||
logFrameError(true);
|
|
||||||
framePosition = 0;
|
|
||||||
bitPosition = 1;
|
|
||||||
wasMark = false;
|
|
||||||
bitError = 0;
|
|
||||||
receiveBuffer = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* logFrameError
|
|
||||||
*
|
|
||||||
* Log the error in the buffer that is a window on the past 10 frames.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void logFrameError(boolean err) {
|
|
||||||
|
|
||||||
// Add a 1 to log errors to the buffer
|
|
||||||
int add = err?1:0;
|
|
||||||
errors[errIdx] = add;
|
|
||||||
|
|
||||||
// and move the buffer loop-around pointer
|
|
||||||
if (++errIdx >= 10) {
|
|
||||||
errIdx = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* sumFrameErrors
|
|
||||||
*
|
|
||||||
* Turn the errors in the frame error buffer into a number useful to display
|
|
||||||
* the quality of reception of late in the status messages. Sums the errors
|
|
||||||
* in the frame error buffer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int sumFrameErrors() {
|
|
||||||
|
|
||||||
// Sum all of the values in our error buffer
|
|
||||||
int i, rv;
|
|
||||||
for (i=0; i< 10; i++) {
|
|
||||||
rv += errors[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* debugPrintFrame
|
|
||||||
*
|
|
||||||
* Print the decoded frame over the seriail port
|
|
||||||
*/
|
|
||||||
|
|
||||||
void debugPrintFrame() {
|
|
||||||
|
|
||||||
char time[255];
|
|
||||||
byte minTen = (byte) wwvbFrame->MinTen;
|
|
||||||
byte minOne = (byte) wwvbFrame->MinOne;
|
|
||||||
byte hourTen = (byte) wwvbFrame->HourTen;
|
|
||||||
byte hourOne = (byte) wwvbFrame->HourOne;
|
|
||||||
byte dayHun = (byte) wwvbFrame->DayHun;
|
|
||||||
byte dayTen = (byte) wwvbFrame->DayTen;
|
|
||||||
byte dayOne = (byte) wwvbFrame->DayOne;
|
|
||||||
byte yearOne = (byte) wwvbFrame->YearOne;
|
|
||||||
byte yearTen = (byte) wwvbFrame->YearTen;
|
|
||||||
|
|
||||||
byte wwvb_minute = (10 * minTen) + minOne;
|
|
||||||
byte wwvb_hour = (10 * hourTen) + hourOne;
|
|
||||||
byte wwvb_day = (100 * dayHun) + (10 * dayTen) + dayOne;
|
|
||||||
byte wwvb_year = (10 * yearTen) + yearOne;
|
|
||||||
|
|
||||||
sprintf(time, "\nFrame Decoded: %0.2i:%0.2i %0.3i 20%0.2i\n",
|
|
||||||
wwvb_hour, wwvb_minute, wwvb_day, wwvb_year);
|
|
||||||
Serial.print(time);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* buffer
|
|
||||||
*
|
|
||||||
* Places the received bits in the receive buffer in the order they
|
|
||||||
* were recived. The first received bit goes in the highest order
|
|
||||||
* bit of the receive buffer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void buffer(int bit) {
|
|
||||||
|
|
||||||
// Process our bits
|
|
||||||
if (bit == 0) {
|
|
||||||
lastBit = '0';
|
|
||||||
if (debug) { Serial.print("0"); }
|
|
||||||
|
|
||||||
} else if (bit == 1) {
|
|
||||||
lastBit = '1';
|
|
||||||
if (debug) { Serial.print("1"); }
|
|
||||||
|
|
||||||
} else if (bit == -1) {
|
|
||||||
lastBit = 'M';
|
|
||||||
if (debug) { Serial.print("M"); }
|
|
||||||
framePosition++;
|
|
||||||
|
|
||||||
} else if (bit == -2) {
|
|
||||||
lastBit = 'X';
|
|
||||||
if (debug) { Serial.print("X"); }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Push the bit into the buffer. The 0s and 1s are the only
|
|
||||||
// ones we care about.
|
|
||||||
if (bit < 0) { bit = 0; }
|
|
||||||
receiveBuffer = receiveBuffer | ( (unsigned long long) bit << (64 - bitPosition) );
|
|
||||||
|
|
||||||
// And increment the counters that keep track of where we are
|
|
||||||
// in the frame.
|
|
||||||
bitPosition++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* incrementWwvbMinute
|
|
||||||
*
|
|
||||||
* The frame On Time Marker occurs at the beginning of the frame. This means
|
|
||||||
* that the time in the frame is one minute old by the time it has been fully
|
|
||||||
* received. Adding one to the minute can be somewhat complicated, in as much
|
|
||||||
* as it can roll over the successive hours, days, and years in just the right
|
|
||||||
* circumstances. This handles that.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void incrementWwvbMinute() {
|
|
||||||
|
|
||||||
// Increment the Time and Date
|
|
||||||
if (++(wwvbFrame->MinOne) == 10) {
|
|
||||||
wwvbFrame->MinOne = 0;
|
|
||||||
wwvbFrame->MinTen++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wwvbFrame->MinTen == 6) {
|
|
||||||
wwvbFrame->MinTen = 0;
|
|
||||||
wwvbFrame->HourOne++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wwvbFrame->HourOne == 10) {
|
|
||||||
wwvbFrame->HourOne = 0;
|
|
||||||
wwvbFrame->HourTen++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (wwvbFrame->HourTen == 2) && (wwvbFrame->HourOne == 4) ) {
|
|
||||||
wwvbFrame->HourTen = 0;
|
|
||||||
wwvbFrame->HourOne = 0;
|
|
||||||
wwvbFrame->DayOne++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wwvbFrame->DayOne == 10) {
|
|
||||||
wwvbFrame->DayOne = 0;
|
|
||||||
wwvbFrame->DayTen++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wwvbFrame->DayTen == 10) {
|
|
||||||
wwvbFrame->DayTen = 0;
|
|
||||||
wwvbFrame->DayHun++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (wwvbFrame->DayHun == 3) &&
|
|
||||||
(wwvbFrame->DayTen == 6) &&
|
|
||||||
(wwvbFrame->DayOne == (6 + (int) wwvbFrame->Leapyear)) ) {
|
|
||||||
// Happy New Year.
|
|
||||||
wwvbFrame->DayHun = 0;
|
|
||||||
wwvbFrame->DayTen = 0;
|
|
||||||
wwvbFrame->DayOne = 1;
|
|
||||||
wwvbFrame->YearOne++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wwvbFrame->YearOne == 10) {
|
|
||||||
wwvbFrame->YearOne = 0;
|
|
||||||
wwvbFrame->YearTen++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wwvbFrame->YearTen == 10) {
|
|
||||||
wwvbFrame->YearTen = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* wwvbChange
|
|
||||||
*
|
|
||||||
* This is the interrupt servicing routine. Changes in the level of the
|
|
||||||
* received WWVB pulse are recorded here to be processed in processBit().
|
|
||||||
*/
|
|
||||||
|
|
||||||
void wwvbChange() {
|
|
||||||
|
|
||||||
int signalLevel = digitalRead(wwvbInPin);
|
|
||||||
|
|
||||||
// Determine if this was triggered by a rising or a falling edge
|
|
||||||
// and record the pulse low period start and stop times
|
|
||||||
if (signalLevel == LOW) {
|
|
||||||
pulseStartTime = millis();
|
|
||||||
} else {
|
|
||||||
pulseEndTime = millis();
|
|
||||||
bitReceived = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* bcd2dec
|
|
||||||
*
|
|
||||||
* Utility function to convert 2 bcd coded hex digits into an integer
|
|
||||||
*/
|
|
||||||
|
|
||||||
int bcd2dec(int bcd) {
|
|
||||||
return ( (bcd>>4) * 10) + (bcd % 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* dec2bcd
|
|
||||||
*
|
|
||||||
* Utility function to convert an integer into 2 bcd coded hex digits
|
|
||||||
*/
|
|
||||||
|
|
||||||
int dec2bcd(int dec) {
|
|
||||||
return ( (dec/10) << 4) + (dec % 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,175 +0,0 @@
|
|||||||
94.34
|
|
||||||
39.62
|
|
||||||
67.36
|
|
||||||
48.64
|
|
||||||
71.57
|
|
||||||
78.93
|
|
||||||
86.80
|
|
||||||
37.59
|
|
||||||
41.87
|
|
||||||
76.45
|
|
||||||
65.54
|
|
||||||
70.19
|
|
||||||
77.87
|
|
||||||
73.15
|
|
||||||
70.13
|
|
||||||
33.27
|
|
||||||
27.52
|
|
||||||
87.68
|
|
||||||
74.66
|
|
||||||
49.75
|
|
||||||
74.90
|
|
||||||
68.83
|
|
||||||
69.74
|
|
||||||
58.10
|
|
||||||
49.23
|
|
||||||
61.75
|
|
||||||
94.63
|
|
||||||
85.94
|
|
||||||
46.70
|
|
||||||
68.18
|
|
||||||
48.62
|
|
||||||
75.80
|
|
||||||
50.17
|
|
||||||
52.28
|
|
||||||
66.22
|
|
||||||
68.36
|
|
||||||
70.89
|
|
||||||
46.68
|
|
||||||
71.96
|
|
||||||
90.99
|
|
||||||
74.44
|
|
||||||
97.34
|
|
||||||
22.63
|
|
||||||
25.14
|
|
||||||
54.39
|
|
||||||
47.70
|
|
||||||
80.27
|
|
||||||
75.28
|
|
||||||
73.23
|
|
||||||
63.09
|
|
||||||
71.75
|
|
||||||
73.39
|
|
||||||
29.64
|
|
||||||
60.99
|
|
||||||
78.13
|
|
||||||
73.29
|
|
||||||
52.33
|
|
||||||
68.42
|
|
||||||
71.71
|
|
||||||
60.31
|
|
||||||
54.13
|
|
||||||
76.60
|
|
||||||
58.99
|
|
||||||
75.99
|
|
||||||
85.64
|
|
||||||
74.30
|
|
||||||
77.69
|
|
||||||
79.76
|
|
||||||
79.61
|
|
||||||
60.93
|
|
||||||
54.99
|
|
||||||
45.50
|
|
||||||
81.65
|
|
||||||
74.05
|
|
||||||
67.01
|
|
||||||
85.79
|
|
||||||
83.92
|
|
||||||
76.03
|
|
||||||
72.04
|
|
||||||
32.79
|
|
||||||
33.62
|
|
||||||
67.26
|
|
||||||
71.17
|
|
||||||
78.02
|
|
||||||
63.84
|
|
||||||
67.86
|
|
||||||
58.04
|
|
||||||
71.88
|
|
||||||
72.92
|
|
||||||
72.11
|
|
||||||
68.45
|
|
||||||
68.71
|
|
||||||
93.77
|
|
||||||
65.92
|
|
||||||
78.33
|
|
||||||
63.78
|
|
||||||
58.41
|
|
||||||
48.74
|
|
||||||
71.87
|
|
||||||
53.10
|
|
||||||
80.33
|
|
||||||
58.18
|
|
||||||
72.19
|
|
||||||
79.94
|
|
||||||
85.44
|
|
||||||
78.55
|
|
||||||
82.78
|
|
||||||
71.12
|
|
||||||
63.79
|
|
||||||
62.94
|
|
||||||
63.66
|
|
||||||
58.44
|
|
||||||
50.59
|
|
||||||
91.02
|
|
||||||
89.28
|
|
||||||
68.35
|
|
||||||
86.34
|
|
||||||
31.90
|
|
||||||
69.33
|
|
||||||
65.45
|
|
||||||
76.41
|
|
||||||
83.79
|
|
||||||
73.95
|
|
||||||
73.08
|
|
||||||
60.52
|
|
||||||
51.60
|
|
||||||
59.42
|
|
||||||
82.91
|
|
||||||
82.62
|
|
||||||
64.72
|
|
||||||
69.13
|
|
||||||
67.46
|
|
||||||
71.94
|
|
||||||
78.55
|
|
||||||
73.33
|
|
||||||
70.58
|
|
||||||
80.87
|
|
||||||
77.23
|
|
||||||
75.79
|
|
||||||
87.83
|
|
||||||
88.32
|
|
||||||
79.55
|
|
||||||
60.92
|
|
||||||
71.68
|
|
||||||
69.79
|
|
||||||
83.03
|
|
||||||
89.25
|
|
||||||
76.60
|
|
||||||
55.45
|
|
||||||
67.67
|
|
||||||
82.52
|
|
||||||
77.72
|
|
||||||
65.99
|
|
||||||
60.15
|
|
||||||
73.46
|
|
||||||
68.14
|
|
||||||
61.96
|
|
||||||
85.54
|
|
||||||
64.17
|
|
||||||
83.86
|
|
||||||
61.66
|
|
||||||
79.66
|
|
||||||
64.02
|
|
||||||
45.70
|
|
||||||
76.10
|
|
||||||
63.10
|
|
||||||
64.77
|
|
||||||
94.71
|
|
||||||
76.37
|
|
||||||
75.78
|
|
||||||
76.00
|
|
||||||
35.66
|
|
||||||
65.96
|
|
||||||
68.23
|
|
||||||
91.41
|
|
|
File diff suppressed because it is too large
Load Diff
@ -1,405 +0,0 @@
|
|||||||
#include <LiquidCrystal_I2C.h>
|
|
||||||
LiquidCrystal_I2C lcd(0x27, 16, 2);
|
|
||||||
|
|
||||||
#define SERIAL_RATE 115200
|
|
||||||
#define WWV_SIGNAL_PIN 14
|
|
||||||
#define PPS_OUTPUT_PIN 16
|
|
||||||
#define LOSC_INPUT_PIN 0
|
|
||||||
#define DEBUG1_OUTPUT_PIN 15
|
|
||||||
|
|
||||||
#define ONEBIT 1
|
|
||||||
#define ZEROBIT 2
|
|
||||||
#define MARKBIT 3
|
|
||||||
|
|
||||||
#define NUM_SAMPLES_PER_FRAME 32000
|
|
||||||
#define CLOCKS_PER_MS 32
|
|
||||||
|
|
||||||
char statusString[25] = "LOS";
|
|
||||||
|
|
||||||
volatile unsigned int lowLatencyInState;
|
|
||||||
volatile unsigned int wwvbInState;
|
|
||||||
volatile unsigned int lastWWVBInState;
|
|
||||||
|
|
||||||
volatile unsigned int stateStableCounter = 0;
|
|
||||||
volatile unsigned int stateStableMillis = 0;
|
|
||||||
volatile unsigned int lastStateStableMillis = 0;
|
|
||||||
|
|
||||||
volatile unsigned int secondCounter = 0;
|
|
||||||
volatile unsigned int milliCounter = 0;
|
|
||||||
volatile unsigned int clockCounter = 0;
|
|
||||||
|
|
||||||
volatile unsigned int timeToTick = 0;
|
|
||||||
volatile unsigned int frameReadyToStart = 0;
|
|
||||||
volatile unsigned int beginFrameSearch = 0;
|
|
||||||
volatile unsigned int frameSamples = 0;
|
|
||||||
volatile unsigned int lossOfSignal = 1;
|
|
||||||
volatile unsigned int displayUpdateRequired = 1;
|
|
||||||
volatile unsigned int frameSearch = 0;
|
|
||||||
volatile unsigned int frameStart = 0;
|
|
||||||
volatile unsigned int frameStartTime = 0;
|
|
||||||
volatile unsigned int frameHigh = 0;
|
|
||||||
volatile unsigned int frameHighReadOut = 0;
|
|
||||||
volatile unsigned int frameLow = 0;
|
|
||||||
volatile unsigned int frameLowReadOut = 0;
|
|
||||||
volatile unsigned int frameCounter = 0;
|
|
||||||
volatile unsigned int frameReadyForRead = 0;
|
|
||||||
volatile unsigned int lastBitReceived = 0;
|
|
||||||
volatile unsigned int millisSinceBoot = 0;
|
|
||||||
volatile unsigned int ppsActivationTime;
|
|
||||||
volatile unsigned int millisSinceSignalStateChange = 0;
|
|
||||||
volatile unsigned int minuteSync = 0;
|
|
||||||
|
|
||||||
void ICACHE_RAM_ATTR WWVFallingEdge();
|
|
||||||
void ICACHE_RAM_ATTR OSCEdge();
|
|
||||||
void ICACHE_RAM_ATTR MilliEdge();
|
|
||||||
void ICACHE_RAM_ATTR SecondEdge();
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
pinMode(LED_BUILTIN, OUTPUT);
|
|
||||||
pinMode(PPS_OUTPUT_PIN, OUTPUT);
|
|
||||||
pinMode(DEBUG1_OUTPUT_PIN, OUTPUT);
|
|
||||||
pinMode(WWV_SIGNAL_PIN, INPUT);
|
|
||||||
pinMode(LOSC_INPUT_PIN, INPUT);
|
|
||||||
attachInterrupt(digitalPinToInterrupt(LOSC_INPUT_PIN), OSCEdge, RISING);
|
|
||||||
lcd.init();
|
|
||||||
lcd.backlight();
|
|
||||||
lcd.setCursor(0, 0);
|
|
||||||
lcd.print("booting");
|
|
||||||
Serial.begin(SERIAL_RATE);
|
|
||||||
Serial.print("\n\n************\n\nherro booted\n");
|
|
||||||
ppsActivationTime = millis();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSCEdge() {
|
|
||||||
clockCounter++;
|
|
||||||
if(clockCounter > CLOCKS_PER_MS) {
|
|
||||||
clockCounter -= CLOCKS_PER_MS;
|
|
||||||
|
|
||||||
// *****************************************************************************
|
|
||||||
// LOW LATENCY HACK to respond in 1/32nd of a ms to a falling
|
|
||||||
// start-of-second edge
|
|
||||||
// respond really fast to a falling edge if in the frameReadyToStart
|
|
||||||
// state
|
|
||||||
lowLatencyInState = digitalRead(WWV_SIGNAL_PIN);
|
|
||||||
if(!lowLatencyInState && frameReadyToStart && !lossOfSignal && !frameStart) {
|
|
||||||
// TICK!
|
|
||||||
// falling edge, beginning of a new frame and second
|
|
||||||
digitalWrite(PPS_OUTPUT_PIN, 1);
|
|
||||||
timeToTick = 1;
|
|
||||||
frameStart = 1;
|
|
||||||
frameStartTime = millisSinceBoot;
|
|
||||||
frameReadyToStart = 0;
|
|
||||||
frameSearch = 0;
|
|
||||||
}
|
|
||||||
// *****************************************************************************
|
|
||||||
MilliEdge();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SecondEdge() {
|
|
||||||
secondCounter++;
|
|
||||||
displayUpdateRequired = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MilliEdge() {
|
|
||||||
digitalWrite(DEBUG1_OUTPUT_PIN, 1);
|
|
||||||
wwvbInState = digitalRead(WWV_SIGNAL_PIN);
|
|
||||||
|
|
||||||
milliCounter++;
|
|
||||||
millisSinceBoot++;
|
|
||||||
|
|
||||||
if(milliCounter > 1000) {
|
|
||||||
milliCounter -= 1000;
|
|
||||||
SecondEdge();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(wwvbInState == lastWWVBInState) {
|
|
||||||
stateStableMillis++;
|
|
||||||
|
|
||||||
if(stateStableMillis > 1000) {
|
|
||||||
stateStableMillis = 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
//edge of some sort.
|
|
||||||
lastStateStableMillis = stateStableMillis;
|
|
||||||
// if it's a falling edge
|
|
||||||
if(!wwvbInState && (stateStableMillis > 100) && (stateStableMillis < 2000)) {
|
|
||||||
// main screen turn on
|
|
||||||
lossOfSignal = 0;
|
|
||||||
frameSearch = 1;
|
|
||||||
}
|
|
||||||
stateStableMillis = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastWWVBInState = wwvbInState; // copy/save for next loop
|
|
||||||
|
|
||||||
if((stateStableMillis > 2000) && !lossOfSignal) {
|
|
||||||
// we have received nothing for 2 seconds, loss of signal:
|
|
||||||
lossOfSignal = 1;
|
|
||||||
frameStart = 0;
|
|
||||||
frameCounter = 0;
|
|
||||||
minuteSync = 0;
|
|
||||||
digitalWrite(DEBUG1_OUTPUT_PIN, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(frameSearch && wwvbInState) {
|
|
||||||
// if we have been high for 100ms (frameSearch) we are ready to start a new frame on the mark
|
|
||||||
frameHigh = 0;
|
|
||||||
frameLow = 0;
|
|
||||||
frameReadyToStart = 1;
|
|
||||||
digitalWrite(DEBUG1_OUTPUT_PIN, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (frameStart && (frameSamples < NUM_SAMPLES_PER_FRAME)) {
|
|
||||||
//begin sampling
|
|
||||||
if (wwvbInState) {
|
|
||||||
frameHigh++;
|
|
||||||
} else {
|
|
||||||
frameLow++;
|
|
||||||
}
|
|
||||||
frameSamples++;
|
|
||||||
digitalWrite(DEBUG1_OUTPUT_PIN, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(frameStart && (frameSamples >= NUM_SAMPLES_PER_FRAME)) {
|
|
||||||
frameReadyForRead = 1;
|
|
||||||
frameHighReadOut = frameHigh;
|
|
||||||
frameLowReadOut = frameLow;
|
|
||||||
frameStart = 0;
|
|
||||||
frameHigh = 0;
|
|
||||||
frameLow = 0;
|
|
||||||
frameSamples = 0;
|
|
||||||
}
|
|
||||||
digitalWrite(DEBUG1_OUTPUT_PIN, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
char pb[255];
|
|
||||||
// the loop function runs over and over again forever
|
|
||||||
void loop() {
|
|
||||||
digitalWrite(LED_BUILTIN, !wwvbInState);
|
|
||||||
|
|
||||||
if(timeToTick) {
|
|
||||||
Serial.println("*** TICK in loop()");
|
|
||||||
timeToTick = 0;
|
|
||||||
TickSecond();
|
|
||||||
}
|
|
||||||
|
|
||||||
yield();
|
|
||||||
|
|
||||||
if(frameReadyForRead) {
|
|
||||||
Serial.println("*** processFrame() in loop()");
|
|
||||||
frameReadyForRead = 0;
|
|
||||||
processFrame();
|
|
||||||
}
|
|
||||||
|
|
||||||
yield();
|
|
||||||
|
|
||||||
PPSLowIfRequired();
|
|
||||||
|
|
||||||
yield();
|
|
||||||
|
|
||||||
if (displayUpdateRequired) {
|
|
||||||
Serial.println("*** updateDisplay() in loop()");
|
|
||||||
sprintf(pb,"*** secondCounter=%d\n", secondCounter);
|
|
||||||
Serial.print(pb);
|
|
||||||
updateDisplay();
|
|
||||||
displayUpdateRequired = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetPPSHigh() {
|
|
||||||
digitalWrite(PPS_OUTPUT_PIN, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetPPSLow() {
|
|
||||||
digitalWrite(PPS_OUTPUT_PIN, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SendPPS() {
|
|
||||||
unsigned int tickInterval = millisSinceBoot - ppsActivationTime;
|
|
||||||
ppsActivationTime = millisSinceBoot;
|
|
||||||
SetPPSHigh();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PPSLowIfRequired() {
|
|
||||||
if ((millisSinceBoot - ppsActivationTime) > 500) {
|
|
||||||
SetPPSLow();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TickSecond() {
|
|
||||||
char buf[255];
|
|
||||||
sprintf(buf, "TICK(%d): WWVB going low after %d ms high\n", frameCounter, lastStateStableMillis);
|
|
||||||
SendPPS();
|
|
||||||
Serial.print(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void processFrame() {
|
|
||||||
char buf[255];
|
|
||||||
sprintf(buf, "end of frame summary: frameHigh: %d, frameLow: %d\n", frameHighReadOut, frameLowReadOut);
|
|
||||||
Serial.print(buf);
|
|
||||||
float rawVal = (float)frameHighReadOut / frameLowReadOut;
|
|
||||||
rawVal *= 1000;
|
|
||||||
unsigned int intRawVal = (int)rawVal;
|
|
||||||
if (intRawVal > 100000) {
|
|
||||||
intRawVal = 100000;
|
|
||||||
}
|
|
||||||
displayUpdateRequired++;
|
|
||||||
registerBit(convertDutyCycleToBit(intRawVal));
|
|
||||||
}
|
|
||||||
|
|
||||||
int convertDutyCycleToBit(unsigned int rawVal) {
|
|
||||||
char buf[255];
|
|
||||||
/*
|
|
||||||
|
|
||||||
20% - marker
|
|
||||||
50% - one bit
|
|
||||||
80% - zero bit
|
|
||||||
our cutoff points will be 50% and 80%
|
|
||||||
*/
|
|
||||||
char bitbuf[20];
|
|
||||||
|
|
||||||
int output = 0;
|
|
||||||
output = ZEROBIT;
|
|
||||||
sprintf(bitbuf, "ZERO");
|
|
||||||
|
|
||||||
if (rawVal > 20000) {
|
|
||||||
output = MARKBIT;
|
|
||||||
sprintf(bitbuf, "MARK");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rawVal > 30000) {
|
|
||||||
output = ONEBIT;
|
|
||||||
sprintf(bitbuf, "ONE");
|
|
||||||
}
|
|
||||||
|
|
||||||
sprintf(buf, "frame rawVal=%d, bit=%s\n", rawVal, bitbuf);
|
|
||||||
Serial.print(buf);
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
void registerBit(int doot) {
|
|
||||||
if (minuteSync) {
|
|
||||||
frameCounter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (doot == MARKBIT) {
|
|
||||||
if (lastBitReceived == MARKBIT) {
|
|
||||||
// two mark bits in a row means we are in the first second of the minute
|
|
||||||
frameCounter = 0;
|
|
||||||
minuteSync = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!minuteSync) {
|
|
||||||
frameCounter = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
sanityCheckFrame(doot);
|
|
||||||
lastBitReceived = doot;
|
|
||||||
logBit(doot);
|
|
||||||
}
|
|
||||||
|
|
||||||
void logBit(int doot) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void lossOfSync(int errorFrame) {
|
|
||||||
char buf[255];
|
|
||||||
sprintf(buf, "ERROR: %d bit incorrect for framing, loss of sync!\n", errorFrame);
|
|
||||||
Serial.print(buf);
|
|
||||||
minuteSync = 0;
|
|
||||||
displayUpdateRequired++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void sanityCheckFrame(int doot) {
|
|
||||||
if (
|
|
||||||
(
|
|
||||||
(frameCounter == 9)
|
|
||||||
||
|
|
||||||
(frameCounter == 19)
|
|
||||||
||
|
|
||||||
(frameCounter == 29)
|
|
||||||
||
|
|
||||||
(frameCounter == 39)
|
|
||||||
||
|
|
||||||
(frameCounter == 49)
|
|
||||||
)
|
|
||||||
&& doot != MARKBIT) {
|
|
||||||
lossOfSync(frameCounter);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
(doot == MARKBIT)
|
|
||||||
&&
|
|
||||||
(
|
|
||||||
(frameCounter != 0)
|
|
||||||
&&
|
|
||||||
(frameCounter != 9)
|
|
||||||
&&
|
|
||||||
(frameCounter != 19)
|
|
||||||
&&
|
|
||||||
(frameCounter != 29)
|
|
||||||
&&
|
|
||||||
(frameCounter != 39)
|
|
||||||
&&
|
|
||||||
(frameCounter != 49)
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
lossOfSync(frameCounter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateDisplay() {
|
|
||||||
//Serial.print("updateDisplay()\n");
|
|
||||||
|
|
||||||
if (frameStart) {
|
|
||||||
// don't do anything if we are currently sampling.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lossOfSignal) {
|
|
||||||
sprintf(statusString, "LOS");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (millisSinceBoot - frameStartTime < 10000) {
|
|
||||||
sprintf(statusString, "RX(syncing)");
|
|
||||||
}
|
|
||||||
if (minuteSync) {
|
|
||||||
sprintf(statusString, "RX(bit %d)", frameCounter);
|
|
||||||
}
|
|
||||||
|
|
||||||
char d[20];
|
|
||||||
|
|
||||||
if (lastBitReceived == MARKBIT) {
|
|
||||||
sprintf(d, "%d=MARK", frameCounter);
|
|
||||||
}
|
|
||||||
if (lastBitReceived == ONEBIT) {
|
|
||||||
sprintf(d, "%d=ONE ", frameCounter);
|
|
||||||
}
|
|
||||||
if (lastBitReceived == ZEROBIT) {
|
|
||||||
sprintf(d, "%d=ZERO", frameCounter);
|
|
||||||
}
|
|
||||||
|
|
||||||
lcd.clear();
|
|
||||||
lcd.setCursor(0, 0);
|
|
||||||
char msg[20];
|
|
||||||
sprintf(msg, "up:%03d", millisSinceBoot/1000);
|
|
||||||
lcd.print(msg);
|
|
||||||
lcd.setCursor(0, 1);
|
|
||||||
sprintf(msg, "s:%s", statusString);
|
|
||||||
lcd.print(msg);
|
|
||||||
|
|
||||||
|
|
||||||
if (minuteSync) {
|
|
||||||
lcd.setCursor(10, 0);
|
|
||||||
lcd.print(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -5,7 +5,7 @@ set -x
|
|||||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
|
||||||
INPUTFILE="$DIR/all.txt"
|
INPUTFILE="$DIR/all.txt"
|
||||||
DESTDIR="/Volumes/EXT/tmp/jwztv-youtube-scrape"
|
DESTDIR="/Volumes/movies/_MUSIC_VIDEOS/jwztv-youtube-scrape"
|
||||||
|
|
||||||
while IFS= read -r SEARCHTERM; do
|
while IFS= read -r SEARCHTERM; do
|
||||||
cd $DESTDIR
|
cd $DESTDIR
|
||||||
|
Loading…
Reference in New Issue
Block a user