#include <TinyGPSPlus.h>
#include <SoftwareSerial.h>
#include <EEPROM.h>
#include <TimeLib.h> //this is needed to read internal time
#include <Wire.h> //this is needed for light sensor
#include "Adafruit_VEML7700.h" //this is needed for light sensor
static const int RXPin = 1, TXPin = 0; //GPS - Rx wire on GPS to 1, Tx to 0
const int buttonPin1 = 24, buttonPin2 = 25; // push button 1 is to allign, 2 for resetting OCXO
const int buttonPin3 = 9, buttonPin4 = 10; //
const byte Main_Pin = 34; //OCXO 5MHz
const byte Control_Pin = 22; //NEO PPS pin 2x per second
const int ledPin = 13; // led on the arduino itself
SoftwareSerial DisplaySerial(28, 29); // RX, TX
Adafruit_VEML7700 sensor = Adafruit_VEML7700();
static const uint32_t GPSBaud = 9600;
long TicsPerMinute = 300000540;
volatile boolean gps_start = 1; //is used to show when GPS has been initialized, i.e. location was fixed
volatile boolean pps_start = 1; //this is needed when pps signal was not avilable from the start, thus additional 2 minutes of allignemnt is needed
volatile boolean allign = 0; // 1 - match time and 0 - not
volatile boolean allign2 = 0;
volatile boolean pps_live = 0; // 1 - match time and 0 - not
int Time_Zone = 2; //delta to be added to UTC time received from GPS: 1=winter and 2=summer
int o_Time_Zone = 2;
long startSeconds; // execute update time every second, when startSeconds change
long TotalSeconds = 0; //counting uninterrupted days of work via GPS
int buttonState1 = 0, buttonState2 = 0, buttonState3 = 0, buttonState4 = 0;
int Prev_buttonState1 = 0, Prev_buttonState2 = 0, Prev_buttonState3 = 0, Prev_buttonState4 = 0;
int Pushed_button1 = 0, Pushed_button2 = 0, Pushed_button4 = 0;
long sec_buttonState1 = 0, sec_buttonState2 = 0, sec_buttonState4 = 0;
int Hour, Hours, Minutes, Seconds, xMinutes = 99;
int Brightness = 3; //bright
int min_to_ignore = 3; // 0 - bright outside; 999 - dark
int Prev_is_night_state = 0;
int mario_i = 1, mario_x = -33;
int allign2_count, allign2_delta;
int b = 100, b0 = 100; //brightness in nextion format
//int light_data;
//uint16_t lux; //brightness from sensor
char Satellites[3];
float forecasted_dev_in_sec;
char log_filename[40];
volatile long HZCount = 0; // use volatile for shared variables
volatile long HZCopy, HZTotal, HZStart, TicsPerSecond, TicsPerHalfSecond; // holds a copy of the count
volatile long oSeconds;
long oDays, oHours = 0, oMinutes = 0, oTotalSeconds2, oTotalSeconds1, oTotalSeconds3, oTotalSeconds4, TicsPerDay, TicsPerYear, GPSCopy, GPSTotal; //o is for ocxo from start
volatile long i, j, J, i_check, j_check;
long currHours, currMinutes, pps_error, pps_shift, pps_i; // ocxo alligned time
TinyGPSPlus gps; // The TinyGPSPlus object
SoftwareSerial ss(TXPin, RXPin); // The serial connection to the GPS device
TinyGPSCustom sats(gps, "GPGSV", 3); //GPGSV - is for GPS satellites only, number of sats (3rd value in the line)
void setup() {
Serial.begin(9600);
DisplaySerial.begin(9600);
ss.begin(GPSBaud);
Serial.println(F("OCXO + Satellite Clock. Andrey Bolger"));
pinMode(ledPin, OUTPUT); // initialize Led
pinMode(buttonPin1, INPUT_PULLUP); // allign time like from the start
pinMode(buttonPin2, INPUT_PULLUP); // reset counts only : button 1 for resetting OCXO count and times
pinMode(buttonPin3, INPUT_PULLUP); // brightness
pinMode(buttonPin4, INPUT_PULLUP); // fine tune: perform 1 hour delta calc
//pinMode(LDIO, INPUT);
pinMode(Main_Pin, INPUT_PULLUP); //ocxo setup
pinMode(Control_Pin, INPUT_PULLDOWN); //seconds pin, changed to down as signal was not reliable
attachInterrupt(digitalPinToInterrupt(Main_Pin), HZ, RISING);
attachInterrupt(digitalPinToInterrupt(Control_Pin), Control, RISING);
digitalToggleFast(digitalPinToInterrupt(Main_Pin));
digitalToggleFast(digitalPinToInterrupt(Control_Pin));
TicsPerSecond = TicsPerMinute / 60;
TicsPerHalfSecond = TicsPerMinute / 120;
NVIC_SET_PRIORITY(IRQ_GPIO6789, 9);
if (!sensor.begin()) {
Serial.println("Error reading VEML7700");
}
}
void HZ() {
HZCount = HZCount + 1;
}
void Control() {
//is triggered 2 times a second
//PPS signal may be not updated, i.e. value of J may not be set to value of j, bacuse it only happens in the first half seconds
//and if GPS PPS signal is not synced it only sends signal once a second, which could easily fall in the second half of a second
if ((oSeconds == 0) and (HZCount < (TicsPerHalfSecond))) { // this section triggered only once a minute for first tic
HZCopy = HZTotal;
HZTotal = HZCount;
i++; // this variable is not get resetteded, however since it is long it will take forever to get it to overflow
// i - is the count of uninterrupted minutes when we receive a pps signal on a first half of a zero second
J = j; // we need to copy it here, since j updating is way too fast for the program to catch up reliably
j = 0; // J is the count of PPS per minute, j is a variable that makes that count
}
j++;
}
void loop() {
String Line5;
//long xSeconds;
Buttons();
//ocxo processing
OCXO_time();
//gps module processing
while (ss.available() > 0) {
if (gps.encode(ss.read())) {
if (gps_start == 1) {
if (Satellites != sats.value()) {
Line5 = "GPS signal detected, connecting to settelites, current number: " + String(sats.value());
Serial.println(Line5);
char temp[16];
sprintf(temp, "%s", sats.value());
DisplaySerial.print(F("t4.txt=\"GPS signal detected, sats: "));
DisplaySerial.print(temp);
DisplaySerial.print(F("\""));
DisplaySerial.print(F("\xFF\xFF\xFF"));
}
}
if (gps.time.second() != startSeconds) { // execute update time every second, when startSeconds change
if ((gps_start == 1) and (atoi(sats.value()) > 6)) { //==3 satellites is not enought for accurate timing, changed to 5 or more
//Serial.println("xdx");
gps_start = 0;
allign = 1;
}
GPS_time();
startSeconds = Seconds;
}
}
}
}
void OCXO_time() {
String Line6;
if (HZCount > TicsPerMinute) {
HZCount = 0; //we can not hold tics for more than 1 minuter
//workout minutes first
oMinutes++;
if (min_to_ignore > 0) {
min_to_ignore--;
//i_check ++; //bring up to speed value during warm up time
}
if (oMinutes > 59) {
oMinutes = 0;
oHours++;
if (oHours > 23) {
oHours = oHours - 24;
oDays++;
TicsPerDay = 0;
}
}
currMinutes++;
if (currMinutes > 59) {
currMinutes = 0;
currHours++;
// Serial.println("befor time zone check");
if (o_Time_Zone != Time_Zone) { //adjust summer and winter time
currHours = currHours - o_Time_Zone + Time_Zone;
o_Time_Zone = Time_Zone;
// Serial.println("see if check worked out");
}
//Serial.println(oHours);
if (currHours > 23) currHours = 0;
mario_x = -33;
mario_i = 0;
}
//OCXO_Total_Time_Output();
}
//work on seconds
oSeconds = HZCount / TicsPerSecond;
if ((oSeconds != oTotalSeconds2) and (oSeconds < 60)) { //for very short time it could be equal to 60 but we ignore it
oTotalSeconds2 = oSeconds;
oTotalSeconds3 = HZTotal - HZCopy;
if ((oTotalSeconds3 < 800) and (oTotalSeconds3 > -800) and (min_to_ignore == 1) and (oTotalSeconds2 == 1)) { //macro adjustment at the start
TicsPerMinute = TicsPerMinute + oTotalSeconds3;
TicsPerSecond = TicsPerMinute / 60;
TicsPerHalfSecond = TicsPerMinute / 120;
Line6 = "Delta tics added to adjust standard frq: " + String(oTotalSeconds3) + " hzcount: " + String(HZTotal) + " hzcopy: " + String(HZCopy);
Serial.println(Line6);
oMinutes = -1;
oDays = 0;
oHours = 0;
//HZStart = HZTotal; not used it seems
if ((pps_start == 1) and (oTotalSeconds3 != 0)) pps_start = 0; //this is needed when pps signal is there from the start
//delta to do
// Serial.println(oTotalSeconds2);
}
if ((pps_start == 1) and (i > 0) and (J > 118) and (J < 122)) { //if accuracy of pps from GPS is not there, thus additional 2 minutes of allignemnt is added by setting allign value to 1
Serial.println("PPS signal detected with 120bpm, OCXO fine tuning will start from the next minute");
allign = 1;
pps_start = 0;
}
/*
if ((min_to_ignore == 0) and (oTotalSeconds2 == 1) and (i > 1)) {
//logic to ignore deviations (HZTotal - HZCopy) if there is no pps, when operation is stable
//Serial.print(i);
//Serial.println("-if");
if ((J > 118) and (J < 122)) {
//pps signal is locked
//pps_start=0;
//Serial.println("PPS is live"); //currently i decided not to use it and stuck with signal once a sec
} */
if (((i - i_check) >= 1) and (oTotalSeconds2 == 1) and (oTotalSeconds3 < 200) and (oTotalSeconds3 > -200) and (min_to_ignore == 0)) { //OLD : i changed it to when i is only changing, pps_live simply means Control procedure is working once a minute
//new: once a minute (oTotalSeconds2 on a first sec) check if count has changed - if yes, we have a PPS signal, if no, we have not received a PPS signal this minute
//this is just for reporting purposes to know if gps is live or not
i_check = i;
//Serial.println("we get signal once a sec");
pps_live = 1;
} else if (((i - i_check) < 1) and (oTotalSeconds2 == 1)) {
//Serial.print("we DO NOT get signal once a sec");
//Serial.print(i); Serial.print(":");
//Serial.println(i_check);
pps_live = 0; // see if above, only gets updated when i>1 and min_to_ignore=0
HZCopy = HZTotal; //no signal, thus we need to reset deviations and store old value of deviation
oTotalSeconds3 = 0; //reset current min delta
i = 0; //start count of minutes from the start, i - is the count of uninterrupted minutes when we receive a pps signal on a first half of a zero second
i_check = 0; //reset this so that next minute we can check the result again
J = 0; //reset pps, not necessary, but helps getting cleaner data
}
//}
if ((oTotalSeconds3 < 800) and (oTotalSeconds3 > -800) and (min_to_ignore == 0) and (oTotalSeconds2 == 1)) {
//the reason here to exclude deviation of over 800 is because they are typically happen not because of the shift in timing of the crystal, but rather because gps PPS signal somehow shifts (for example when TX pin is taken out occasionaly it could result in PPS signal shift in a few thousands )
TicsPerDay = TicsPerDay + HZTotal - HZCopy;
TicsPerYear = TicsPerYear + HZTotal - HZCopy;
// Serial.println(oTotalSeconds2);
}
//edge cases when tics move out of current range to the right (i assume max deviation of 300 tics per minute here)
else if ((oTotalSeconds3 < (-TicsPerHalfSecond + 300)) and (oTotalSeconds3 >= (-TicsPerHalfSecond)) and (HZTotal < 300) and (min_to_ignore == 0) and (oTotalSeconds2 == 1)) { //ingnore deviations of over 800 as unrealistic
//here internal watch moves faster, i.e. for each second tic it takes more tics than in TicsPerHalfSecond
TicsPerDay = TicsPerDay + TicsPerHalfSecond + HZTotal - HZCopy;
TicsPerYear = TicsPerYear + TicsPerHalfSecond + HZTotal - HZCopy;
oTotalSeconds3 = TicsPerHalfSecond + oTotalSeconds3;
Serial.println("Lucky you, seconds shifted Right");
} else if ((oTotalSeconds3 > (TicsPerHalfSecond - 300)) and (oTotalSeconds3 <= TicsPerHalfSecond) and (HZCopy < 300) and (min_to_ignore == 0) and (oTotalSeconds2 == 1)) { //ingnore deviations of over 800 as unrealistic
TicsPerDay = TicsPerDay + HZTotal - HZCopy - TicsPerHalfSecond;
TicsPerYear = TicsPerYear + HZTotal - HZCopy - TicsPerHalfSecond;
oTotalSeconds3 = oTotalSeconds3 - TicsPerHalfSecond;
Serial.println("Lucky you, seconds shifted Left"); //internal watch moves slower
} else if ((min_to_ignore == 0) and (oTotalSeconds2 == 1) and (pps_i != i)) { //it looks like the shift happends whem pps_live == 0
//we are outseide of deviation range, which is mosty due to shift in PPS signal;
//pps_i is needed to ignore situation when Control procedure for Seconds and HZCount is not fullfiled, thus HZTotal and HZCopy not being actualized
pps_shift = pps_shift + HZTotal - HZCopy;
pps_error++;
pps_i = i;
}
if ((oTotalSeconds2 == 1) and (allign2 == 1)) {
if ((pps_live == 0) or (min_to_ignore > 0) or (oTotalSeconds3 > 200) or (oTotalSeconds3 < -200)) {
//restart delta count if pps signal interrupted, or we have not alligned the clockes or drift in the clock is outside 200 tics
allign2_count = 0;
allign2_delta = 0;
} else {
allign2_count++;
allign2_delta += oTotalSeconds3;
if (allign2_count == 80) {
allign2 = 0;
allign2_count = 0;
TicsPerMinute += allign2_delta / 80;
Line6 = "Delta tics added to adjust standard frq: " + String(allign2_delta / 80);
Serial.println(Line6);
}
}
}
if (gps_start == 0) {
if (oTotalSeconds2 == 1) {
OCXO_Serial_Output(); //WORKING
DisplayPPS();
}
mario_i++;
if ((oTotalSeconds2 == 2)) {
DisplayDelta();
DisplayLifeDelta();
//DisplayBrightness();
}
if ((oTotalSeconds2 == 3)) {
DisplayLifeTime();
DisplayGraph(oTotalSeconds3);
}
DisplayTime();
DisplayMario();
}
}
}
void OCXO_Serial_Output() {
String Line3;
char logdata[500];
forecasted_dev_in_sec = TicsPerYear * ((365 * 24 * 60) / (oDays * 24 * 60 + oHours * 60 + oMinutes));
forecasted_dev_in_sec = forecasted_dev_in_sec / 5000000;
Line3 = "PPS_live " + String(pps_live) + " OCXO time HH:MM:SS " + String(currHours) + ":" + String(currMinutes) + ":" + String(oSeconds)
+ " pps_e:pps_s:i " + String(pps_error) + ":" + String(pps_shift) + ":" + String(i) + " min_to_ignore:a2_cnt " + String(min_to_ignore) + ":" + String(allign2_count) + " PPS: " + String(J)
+ " last:curr min tics: " + String(HZCopy) + ":" + String(HZTotal) + " delta per min: " + String(oTotalSeconds3) + " delta per day:year "
+ String(TicsPerDay) + ":" + String(TicsPerYear) + " life time DD:HH:MM " + String(oDays) + ":" + String(oHours) + ":" + String(oMinutes) + " annual accuracy in Sec:" + String(forecasted_dev_in_sec, 4);
if (pps_live == 0) Line3 = Line3 + " approximate!";
}
void OCXO_Total_Time_Output() {
//debuggin print out
String Line4;
//Line4 = "OCXO Days in operation "+ String(oDays) + " online time " + String(oHours) + ":"+ String(oMinutes) + ":"+ String(oSeconds)+ " deviation per minute: "+ String(HZCopy)+ " per day: "+ String(HZTotal);
Line4 = " HZ:" + String(HZCount) + " i:" + String(i) + " a:" + String(allign) + " copy: " + String(HZCopy) + " total: " + String(HZTotal);
Serial.println(Line4);
}
void GPS_Serial_Output() {
String Line1, Line_Bckp_Ovf; //line 1 standard length with sats 69 and line 2 is 59 with 1 years of data
Line1 = "GPS sats: " + String(sats.value());
Line1 = Line1 + " Location: ";
if (gps.location.isValid()) {
Line1 = Line1 + String(gps.location.lat(), 6) + "," + String(gps.location.lng(), 6); //sizeof(gps.location.lat()) somehow return 4
} else {
Line1 = Line1 + "INVALID";
}
Line1 = Line1 + " Date/Time: ";
if (gps.date.isValid()) {
Line1 = Line1 + String(gps.date.day()) + ":" + String(gps.date.month()) + ":" + String(gps.date.year());
} else {
Line1 = Line1 + "INVALID";
}
Line1 = Line1 + "/";
if (gps.time.isValid()) {
if ((gps.time.hour() + Time_Zone) >= 24) {
Line1 = Line1 + "0";
Line1 = Line1 + String(gps.time.hour() + Time_Zone - 24) + ":";
} else {
if ((gps.time.hour() + Time_Zone) < 10) Line1 = Line1 + "0";
Line1 = Line1 + String(gps.time.hour() + Time_Zone) + ":";
}
if (gps.time.minute() < 10) Line1 = Line1 + "0";
Line1 = Line1 + String(gps.time.minute()) + ":";
if (gps.time.second() < 10) Line1 = Line1 + "0";
Line1 = Line1 + String(gps.time.second());
} else {
Line1 = Line1 + "INVALID";
}
Serial.println(Line1);
}
void GPS_Total_Time_Output() {
String Line2, Line_Bckp_Ovf; //line 1 standard length with sats 69 and line 2 is 59 with 1 years of data
unsigned long lDays = TotalSeconds / 60 / 60 / 24;
unsigned long lHours = (TotalSeconds - (lDays * 60 * 60 * 24)) / 60 / 60;
unsigned long lMinutes = (TotalSeconds - (lDays * 60 * 60 * 24) - (lHours * 60 * 60)) / 60;
unsigned long lSeconds = TotalSeconds - lDays * 60 * 60 * 24 - lHours * 60 * 60 - lMinutes * 60;
Line2 = "GPS uninterrupted work: " + String(lDays) + " Days " + String(lHours) + " Hours " + String(lMinutes) + " Minutes " + String(lSeconds) + " Seconds";
Serial.println(Line2);
}
void GPS_time() {
String Line1, Line2, Line_Bckp_Ovf; //line 1 standard length with sats 69 and line 2 is 59 with 1 years of data
//xminutes is used to display time additional time extra for when display is refreshed, in this case it will be equal to time
if ((Hours != gps.time.hour()) or (Minutes != gps.time.minute())) { //or (xMinutes == gps.time.minute())) {
Hours = gps.time.hour();
DST();
Hour = gps.time.hour() + Time_Zone; //hour is in local time zone
if (Hour >= 24) Hour = Hour - 24;
Minutes = gps.time.minute();
//GPS_Total_Time_Output(); //WORKING
//xMinutes = 99;
}
if (Seconds != gps.time.second()) {
TotalSeconds++;
Seconds = gps.time.second();
if (allign == 1) {
HZCount = TicsPerSecond * Seconds + TicsPerSecond / 4; //i added small delta for allignment, because the update time on display is a bit lagging, or programming logic is lagging
currMinutes = Minutes;
DST();
allign2 = 1;
allign2_count = 0;
allign2_delta = 0;
o_Time_Zone = Time_Zone;
currHours = Hours + o_Time_Zone; //we have to do it here, because we do not know what will trigger first GPS or OCXO
if (currHours > 23) currHours -= 24;
mario_x = (((480 + 33) * currMinutes) / 60) - 33;
mario_i = 1;
allign = 0;
min_to_ignore = 3;
TicsPerDay = 0; //this is needed because 1. seconds synch moment is shifting and thus old timing valus become irrelevant 2. because new time and new seconds sync is made new start of accuracy is needed
TicsPerYear = 0;
pps_error = 0;
pps_shift = 0;
i = 0;
j = 0;
J = 0;
//soring last date of allignment - not really needed
EEPROM.write(0, highByte(gps.date.year()));
EEPROM.write(1, lowByte(gps.date.year()));
EEPROM.write(2, highByte(gps.date.month()));
EEPROM.write(3, lowByte(gps.date.month()));
EEPROM.write(4, highByte(gps.date.day()));
EEPROM.write(5, lowByte(gps.date.day()));
}
}
}
void DST() {
int dayOfMonth = gps.date.day();
int Month = gps.date.month();
int maxWeekDay;
int y = gps.date.year() - 2000; // Get year from RTC and subtract 2000
int x = (y + y / 4 + 2) % 7; // in reality formula should be be y + y/4 + 3 + 6 (where 3 is the month (same number for march and november) and 6 is for century, but because 9 %7 = 2%7 we have here 2
if ((35 - x) > 31) {
maxWeekDay = 28;
} else {
maxWeekDay = 35;
}
if ((Month == 3) && ((dayOfMonth == (maxWeekDay - x)) && (Hours >= 2))) { Time_Zone = 2; } //31
if ((Month == 3) && (dayOfMonth > (maxWeekDay - x))) { Time_Zone = 2; }
if ((Month == 3) && (dayOfMonth < (maxWeekDay - x))) { Time_Zone = 1; }
//Last Sunday of Nov @ 2:00 AM
if ((Month == 10) && (dayOfMonth == (31 - x)) && Hours >= 2) { Time_Zone = 1; } //27
if ((Month == 10) && (dayOfMonth > (31 - x))) { Time_Zone = 1; }
if ((Month == 10) && (dayOfMonth < (31 - x))) { Time_Zone = 2; }
if ((Month == 11) || (Month == 12) || (Month == 1) || (Month == 2)) { Time_Zone = 1; }
if ((Month == 4) || (Month == 5) || (Month == 6) || (Month == 7) || (Month == 8) || (Month == 9)) { Time_Zone = 2; }
//Serial.println(x);
}
void Buttons() {
// read the state of the pushbutton value:
// buttons in the order on the board
buttonState3 = digitalRead(buttonPin3); //Brightness
buttonState4 = digitalRead(buttonPin4); //Fine tune - 1 hour allignment delta calc
buttonState1 = digitalRead(buttonPin1); //Allign time from start
buttonState2 = digitalRead(buttonPin2); //Reset Current Count values
if (buttonState3 != Prev_buttonState3) {
if (buttonState3 == HIGH) {
digitalWrite(ledPin, LOW);
} else {
digitalWrite(ledPin, HIGH);
//reset_OCXO();
b += 30;
if (b > 100) b = 10;
DisplayBrightness();
}
delay(50);
}
if (buttonState4 != Prev_buttonState4) {
if (buttonState4 == HIGH) {
digitalWrite(ledPin, LOW);
Pushed_button4 = 0;
} else {
digitalWrite(ledPin, HIGH);
sec_buttonState4 = oSeconds; //saving current seconds - logic with the hold function for 2 seconds
Pushed_button4 = 1;
}
delay(50);
}
if ((Pushed_button4 == 1) and (abs(sec_buttonState4 - oSeconds) > 1)) { //and (buttonState1 == LOW)
digitalWrite(ledPin, LOW);
allign2 = 1;
allign2_count = 0;
allign2_delta = 0;
Pushed_button4 = 0;
}
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
if (buttonState1 != Prev_buttonState1) {
if (buttonState1 == HIGH) {
digitalWrite(ledPin, LOW);
Pushed_button1 = 0;
} else {
digitalWrite(ledPin, HIGH);
sec_buttonState1 = oSeconds; //saving current seconds - logic with the hold function for 2 seconds
Pushed_button1 = 1;
}
delay(50);
}
if ((Pushed_button1 == 1) and (abs(sec_buttonState1 - oSeconds) > 1)) { //and (buttonState1 == LOW)
digitalWrite(ledPin, LOW);
Serial.println("button1 pressed");
allign = 1;
min_to_ignore = 2;
Pushed_button1 = 0;
}
if (buttonState2 != Prev_buttonState2) {
if (buttonState2 == HIGH) {
digitalWrite(ledPin, LOW);
Pushed_button2 = 0;
} else {
digitalWrite(ledPin, HIGH);
sec_buttonState2 = oSeconds; //saving current seconds - logic with the hold function for 2 seconds
Pushed_button2 = 1;
}
delay(50);
}
if ((Pushed_button2 == 1) and (abs(sec_buttonState2 - oSeconds) > 1)) { //and (buttonState1 == LOW)
digitalWrite(ledPin, LOW);
TicsPerDay = 0; //this is needed because 1. seconds synch moment is shifting and thus old timing valus become irrelevant 2. because new time and new seconds sync is made new start of accuracy is needed
TicsPerYear = 0;
Pushed_button2 = 0;
}
Prev_buttonState1 = buttonState1;
Prev_buttonState2 = buttonState2;
Prev_buttonState3 = buttonState3;
Prev_buttonState4 = buttonState4;
}
void DisplayTime() {
char temp[9];
//char temp22[30];
sprintf(temp, "%02ld:%02ld:%02ld", currHours, currMinutes, oSeconds);
DisplaySerial.print(("t0.txt=\""));
DisplaySerial.print(temp);
DisplaySerial.print(("\""));
DisplaySerial.print(("\xFF\xFF\xFF"));
}
void DisplayDelta() {
char temp1[10];
char temp2[10];
dtostrf(forecasted_dev_in_sec, 9, 6, temp1);
sprintf(temp2, "%s", temp1);
DisplaySerial.print(F("t1.txt=\""));
DisplaySerial.print(temp2);
DisplaySerial.print(F("\""));
DisplaySerial.print(F("\xFF\xFF\xFF"));
}
void DisplayLifeTime() {
char temp[9];
sprintf(temp, "%02ld:%02ld:%02ld", oDays, oHours, oMinutes);
DisplaySerial.print(F("t3.txt=\"life "));
DisplaySerial.print(F("time DD:HH:MM "));
DisplaySerial.print(temp);
DisplaySerial.print(F("\""));
DisplaySerial.print(F("\xFF\xFF\xFF"));
}
void DisplayLifeDelta() {
char temp[9];
sprintf(temp, "%02ld:%02ld:%02ld", oTotalSeconds3, TicsPerDay, TicsPerYear);
DisplaySerial.print(F("t4.txt=\"delta "));
DisplaySerial.print(F("per min:day:year "));
DisplaySerial.print(temp);
DisplaySerial.print(F("\""));
DisplaySerial.print(F("\xFF\xFF\xFF"));
}
void DisplayPPS() {
if (pps_live == 1) {
DisplaySerial.print(F("r0.bco"));
DisplaySerial.print(F("=1024"));
DisplaySerial.print(F("\xFF\xFF\xFF"));
} else {
DisplaySerial.print(F("r0.bco"));
DisplaySerial.print(F("=53248"));
DisplaySerial.print(F("\xFF\xFF\xFF"));
}
}
void DisplayMario() {
char temp[12];
if (mario_i % 7 == 0) {
mario_x++;
sprintf(temp, "%d", mario_x);
DisplaySerial.print(F("p2.x="));
DisplaySerial.print(temp);
DisplaySerial.print(F("\xFF\xFF\xFF"));
uint16_t lux = sensor.readLux();
if (lux < 5) b0 = 10;
if ((lux >= 5) and (lux < 20)) b0 = 15;
if ((lux >= 20) and (lux < 50)) b0 = 25;
if ((lux >= 50) and (lux < 150)) b0 = 33;
if ((lux >= 150) and (lux < 300)) b0 = 40;
if ((lux >= 300) and (lux < 800)) b0 = 70;
if (lux >= 800) b0 = 100;
if (b0 != b) {
b = b0;
DisplayBrightness();
}
//Serial.println(b);
//Serial.println(lux);
//if (mario_x > 480) mario_x = -33;
}
}
void DisplayGraph(long delta_per_min) {
char temp[10];
int graph_max = 50; //value on the monitor maximum (ie ssize of sqare)
int graph_min = 0;
int value_max = 10; //max value to fit inside the square so it does not go out
// here actually value is 9,5 which 5K ticks (tics per 1 sec) that we want to achive in 1 min / (365 * 24 * 60)
long converted_value;
converted_value = delta_per_min * (graph_max - graph_min) / (value_max * 2) + ((graph_max - graph_min) / 2);
sprintf(temp, "%ld", converted_value);
DisplaySerial.print("va0.val=");
DisplaySerial.print(temp);
DisplaySerial.print(F("\xFF\xFF\xFF"));
if (pps_live == 1) { //if pps is not live do not update
DisplaySerial.print("add 6,0,va0.val");
DisplaySerial.print(F("\xFF\xFF\xFF"));
}
}
void DisplayBrightness() {
char temp[12];
sprintf(temp, "%d", b);
DisplaySerial.print(F("dim="));
DisplaySerial.print(temp);
DisplaySerial.print(F("\xFF\xFF\xFF"));
}