Library to decode MSF time signal.
Revision 0:340305453f64, committed 2022-01-07
- Comitter:
- dswood
- Date:
- Fri Jan 07 12:12:25 2022 +0000
- Commit message:
- A simple library to decode MSF time signal. Probably useful for DSF
Changed in this revision
MSF_Time.cpp | Show annotated file Show diff for this revision Revisions of this file |
MSF_Time.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r 000000000000 -r 340305453f64 MSF_Time.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MSF_Time.cpp Fri Jan 07 12:12:25 2022 +0000 @@ -0,0 +1,746 @@ +/*This library will decode an MSF signal on a digital input pin and turn it +into a timestamp. +Copyright (C) 2017 Duncan Wood + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + + + + + +#ifndef MSF_Time_h +#define MSF_Time_h + +#include "mbed.h" +#include "MSF_Time.h" + +MSF_Time::MSF_Time(PinName InputPin, int polarity, int OffsetTuning) + : Time_Data(InputPin), Polarity(polarity), OffsetTuning(OffsetTuning), + MyInput(InputPin) +{ + DataValid=false; + Time_Data_Count=0; + Time_Data_Duration=0x0000; + Time_Data.fall(this, &MSF_Time::Falling); + Time_Data.rise(this, &MSF_Time::Rising); + Received_timestamp=0; //set time to zero until we can set it properly + MyData.BCDMonth=0; + MyData.BCDTime=0; + MyData.BCDYear=0; + MyData.SyncByte=0; + MyData.DayOfWeek=0; + MyData.BST=0; + MyData.DUT=0; + +} + +void MSF_Time::Rising() +{ + if (Polarity==0) { + LogicOne(); + } else { + LogicZero(); + } + + +} +void MSF_Time::LogicOne() //When there is no carrier (pulse every second) +{ + Time_Data_timer.reset(); + Time_Data_timer.start(); +} +void MSF_Time::LogicZero() // When carrier is present (most of the time) +{ + Time_Data_timer.stop(); + Time_Data_Duration=Time_Data_timer.read_us(); + // Test for the 500ms minute sync pulse + if (Time_Data_Duration > 450000 && Time_Data_Duration < 550000 ) { // +/-50ms for now + Received_Time.tm_sec=0; //set time to zero until we can set it properly + Time_Data_Count=0; + MyData.BCDMonth=0; + MyData.BCDTime=0; + MyData.BCDYear=0; + MyData.SyncByte=0; + MyData.DayOfWeek=0; + Time_Data_Sync=true; + Time_Data_Ticker.attach(this, &MSF_Time::Time_Data_Strobe,0.05); // start a timer to read data + } +} +void MSF_Time::Falling() +{ + if (Polarity==0) { + LogicZero(); + } else { + LogicOne(); + } + +} + +void MSF_Time::IncrementSeconds() +{ + // called 50ms ish before the second. Add delay of 50ms ish. + offset.attach_us(this, &MSF_Time::IncrementSecondsNow,OffsetTuning); +} +void MSF_Time::IncrementSecondsNow() +{ + Received_timestamp++; + if (DV) { //this is the signal to set time now at 00 seconds + DV=false; + Received_Time.tm_sec=0; + Received_timestamp=mktime(&Received_Time); + if (Received_timestamp != -1 ) {//0x80000001 + DataValid=true; + } + } +} + + +void MSF_Time::Time_Data_Strobe() +{ + Time_Data_Count++; + switch(Time_Data_Count) { + case 1: + break; + case 9: //zero seconds + IncrementSeconds(); + break; + //case 13://01A + //case 15://01B DUT1+ + //break; + case 29:// Incerment seconds + IncrementSeconds(); + break; + //case 33://02A + //case 35://02B DUT1+ + //break; + case 49: + IncrementSeconds(); + break; + //case 53://03A + //case 55://03B DUT1+ + //break; + case 69: + IncrementSeconds(); + break; + //case 73://04A + //case 75://04B DUT1+ + case 89: + IncrementSeconds(); + break; + //case 93://05A + //case 95://05B DUT1+ + case 109: + IncrementSeconds(); + break; + //case 113://06A + //case 115://06B DUT1+ + case 129: + IncrementSeconds(); + break; + //case 133://07A + //case 135://07B DUT1+ + case 149: + IncrementSeconds(); + break; + //case 153://08A + //case 155://08B DUT1+ + case 169: + IncrementSeconds(); + break; + //case 173://09A + //case 175://09B DUT1- + case 189: + IncrementSeconds(); + break; + //case 193://10A + //case 195://10B DUT1- + case 209: + IncrementSeconds(); + break; + //case 213://11A + //case 215://11B DUT1- + case 229: + IncrementSeconds(); + break; + //case 233://12A + //case 235://12B DUT1- + case 249: + IncrementSeconds(); + break; + //case 253://13A + //case 255://13B DUT1- + case 269: + IncrementSeconds(); + break; + //case 273://14A + //case 275://14B DUT1- + case 289: + IncrementSeconds(); + break; + //case 293://15A + //case 295://15B DUT1- + case 309: + IncrementSeconds(); + break; + case 313://16A + MyData.BCDYear+= MyInput.read()^Polarity; + //leap second + break; + //case 315://16B DUT1- + case 329: + IncrementSeconds(); + break; + case 333://17A Year 80 + MyData.BCDYear=MyData.BCDYear << 1; + MyData.BCDYear+= MyInput.read()^Polarity; + + break; + //case 335://17B + case 349: + IncrementSeconds(); + break; + case 353://18A Year 40 + MyData.BCDYear=MyData.BCDYear << 1; + MyData.BCDYear+= MyInput.read()^Polarity; + break; + //case 355://18B + case 369: + IncrementSeconds(); + break; + case 373://19A Year 20 + MyData.BCDYear=MyData.BCDYear << 1; + MyData.BCDYear+= MyInput.read()^Polarity; + break; + //case 375://19B + case 389: + IncrementSeconds(); + break; + case 393://20A Year 10 + MyData.BCDYear=MyData.BCDYear << 1; + MyData.BCDYear+= MyInput.read()^Polarity; + break; + //case 395://20B + case 409: + IncrementSeconds(); + break; + case 413://21A Year 8 + MyData.BCDYear=MyData.BCDYear << 1; + MyData.BCDYear+= MyInput.read()^Polarity; + break; + //case 415://21B + case 429: + IncrementSeconds(); + break; + case 433://22A Year 4 + MyData.BCDYear=MyData.BCDYear << 1; + MyData.BCDYear+= MyInput.read()^Polarity; + break; + //case 435://22B + case 449: + IncrementSeconds(); + break; + case 453://23A Year 2 + MyData.BCDYear=MyData.BCDYear << 1; + MyData.BCDYear+= MyInput.read()^Polarity; + break; + //case 455://23B + case 469: + IncrementSeconds(); + break; + case 473://24A Year 1 + MyData.BCDYear=MyData.BCDYear << 1; + MyData.BCDYear+= MyInput.read()^Polarity; + MyData.BCDMonth+= MyInput.read()^Polarity;; //leap second minus + + break; + //case 475://24B + + case 489: + IncrementSeconds(); + break; + case 493://25A Month 10 + MyData.BCDMonth=MyData.BCDMonth << 1; + MyData.BCDMonth+= MyInput.read()^Polarity; + + MyData.BCDYear=MyData.BCDYear << 1; + MyData.BCDYear+= MyInput.read()^Polarity; //leap second + break; + + //case 495://25B + + case 509: + IncrementSeconds(); + break; + case 513://26A Month 8 + MyData.BCDMonth=MyData.BCDMonth << 1; + MyData.BCDMonth+= MyInput.read()^Polarity; + break; + //case 515://26B + case 529: + IncrementSeconds(); + break; + case 533://27A Month 4 + MyData.BCDMonth=MyData.BCDMonth << 1; + MyData.BCDMonth+= MyInput.read()^Polarity; + break; + //case 535://27B + case 549: + IncrementSeconds(); + break; + case 553://28A Month 2 + MyData.BCDMonth=MyData.BCDMonth << 1; + MyData.BCDMonth+= MyInput.read()^Polarity; + break; + //case 555://28B + case 569: + IncrementSeconds(); + break; + case 573://29A Month 1 + MyData.BCDMonth=MyData.BCDMonth << 1; + MyData.BCDMonth+= MyInput.read()^Polarity; + break; + //case 575://29B + case 589: + IncrementSeconds(); + break; + case 593://30A Day of Month 20 + MyData.BCDMonth=MyData.BCDMonth << 1; + MyData.BCDMonth+= MyInput.read()^Polarity; + break; + //case 595://30B + case 609: + IncrementSeconds(); + break; + case 613://31A Day of Month 10 + MyData.BCDMonth=MyData.BCDMonth << 1; + MyData.BCDMonth+= MyInput.read()^Polarity; + break; + //case 615://31B + case 629: + IncrementSeconds(); + break; + case 633://32A Day of Month 8 + MyData.BCDMonth=MyData.BCDMonth << 1; + MyData.BCDMonth+= MyInput.read()^Polarity; + break; + //case 635://32B + case 649: + IncrementSeconds(); + break; + case 653://33A Day of Month 4 + MyData.BCDMonth=MyData.BCDMonth << 1; + MyData.BCDMonth+= MyInput.read()^Polarity; + break; + //case 655://33B + case 669: + IncrementSeconds(); + break; + case 673://34A Day of Month 2 + MyData.BCDMonth=MyData.BCDMonth << 1; + MyData.BCDMonth+= MyInput.read()^Polarity; + break; + //case 675://34B + case 689: + IncrementSeconds(); + break; + case 693://35A Day of Month 1 + MyData.BCDMonth=MyData.BCDMonth << 1; + MyData.BCDMonth+= MyInput.read()^Polarity; + MyData.DayOfWeek+= MyInput.read()^Polarity; + + break; + //case 695://35B + + case 709: + IncrementSeconds(); + break; + case 713://36A Day of Week 4 + MyData.DayOfWeek=MyData.DayOfWeek <<1; + MyData.DayOfWeek+= MyInput.read()^Polarity; + + MyData.BCDMonth=MyData.BCDMonth << 1; + MyData.BCDMonth+= MyInput.read()^Polarity; + break; + // case 715://36B + + case 729: + IncrementSeconds(); + break; + case 733://37A Day of Week 2 + MyData.DayOfWeek=MyData.DayOfWeek <<1; + MyData.DayOfWeek+= MyInput.read()^Polarity; + break; + //case 735://37B + case 749: + IncrementSeconds(); + break; + case 753://38A Day of Week 1 + MyData.DayOfWeek=MyData.DayOfWeek <<1; + MyData.DayOfWeek+= MyInput.read()^Polarity; + MyData.BCDTime+= MyInput.read()^Polarity; //leap second + + break; + //case 755://38B + + case 769: + IncrementSeconds(); + break; + case 773://39A Hour 20 + MyData.BCDTime=MyData.BCDTime << 1; + MyData.BCDTime+= MyInput.read()^Polarity; + + MyData.DayOfWeek=MyData.DayOfWeek <<1; + MyData.DayOfWeek+= MyInput.read()^Polarity; //leap second + break; + + //case 775://39B + + case 789: + IncrementSeconds(); + break; + case 793://40A Hour 10 + MyData.BCDTime=MyData.BCDTime << 1; + MyData.BCDTime+= MyInput.read()^Polarity; + break; + //case 795://40B + case 809: + IncrementSeconds(); + break; + case 813://41A Hour 8 + MyData.BCDTime=MyData.BCDTime << 1; + MyData.BCDTime+= MyInput.read()^Polarity; + break; + //case 815://41B + case 829: + IncrementSeconds(); + break; + case 833://42A Hour 4 + MyData.BCDTime=MyData.BCDTime << 1; + MyData.BCDTime+= MyInput.read()^Polarity; + break; + //case 835://42B + case 849: + IncrementSeconds(); + break; + case 853://43A Hour 2 + MyData.BCDTime=MyData.BCDTime << 1; + MyData.BCDTime+= MyInput.read()^Polarity; + break; + //case 855://43B + case 869: + IncrementSeconds(); + break; + case 873://44A Hour 1 + MyData.BCDTime=MyData.BCDTime << 1; + MyData.BCDTime+= MyInput.read()^Polarity; + break; + //case 875://44B + case 889: + IncrementSeconds(); + break; + case 893://45A Minute 40 + MyData.BCDTime=MyData.BCDTime << 1; + MyData.BCDTime+= MyInput.read()^Polarity; + break; + //case 895://45B + case 909: + IncrementSeconds(); + break; + case 913://46A Minute 20 + MyData.BCDTime=MyData.BCDTime << 1; + MyData.BCDTime+= MyInput.read()^Polarity; + break; + //case 915://46B + case 929: + IncrementSeconds(); + break; + case 933://47A Minute 10 + MyData.BCDTime=MyData.BCDTime << 1; + MyData.BCDTime+= MyInput.read()^Polarity; + break; + //case 935://47B + case 949: + IncrementSeconds(); + break; + case 953://48A Minute 8 + MyData.BCDTime=MyData.BCDTime << 1; + MyData.BCDTime+= MyInput.read()^Polarity; + break; + //case 955://48B + case 969: + IncrementSeconds(); + break; + case 973://49A Minute 4 + MyData.BCDTime=MyData.BCDTime << 1; + MyData.BCDTime+= MyInput.read()^Polarity; + break; + //case 975://49B + case 989: + IncrementSeconds(); + break; + case 993://50A Minute 2 + MyData.BCDTime=MyData.BCDTime << 1; + MyData.BCDTime+= MyInput.read()^Polarity; + break; + //case 995://50B + + case 1009: + IncrementSeconds(); + break; + case 1013://51A Minute 1 + MyData.BCDTime=MyData.BCDTime << 1; + MyData.BCDTime+= MyInput.read()^Polarity; + MyData.SyncByte+= MyInput.read()^Polarity; // Or is it a leap second + + break; + //case 1015://51B + + case 1029: + IncrementSeconds(); + break; + case 1033://52A set to 0 + MyData.SyncByte=MyData.SyncByte <<1; + MyData.SyncByte+= MyInput.read()^Polarity; + + MyData.BCDTime=MyData.BCDTime << 1; + MyData.BCDTime+= MyInput.read()^Polarity; //leap second + break; + //case 1035://52B + case 1049: + IncrementSeconds(); + break; + case 1053://53A set to 1 + MyData.SyncByte=MyData.SyncByte <<1; + MyData.SyncByte+= MyInput.read()^Polarity; + + break; + case 1055://53B Change of summertime soon + // Fortunately leap seconds are never added in spring or autumn + MyData.BCDYear=MyData.BCDYear << 1; + MyData.BCDYear+= MyInput.read()^Polarity; + break; + case 1069: + IncrementSeconds(); + break; + + + case 1073://54A set to 1 + MyData.SyncByte=MyData.SyncByte <<1; + MyData.SyncByte+= MyInput.read()^Polarity; + + break; + case 1075://54B Year Parity + MyData.BCDYear=MyData.BCDYear << 1; + MyData.BCDYear+= MyInput.read()^Polarity; + MyData.BCDMonth=MyData.BCDMonth << 1; + MyData.BCDMonth+= MyInput.read()^Polarity; + break; + case 1089: + IncrementSeconds(); + break; + + case 1093://55A set to 1 + MyData.SyncByte=MyData.SyncByte <<1; + MyData.SyncByte+= MyInput.read()^Polarity; + + break; + case 1095://55B Month Parity + MyData.BCDMonth=MyData.BCDMonth << 1; + MyData.BCDMonth+= MyInput.read()^Polarity; + MyData.BCDYear=MyData.BCDYear << 1; + MyData.BCDYear+= MyInput.read()^Polarity; + MyData.DayOfWeek=MyData.DayOfWeek <<1; + MyData.DayOfWeek+= MyInput.read()^Polarity; + break; + case 1109: + IncrementSeconds(); + break; + case 1113://56A set to 1 + MyData.SyncByte=MyData.SyncByte <<1; + MyData.SyncByte+= MyInput.read()^Polarity; + + break; + case 1115://56B day of Week Parity + MyData.DayOfWeek=MyData.DayOfWeek <<1; + MyData.DayOfWeek+= MyInput.read()^Polarity; + MyData.BCDMonth=MyData.BCDMonth << 1; + MyData.BCDMonth+= MyInput.read()^Polarity; + MyData.BCDTime=MyData.BCDTime << 1; + MyData.BCDTime+= MyInput.read()^Polarity; + break; + case 1129: + IncrementSeconds(); + break; + case 1133://57A set to 1 + MyData.SyncByte=MyData.SyncByte <<1; + MyData.SyncByte+= MyInput.read()^Polarity; + + break; + case 1135://57B Time - hour minute parity + MyData.BCDTime=MyData.BCDTime << 1; + MyData.BCDTime+= MyInput.read()^Polarity; + MyData.DayOfWeek=MyData.DayOfWeek <<1; + MyData.DayOfWeek+= MyInput.read()^Polarity; + break; + case 1149: + IncrementSeconds(); + break; + case 1153://58A set to 1 + MyData.SyncByte=MyData.SyncByte <<1; + MyData.SyncByte+= MyInput.read()^Polarity; + + + break; + case 1155://58B British Summertime + MyData.BCDTime=MyData.BCDTime << 1; + MyData.BCDTime+= MyInput.read()^Polarity; + MyData.BST=MyInput.read()^Polarity; + + break; + case 1169: + IncrementSeconds(); + ProcessData();// if success count will be stopped but increment will still happen + break; + case 1173://59A set to 0 + MyData.SyncByte=MyData.SyncByte <<1; + MyData.SyncByte+= MyInput.read()^Polarity; + break; + // case 1175://59B + case 1189: + IncrementSeconds(); + ProcessData(); + break; + case 1193://60A + MyData.SyncByte=MyData.SyncByte <<1; + MyData.SyncByte+= MyInput.read()^Polarity; // + break; + // case 1195://60B + case 1209: + IncrementSeconds(); + ProcessData(); + // End stop + // On a leap second we should count extra but not dealing with it + // so for one minute time will be out by a second. + Time_Data_Ticker.detach(); + Time_Data_Count=0; // Should stop this being called more than once + DataValid=false; //no data received + + } +} + +int MSF_Time::ParityCheck(unsigned int CheckMe) //0=even 1= odd naturally +{ +// My parity is going to check 16 bit feel free to add more +// Stolen shamelessly from internet +//x ^= x >> 16; +//x ^= x >> 8; +//x ^= x >> 4; +//x ^= x >> 2; +//x ^= x >> 1; +//return (~x) & 1; + CheckMe^=CheckMe>>8; + CheckMe^=CheckMe>>4; + CheckMe^=CheckMe>>2; + CheckMe^=CheckMe>>1; + CheckMe&=1;// 1=odd 0=even + + return CheckMe; +} + +void MSF_Time::ProcessData() +{ + DV=false; + int shift=0; // by how much to shift just to leave data + + + // Find sync + // sync data is 01111110 + if ((MyData.SyncByte&0x0FF) == 0x07E) { // sync byte + + /* There are 3 processdata calls. The ticker will be either + 1155 or 1173 or 1193. If it is on time or late, extra data will + have been collected. We shall get rid.*/ + } else { + if (Time_Data_Count==1193) { + //pc.printf("last chance of sync failed - data not valid"); + DataValid=false; + } + return; + } + + if (Time_Data_Count==1169) { //leap second early + shift=2; + + } + if (Time_Data_Count==1189) { + shift=1; + + } + if (Time_Data_Count==1209) { + shift=0; + } + Time_Data_Ticker.detach(); + Time_Data_Count=0; // Should stop this being called more than once + MyData.BCDYear>>=shift; + MyData.BCDMonth>>=shift; + MyData.DayOfWeek>>=shift; + MyData.BCDTime>>=shift; + MyData.BCDYear&=0x7F9 ; //8 bits +2 rubbish + parity + MyData.BCDMonth&=0x3FF9; // 11 bits +2 rubbish + parity + MyData.DayOfWeek&=0x039 ; //3 bits +2 rubbish + parity + MyData.BCDTime&=0xFFF9; // 13bits +2 rubbish + parity + + if (ParityCheck(MyData.BCDYear) && + ParityCheck(MyData.BCDMonth) && + ParityCheck(MyData.DayOfWeek) && + ParityCheck(MyData.BCDTime) ) { + // Parity ok - remove parity bits + MyData.BCDYear>>=3; + MyData.BCDMonth>>=3; + MyData.DayOfWeek>>=3; + MyData.BCDTime>>=3; + DV=true; + } else { + DataValid=false; //sync but parity fail + return; + } + + //Convert BCD to binary + // pc.printf("Year Month DOW Time\n\r"); +//pc.printf("%x %x %x %x\n\r",MyData.BCDYear,MyData.BCDMonth,MyData.DayOfWeek,MyData.BCDTime); + if (DV) { + Received_Time.tm_year=100+(MyData.BCDYear & 0x0F)+(10*((MyData.BCDYear>>4) & 0x01)) ; //years _since_ 1900 + Received_Time.tm_mon=((MyData.BCDMonth>>6) & 0x0F)+(10*((MyData.BCDMonth>>10) & 0x01))-1; + Received_Time.tm_mday=(MyData.BCDMonth & 0x0F)+(10*((MyData.BCDMonth>>4) & 0x03)) ; + Received_Time.tm_hour=((MyData.BCDTime>>7)& 0x0F)+(10*((MyData.BCDTime>>11) & 0x03)); + Received_Time.tm_min=(MyData.BCDTime&0x0F)+(10*((MyData.BCDTime>>4) & 0x07)); + Received_Time.tm_wday = (MyData.DayOfWeek&0x07); + Received_Time.tm_sec=0; + } +} +bool MSF_Time::Valid() +{ + //if (DataValid) pc.printf("Data Valid\n\r"); + + return DataValid; +} +time_t MSF_Time::Read() +{ + // pc.printf("Received ts %s\n\r",ctime(&Received_timestamp)); + return Received_timestamp; +} +#endif +
diff -r 000000000000 -r 340305453f64 MSF_Time.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MSF_Time.h Fri Jan 07 12:12:25 2022 +0000 @@ -0,0 +1,75 @@ +/*This library will decode an MSF signal on a digital input pin and turn it +into a timestamp. +Copyright (C) 2017 Duncan Wood + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + + + +#include "mbed.h" +class MSF_Time +{ +public: +/* Start MSF_Time with this function +InputPin is the data coming from your reciever + Polarity is 0 if your receiver output is high for no carrier + polarity is 1 to invert this logic. */ + + +MSF_Time(PinName InputPin, int polarity,int OffsetTuning =48000); + +bool Valid(); // Is the time valid +time_t Read(); + +protected: +struct MSF_Data { + int BCDYear; + int BCDMonth; + int DayOfWeek; + int BCDTime; + int SyncByte; //This is sent and allows you to detect leap seconds + int DUT; + int BST; +}; + +struct MSF_Data MyData; +struct tm Received_Time; // Normal data coming in +time_t Received_timestamp; //Data converted to timestamp +unsigned int Time_Data_Duration; //Pulse length - The minute marker is 500ms +bool Time_Data_Sync; // True when a 500ms pulse is detected denoting the start of a minute +Ticker Time_Data_Ticker; // A 50ms clock used to clock in data +unsigned int Time_Data_Count;// counts the 50ms for clocking in the data +void Time_Data_Strobe(); // When the ticker ticks do this +void Falling(); +void Rising(); +bool DataValid; +Timeout offset; // used to fine tune the seconds 50ms equals zero offset +InterruptIn Time_Data; +DigitalIn MyInput; +int Polarity; +int OffsetTuning; +Timer Time_Data_timer; +void LogicOne(); +void LogicZero(); +int ParityCheck(unsigned int CheckMe); +void ProcessData(); +void IncrementSeconds(); +void IncrementSecondsNow(); +//int const OffsetTuning=48000; //in microseconds +bool debug; //turn on off debugging noise +bool DV; + +}; \ No newline at end of file