www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Berechnung der Jahrzahl [jjjj], wenn nur die letzte Stelle vorhanden ist


Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Habe folgendes Problem:

Ich bekomme über ein Protokoll auf der seriellen Schnittstelle das Datum 
folgendermassen gesendet: dd.mm.j

Hat jemand eine Idee, wie ich aus der einzelnen Ziffer (Im Jahr 2008 nur 
die 8) für die nächsten 50 Jahre die ganze 4- stellige Zahl (2008 usw.) 
berechnen kann?

Internes EEPROM steht zur Verfügung.

Gruss Andy

Autor: Hmm... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Garnicht. Es fehlt nämlich die Information welches Jahrzehnt gemeint 
ist, und die kann man auch mit einem EEPROM nicht auf magische Weise 
gewinnen.

Einziger Weg wäre es, zusätzlich noch das Jahrzehnt zu übertragen 
(2008->08),
dann könnte man sogar bis zum Jahr 2099 ein gültiges Datum 
rekonstruieren. In einigen Systemen wurde das bis 2000 übrigens sogar 
genau so gemacht. ;)

Vorschlag: Wenn ein Byte im Protokoll dafür reserviert ist, dass du 
anpassen könntest, dann übertrag das Jahr oder noch besser das ganze 
Datum doch als Binär-Wert.

Beispiel für gepacktes 16-Bit Datum:
31 Tage    -> 5 Bit
12 Monate  -> 4 Bit
Jahr       -> 7 Bit

Damit kannst du satte 127 Jahre lang ein Datum kodieren. Wenn du es als 
Offset auf das Jahr 2000 beziehst bist du damit bis ins Jahr 2127 auf 
der sicheren Seite...

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn die Einerstelle auf einmal kleiner ist als die im
EEprom, kannst Du davon ausgehen das ein 10er Übertrag stattgefunden
haben muß, dann neuen Wert in den EEprom schreiben.

Das sollte auch noch funktionieren, wenn das Gerät mal 9 Jahre
nicht im Betrieb war.

Gruß Klaus

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nimm die ersten drei Stellen der Jahreszahl vom aktuellen Datum.

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für Eure Antworten!

@Hmm... Hab leider keinen Einfluss auf das Protokoll. Deshalb bin ich 
auf diese einzelne Stelle angewiesen.

@Klaus Diese Lösung sieht mir sehr vernünftig aus. Hab auch schon in 
diese Richtung gedacht.

@Martin Weiss leider nicht genau, wie Du das gemeint hast.

Autor: Hmm... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieweit in die Zukunft bzw. die Vergangenheit können die Datumsangaben 
den liegen?

Autor: Severino R. (severino)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm... wrote:

> dann könnte man sogar bis zum Jahr 2099 ein gültiges Datum
> rekonstruieren. In einigen Systemen wurde das bis 2000 übrigens sogar
> genau so gemacht. ;)
Man könnte dann auch bis zum Jahr 9999 ein gültiges Datum 
rekonstruieren, da Du annimmst, dass das Jahr immer "in der Nähe" des 
aktuellen Jahrs liegt.

Wenn das Jahr im Protokoll immer sehr zeitnah ist, gäbe es höchstens 
Probleme um den Jahreswechsel, aber das könnte man auch noch lösen (z.B. 
mit Klaus' Idee).

Martins Idee scheitert hingegen Ende 2009.

Andy soll zuerst mal sagen, ob er am Datumsformat im Protokoll überhaupt 
etwas ändern kann (wohl nicht, sonst würde er wohl jjjj senden).
Ausserdem muss man wissen, wie weit das Datum im Protokoll maximal vom 
aktuellen Datum abweichen kann.

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Datum wird zusammen mit der Zeit ca. 4x pro Minute gesendet. Die 
Jahrzahl wie gesagt leider nur mit einer Stelle.

Es kann aber auch passieren, dass das Gerät Monatelang ausser Betrieb am 
Lager liegt.

Ab und zu (alle paar Monate, ist aber auch nicht garantiert) werden via 
Mamorystick Daten auf das Gerät übertragen. Da habe ich evt. auch noch 
die Gelegenheit das Datum zu synchronisieren.

Muss dann anhand des Datums, den Wochentag und die Feiertage berechnen. 
Dies geht natürlich nur mit der gesamten 4-stelligen Jahreszahl.

Wenn das ganze bis 2099 funktionieren würde wäre das ganz cool...

Autor: Hmm... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie gesagt, wenn stets nur das aktuelle Jahr gesendet wird könnte man es 
mit Klaus Methode machen.

Man sichert einmal das vollständige aktuelle Jahr im EEPROM. 
Anschließend kann das gesendete Datum nur im selben Jahr wie der Wert im 
EEPROM oder danach liegen. Entsprechend aktualisiert man den Wert im 
EEPROM, wenn ein Jahreswechsel statt gefunden hat.

Drei Nachteile hat es:

1. Das Gerät darf nicht länger als 9 Jahre am Stück kein neues Datum
   empfangen. Sonst verliert man ein Jahrzehnt.

2. Das gesendete Datum muss das aktuelle sein. Es sind keine beliebigen
   Datumsangaben möglich.

3. Man sollte wen möglich die Produktion der Geräte sicherheitshalber 
über
   Silvester still legen. ;)

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auch wenn es abgelehnt wurde, wie wäre es mit einer Protokolländerung?
Es ist nunmal nicht möglich, sich Information zu erzaubern.(Dein Chef 
wird dir doch auch sagen, bis zu welchen Tag in welchem Monat und Jahr 
du das fertig haben sollst. Oder gibt er dir hier auch nur den Tag?)

Man, wer denkt sich nur immer so einen Mist aus.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andy wrote:

> Ich bekomme über ein Protokoll auf der seriellen Schnittstelle das Datum
> folgendermassen gesendet: dd.mm.j
>
> Hat jemand eine Idee, wie ich aus der einzelnen Ziffer (Im Jahr 2008 nur
> die 8) für die nächsten 50 Jahre die ganze 4- stellige Zahl (2008 usw.)
> berechnen kann?

Hmm, knifflig.

Versuche es mal mit
jahr = j + 2000;

Das baut darauf, dass der Sender die Jahre ab 2000 schickt, aber 
vergessen hat führende Nullen mit zu schicken (%d statt %02d im 
Formatstring). Es wäre interessant zu wissen, was bei einem Datum ab 
2010 passiert, also ob eine j=10 kommt oder wieder eine j=0. Kannst du 
den Kalender am Sender testweise vor drehen?

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke an alle!

Falls es jemanden interessiert, scheint ganz gut zu klappen:
//----------------------------------------------------------------------------
// Funktionsnamen : complete_year()
//
// Beschreibung   : 4-stellige Jahreszahl aus einer Ziffer berechnen
// Arguments      : unsigned char Jahresziffer 0-9
// Return         : unsigned int16 Jahreszahl (jjjj)
//----------------------------------------------------------------------------
unsigned int16 complete_year(unsigned char protokoll_jahr) 
{
  unsigned int16 tmp_jahr=0;
  unsigned char eeprom_jahr_einer=0;
  unsigned char eeprom_jahr_zehner=0;
  
  eeprom_jahr_einer=save_memory_byte_read(EEPROM_IBIS_JAHR_EINER);
  eeprom_jahr_zehner=save_memory_byte_read(EEPROM_IBIS_JAHR_ZEHNER);
     
     // Ist schon gültige Jahrzahl in EEPROM vorhanden?
  if (((eeprom_jahr_einer <= 9) && (eeprom_jahr_einer >=0)) &&    
    ((eeprom_jahr_zehner <= 90) && (eeprom_jahr_zehner >=0)))
  {
      
    if(eeprom_jahr_einer == protokoll_jahr)    // Ja, vergleichen mit IBIS_year
    {
      tmp_jahr = read_eeprom(EEPROM_IBIS_JAHR_ZEHNER) + save_memory_byte_read(EEPROM_IBIS_JAHR_EINER);
    }
    else
    {
      write_eeprom(EEPROM_IBIS_JAHR_EINER,protokoll_jahr); // Neue Jahrziffer aus Protokoll in EEPROM übernehmen
      tmp_jahr = save_memory_byte_read(EEPROM_IBIS_JAHR_ZEHNER) + save_memory_byte_read(EEPROM_IBIS_JAHR_EINER);
      
      if(protokoll_jahr <= eeprom_jahr_einer) // Ist Protokoll Jahr kleiner als EEPROM Jahr
      {
        if(eeprom_jahr_zehner <= 80)
        {
          eeprom_jahr_zehner += 10; // Zehnerstelle um eins erhöhen  
        }  
        
        write_eeprom(EEPROM_IBIS_JAHR_ZEHNER,eeprom_jahr_zehner); // Wieder zurückschreiben
        
        // Neues Jahr berechnen
        tmp_jahr = save_memory_byte_read(EEPROM_IBIS_JAHR_ZEHNER) + save_memory_byte_read(EEPROM_IBIS_JAHR_EINER);
      }    
    }    
  }
  else // Bei 0xFF neu formatieren 
  {
    // Neues EEPROM formatieren
    write_eeprom(EEPROM_IBIS_JAHR_EINER,8);      // Default Jahr 2008 in EEPROM schreiben
    write_eeprom(EEPROM_IBIS_JAHR_ZEHNER,0);
    tmp_jahr=8;
  }  
            
  tmp_jahr += 2000;
  
  return(tmp_jahr);
}  


Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beim der Anwendung handelt es sich übrigens um das IBIS- Protokoll, 
(Integriertes Bordinformationssystem) welches in der Bahntechnik zur 
Anwendung kommt.

Datensatz: 006 d5Z > AD Kalender- Datum, welches wie gesagt nur 5 
Ziffern enthällt. (dd.mm.j)

Vielleicht kennt sich ja jemand damit aus und und kann mir ein Telegramm 
nennen, wo die gesamte Jahreszahl übertragen wird.

Autor: Zwischenfrequenz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Idee gefällt mir. Es gibt aber noch einen eventuellen Nachteil:
Die Verbindung muss zuverlässig sein. Gibt es Fehlererkennung / 
Fehlerkorrektur im Bahn-Protokoll? Sonst kann dich eine einmalig falsch 
empfangene Jahreszahl dauerhaft (oder bis zum nächsten Memorystick) um 
10 Jahre nach vorne bringen.

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Daten werden mit 1200,7,e,2 übertragen.

D.h. 7Bit- ASCII Codierte Zeichen, welche mit einem Paritäts Bit codiert 
sind. Das Telegram beinhaltet am Ende ausserdem ein Längspartyäts- Byte 
als Chechsumme.

Ich lese das Datum 2x hintereinander ein und akzeptiere dies nur, wenn 
es 2x gleich ist.

Ein gewisses "Restrisiko" besteht natürlich immer. Hoffe jetzt, dass 
sich Murphy ein wenig zurück hält.

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Andy,

wenn das was kommerzielles wird machs sicher! Sonst
steht "Murphy" schon neben Dir.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.