Sommerzeit & mehr

  • 1
  • 2
  • Page 1 of 2
Harry
Moderator
Avatar
Gender:
Location: zwischen Augsburg und Ulm
Age: 59
Posts: 2135
Registered: 03 / 2003
Subject:

Sommerzeit & mehr

 · 
Posted: 02.01.2014 - 19:31  ·  #1
Hi @ all,

anbei ein paar Funktionen die ich geschrieben habe. Evtl. findet sie ja mal jemand nützlich.

Gruss
Harry

Voraussetzung sind folgende Variablen welche von User vorbelegt werden müssen (aus GPS-Daten):
Code

  DayNum            : Integer;                   // Tagesziffer
  MonthNum          : Integer;                   // Monatsziffer
  CentNum           : Integer;                   // Jahrhundertziffer
  YearNum           : Integer;                   // Jahresziffer
  HourNum           : Integer;                   // Stunde
  MinNum            : Integer;                   // Minute

Tagesziffer z.B. 24.03.2014
Monatsziffer z.B. 24.03.2014
Jahrhundertziffer z.B. 24.03.2014
Jahresziffer z.B. 24.03.2014

Funktion zur Ermittlung des Starttages der Sommerzeit (Sonntag im März):
Code

Function StartST:Integer;                      // Start Sommerzeit Tag im März
  Var Dummy : Integer;
  Begin
    Dummy:=31-((((5*YearNum) div 4)+5) Mod 7);
    Return(Dummy);
  End StartST;


Funktion zur Ermittlung des Endtages der Sommerzeit (Sonntag im Oktober):
Code

Function EndST:Integer;                        // End Sommerzeit Tag im Oktober
  Var Dummy : Integer;
  Begin
    Dummy:=31-((((5*YearNum) div 4)+2) Mod 7);
    Return(Dummy);
  End EndST;


Funktion zur Ermittlung der Sommerzeit überhaupt:
Code

Function STime:Boolean;
  Var ST : Boolean;
  Begin
    If (((MonthNum=3) and (DayNum>=StartST) and (HourNum>1)) or
        ((MonthNum=10) and (DayNum<=EndST) and (HourNum<3)) or
         (MonthNum in [4..9]))
      then
        ST:=true;
      else
        ST:=false;
      EndIf;
    Return(ST);
  End STime;


Funktion zur Ermittlung des Wochentages (0 und 7=Sonntag, 1=Montag, 2=Dienstag,.......)
Code

Function CalcDay:Byte; // Berechnung des Wochentages So=0&7; Mo=1, Di=2, Mi=3....
  Var TZ, MZ, JHZ, JZ, SJK, DayResult : Integer;
  Begin
    TZ:=DayNum Mod 7;
    MZ:=MonthConst[MonthNum];
    JHZ:=((3-(CentNum Mod 4))*2)+1;
    JZ:=YearConst[(YearNum Mod 28)];
    If ((MonthNum in [1..2]) and (((YearNum Div 4)*4)=YearNum))
      then
        SJK:=1;
      else
        SJK:=0;
      EndIf;
    DayResult:=((TZ+MZ+JHZ+JZ) Mod 7)-SJK;
    Return(Lo(DayResult));
  End CalcDay;


Funktion zur kompletten Korrektur der Uhrzeit (Datum fehlt noch) anhand Sommer-/Winterzeit und des Längengrades (GPS). Erforderliche zusätzliche Variablen (aus GPS-Daten):
Code

  NMEA : Record
         Message_ID    : String[6];  // RMC protocol header
         Time_UTC      : String[9];  // hhmmss.ss
         Status        : String[1];  // A=data valid or V=data not valid
         Latitude      : String[9];  // ddmm.mmmm
         Lat_Ind       : String[1];  // N=north or S=south
         Longitude     : String[10]; // dddmm.mmmm
         Log_Ind       : String[1];  // E=east or W=west
         Speed         : String[6];  // variable lenght in knots
         Angle         : String[6];  // variable lenght in degrees
         Date          : String[6];  // ddmmyy
         Magnetic      : String[5];  // trash this one ..... not suported on SiRF GPS
         Sat_Track     : String[2];  // Number of sat in view and used in solution
         H_Dilution    : String[6];  // dilution error
         Height        : String[7];  // height over see
         StatusDummy   : String[1];  // für Status im GPGGA-Datensatz
         Height_Unit   : String[1];  // height-unit
         DGPS_time     : String[6];  // trash this one
         DGPS_ID       : String[6];  // trash this one
         Checksum1     : String[2];  // *10
         Checksum2     : String[2];  // *10
         End;

  NG, EG            : String[3];                 // N- & E-Grad
  NM, EM            : String[7];                 // N- & E-Minuten


Code

Procedure GPS_DaT;
  Var Dummy     : Integer;
      EMI       : Integer;
      EMT       : String[2];
  Begin
    Dummy:=HourNum;
    EMT:=Copy(EM,1,2);
    EMI:=(StrToInt(EG)*100)+(StrToInt(EMT));
    If NMEA.Log_Ind='W'
      then
        EMI:=EMI*(-1);
      EndIf;
    Case EMI of
      -18000..-17251:Dummy:=Dummy-12;|
      -17250..-15751:Dummy:=Dummy-11;|
      -15750..-14251:Dummy:=Dummy-10;|
      -14250..-12751:Dummy:=Dummy- 9;|
      -12750..-11251:Dummy:=Dummy- 8;|
      -11250.. -9751:Dummy:=Dummy- 7;|
       -9750.. -8251:Dummy:=Dummy- 6;|
       -8250.. -6751:Dummy:=Dummy- 5;|
       -6750.. -5251:Dummy:=Dummy- 4;|
       -5250.. -3751:Dummy:=Dummy- 3;|
       -3750.. -2251:Dummy:=Dummy- 2;|
       -2250..  -751:Dummy:=Dummy- 1;|
        -750..   750:Dummy:=Dummy+ 0;|
         751..  2250:Dummy:=Dummy+ 1;|
        2251..  3750:Dummy:=Dummy+ 2;|
        3751..  5250:Dummy:=Dummy+ 3;|
        5251..  6750:Dummy:=Dummy+ 4;|
        6751..  8250:Dummy:=Dummy+ 5;|
        8251..  9750:Dummy:=Dummy+ 6;|
        9751.. 11250:Dummy:=Dummy+ 7;|
       11251.. 12750:Dummy:=Dummy+ 8;|
       12751.. 14250:Dummy:=Dummy+ 9;|
       14251.. 15750:Dummy:=Dummy+10;|
       15751.. 17250:Dummy:=Dummy+11;|
       17251.. 18000:Dummy:=Dummy+12;|
      EndCase;
    If Dummy<0
      then
        Dummy:=Dummy+24;
        DayNum:=DayNum-1;
        Case MonthNum of
          5,7,8,10,12:If DayNum<1
                        then
                          DayNum:=30;
                          MonthNum:=MonthNum-1;
                        EndIf;|
           2,4,6,9,11:If DayNum<1
                        then
                          DayNum:=31;
                          MonthNum:=MonthNum-1;
                        EndIf;|
                    3:If DayNum<1
                        then
                          If ((YearNum Div 4)*4)=YearNum
                            then
                              DayNum:=29;
                              MonthNum:=MonthNum-1;
                            else
                              DayNum:=28;
                              MonthNum:=MonthNum-1;
                            EndIf;
                        EndIf;|
                    1:If DayNum<1
                          then
                            DayNum:=31;
                            MonthNum:=12;
                            YearNum:=YearNum-1;
                          EndIf;|
          EndCase;
      EndIf;
    If Dummy>23
      then
        Dummy:=Dummy-24;
        DayNum:=DayNum+1;
        Case MonthNum of
          1,3,5,7,8,10:If DayNum>31
                         then
                           DayNum:=1;
                           MonthNum:=MonthNum+1;
                         EndIf;|
              4,6,9,11:If DayNum>30
                         then
                           DayNum:=1;
                           MonthNum:=MonthNum+1;
                         EndIf;|
                     2:If ((YearNum Div 4)*4)=YearNum
                         then
                           If DayNum>29
                             then
                               DayNum:=1;
                               MonthNum:=MonthNum+1;
                             EndIf;
                         else
                           If DayNum>28
                             then
                               DayNum:=1;
                               MonthNum:=MonthNum+1;
                             EndIf;
                         EndIf;|
                    12:If DayNum>31
                         then
                           DayNum:=1;
                           MonthNum:=1;
                           YearNum:=YearNum+1;
                         EndIf;|
          EndCase;
      EndIf;
    If STime=true
      then
        GPSTime:=IntToStr(Dummy+1:2:'0')+':'+IntToStr(MinNum:2:'0');
      else
        GPSTime:=IntToStr(Dummy:2:'0')+':'+IntToStr(MinNum:2:'0');
      EndIf;
    gDrawString(88,88,1,2,TxtRot0,DayName[CalcDay]);
    gDrawString(111,88,1,2,TxtRot0,GPSTime+'Uhr');
  End GPS_DaT;


es fehlen natürlich noch die Kostantentabellen:
Code

MonthConst      : Array[1..12] of Integer = (6,2,2,5,0,3,5,1,4,6,2,4);
YearConst       : Array[0..28] of Integer = (0,1,2,3,5,6,0,1,3,4,5,6,1,2,3,4,6,0,1,2,4,5,6,0,2,3,4,5,0);
DayName         : Array[0..7] of String[3] = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat','Sun');


Hier noch die Vorbelegung der obigen Variablen (Temp4=String[4]; CentNum muß im Prog belegt werden mit z.B. 20 (für dieses Jahrhundert):
Code

NG:=Copy(NMEA.Latitude,1,2);
NM:=Copy(NMEA.Latitude,3,7);
EG:=Copy(NMEA.Longitude,1,3);
EM:=Copy(NMEA.Longitude,4,7);
Temp4:=Copy(NMEA.Time_UTC,1,2);
HourNum:=StrToInt(Temp4);
Temp4:=Copy(NMEA.Time_UTC,3,2);
MinNum:=StrToInt(Temp4);
Temp4:=Copy(NMEA.Date,1,2);
DayNum:=StrToInt(Temp4);
Temp4:=Copy(NMEA.Date,3,2);
MonthNum:=StrToInt(Temp4);
Temp4:=Copy(NMEA.Date,5,2);
YearNum:=StrToInt(Temp4);
Harry
Moderator
Avatar
Gender:
Location: zwischen Augsburg und Ulm
Age: 59
Posts: 2135
Registered: 03 / 2003
Subject:

Re: Sommerzeit & mehr

 · 
Posted: 02.01.2014 - 22:39  ·  #2
Das Ganze oben ist implementiert in meinem GPS-Tacho5. Leider habe ich momentan das Problem, daß dieser vollkommen willkürlich resettet. Zuerst hab ich es auf das "overdrive" des µC (XMega256A3U @ 64 MHz) geschoben ..... reduzierung auf 32 MHz hat nichts gebracht. Stack/Frame erhöht auf gewaltige $0300, von den beiden Prozessen auch erhöht auf $40 .... keine Verbesserung.
Seltsamerweise hatte ich gestern ohne angeschlossenen GPS-Empfänger das Problem nicht. Leider habe ich heute auch FAT16_32 eingebaut ..... also von irgendwas muß es kommen. Wie gesagt der Reset kommt mal nach 3 Sekunden nach Programmstart und manchmal nach 10 Minuten :aerger:
..... grad noch nen Sack Kondensatoren auf die Platine gelötet ...... mal abwarten.

Gruss
Harry
You must be logged in or your permissions are to low to see this Attachment(s).
Gunter
Administrator
Avatar
Gender:
Location: Frankfurt Main / Germany
Posts: 1697
Registered: 02 / 2003
Subject:

Re: Sommerzeit & mehr

 · 
Posted: 02.01.2014 - 23:06  ·  #3
ach ja - vielleicht hift ja, was ich vor vielen Jahren mal ausgekobelt habe:
ein Jahr hat ja 365 Tage.
Von der letzten KW fallen also
Fall 1: 4 in das alte Jahr und 3 in das neue Jahr oder
Fall 2: 3 in das alte Jahr und 4 in das neue Jahr

Fall 1: altes Jahre besitzt zusätzlich noch eine KW 53
Fall 2: neues Jahre beginnt noch in KW 52 des alten Jahres

Bei Schaltjahren musste ich mir leider das Vorjahr ansehen,
was ja eher easy ist, da man ohnehin mit Tagen und KWs rechnet
und das Vorjahr meist schon vorher durchgeackert hat.
Vielleicht auch nur kalter Kaffee für Euch?

Das ist selbst in vielen Kalendern FALSCH gedruckt!!!

Gunter
Harry
Moderator
Avatar
Gender:
Location: zwischen Augsburg und Ulm
Age: 59
Posts: 2135
Registered: 03 / 2003
Subject:

Re: Sommerzeit & mehr

 · 
Posted: 03.01.2014 - 00:03  ·  #4
Hab die Funktion GPS_Dat um Datumskorrektur ergänzt und muß mal überlegen, wie ich diese überprüfen kann. Am einfachsten wäre wohl mit einem GPS-Simulator Daten einspeisen.
Harry
Moderator
Avatar
Gender:
Location: zwischen Augsburg und Ulm
Age: 59
Posts: 2135
Registered: 03 / 2003
Subject:

Re: Sommerzeit & mehr

 · 
Posted: 10.01.2014 - 19:03  ·  #5
Ein Fehler im Programm oben. Dritt-letzter Block, Procedure GPS_DaT, die 8. Zeile muß heißen:
Code
EMI:=(StrToInt(EG)*100)+((StrToInt(EMT)*100 div 60));
Harry
Moderator
Avatar
Gender:
Location: zwischen Augsburg und Ulm
Age: 59
Posts: 2135
Registered: 03 / 2003
Subject:

Re: Sommerzeit & mehr

 · 
Posted: 10.01.2014 - 23:39  ·  #6
Noch eine Verbesserung: Die Zeitzone wird nicht mehr mit einer Case of-Anweisung gemacht, sondern berechnet. Also ihr könnte den Block von EMI:= ...... bis zum EndCase durch folgendes (viel kürzer) ersetzen:
Code

EMI:=(StrToInt(EG)*100)+((StrToInt(EMT)*100 div 60))+750;
If NMEA.GPSLonInd='W'
  then
    Dummy:=Dummy-(EMI div 1500);
  else
    Dummy:=Dummy+(EMI div 1500);
  EndIf;
Harry
Moderator
Avatar
Gender:
Location: zwischen Augsburg und Ulm
Age: 59
Posts: 2135
Registered: 03 / 2003
Subject:

Re: Sommerzeit & mehr

 · 
Posted: 12.01.2014 - 21:22  ·  #7
Die Funktion CalcDay verkürzt (4 lokale Variablen und 5 Codezeilen weniger):

Code

Function CalcDay:Byte; // Berechnung des Wochentages So=0&7; Mo=1, Di=2, Mi=3....
  Var SJK, DayResult : Integer;
  Begin
    If ((MonthNum in [1..2]) and (((YearNum Div 4)*4)=YearNum))
      then
        SJK:=1;                              // Schaltjahrkorrektur
      else
        SJK:=0;
      EndIf;
    DayResult:=(((DayNum Mod 7)+(MonthConst[MonthNum])+(((3-(CentNum Mod 4))*2)+1)+(YearConst[(YearNum Mod 28)])) Mod 7)-SJK;
    Return(Lo(DayResult));
  End CalcDay;


Falls die Daten aus GPS-Daten stammen: es dauert (zumindest bei mir) immer ein bisschen, bis der RMC-Datensatz (und somit das Datum) verfügbar ist. Der GGA-Datensatz (der kein Datum enthält) ist immer früher da.
Harry
Moderator
Avatar
Gender:
Location: zwischen Augsburg und Ulm
Age: 59
Posts: 2135
Registered: 03 / 2003
Subject:

Re: Sommerzeit & mehr

 · 
Posted: 13.01.2014 - 15:07  ·  #8
Ich schon wieder: Ich habe die Funktion StartST und EndST mit Excel überprüft und es paßt - allerdings ist die Formel nur von 2000-2099 gültig !
  • 1
  • 2
  • Page 1 of 2
Selected quotes for multi-quoting:   0

Registered users in this topic

Currently no registered users in this section

The statistic shows who was online during the last 5 minutes. Updated every 90 seconds.
MySQL Queries: 15 · Cache Hits: 14   134   148 · Page-Gen-Time: 0.0264s · Memory Usage: 2 MB · GZIP: on · Viewport: SMXL-HiDPI