- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 13

Thema: Vorgehensweise beim einlesen eines Telegramms variabler Länge

  1. #1
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    29.07.2011
    Beiträge
    348

    Vorgehensweise beim einlesen eines Telegramms variabler Länge

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hi zusammen,

    wie der Titel schon verrät habe ich ein logisches Problem beim einlesen eines Telegrammes variabler Länge. Das Telegramm läuft über eine RS485-Verbindung.

    Aktuell ist es so, das ich ein Telegramm mit fixer Länge verwende. Da ich weiß wie lang das Telegramm sein muss, warte ich ab bis die notwendige Anzahl an Bytes im Eingangspuffer stehen und werte die Bytes bzw. das gesamte Telegramm dann auf einmal aus.
    Ich prüfe dann ob das Telegramm für diesen Teilnehmer ist, ob die Prüfsumme passt usw. usw..
    Ist es nicht für mich oder stimmt irgendwas nicht, wird es einfach verworfen.

    Wie mache ich das jetzt aber, wenn ich eine variable Länge habe? Ich weiß ja nicht auf wieviele Bytes ich warten muss bis das Telegramm vollständig empfangen wurde? Lese ich zunächst nur den Telegrammkopf ein und werte diesen aus? Von dem weiß ich ja die Fixlänge. Brauche ich da dann eine eigene Prüfsumme für den Telegrammkopf? Wenn ich in dem Kopf dann schon sehe das es nicht für mich ist, dann muss ich trotzdem die Nutzdaten abwarten und verwerfen?

    Aktuell soll das Telegramm so aussehen: (jeweils 1 Byte)

    Zieladresse / Quelladresse / Länge der Nutzdaten / Registerzugriff / ( hier kommen jetzt die variablen Nutzdaten) / Prüfsumme

    Bisher war es auch so, das ich den Telegrammkopf und die Nutzdaten in die Prüfsumme habe mit einfließen lassen. Geht das dann auch noch oder macht es keinen Sinn?

    Ich hoffe Ihr könnt mir weiterhelfen. Ich stehe gerade ein wenig auf dem Schlauch.

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    53
    Beiträge
    765
    Bei mir wird jedes Telegramm mit einem CHR(13) abgeschlossen. Bei "empfindlichen" Dingen kommt auch ein Zeichen für den Beginn eines Telegramms.
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

  3. #3
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    29.07.2011
    Beiträge
    348
    Ok,

    und wie gehst du vor beim Einlesen deines Telegramms?

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    66
    Beiträge
    2.435
    Hallo,

    Ich habe solche Decoder immer als State-Maschine im Interrupthandler eingebaut.

    Eine Prüfsumme über die beiden Adressen und die Länge ist nötig, wenn sich ein Fehler bei der Länge einschleicht, findest du das Ende nicht.
    Zudem brauchst du noch eine Möglichkeit, welche eindeutig den Anfang oder das Ende markiert. Sonst kannst du den Anfang der nächsten Meldung nicht finden, wenn die Länge kaputt ist.

    Möglich sind irgendwelche Statusleitungen, die Zeit, wenn sichergestellt ist, dass die minimale Zeit zwischen zwei Meldungen deutlich grösser ist als die maximale Zeit zwischen zwei Zeichen oder halt ein spezielles Zeichen, bzw. ein Escape-Kombination wenn die Protokoll binär ist.

    Als Escape-Zeichen nimmt man ein Bitkombination, welche normalerweise eher selten im Datenstrom vorkommt.
    Nehmen wir mal z.B. 0xAA
    Als Start- oder Endmarke sendest du die Bytes 0xAA, 0xFF
    Wenn 0xAA im Datenstrom vorkommt, verdoppelst du dies zu 0xAA 0xAA beim Sender.
    Wenn der Empfänger 0xAA 0xAA erhält, wird das erste 0xAA entfernt und das Zweite im Buffer abgelegt.

    Scheinbar programmierst du in Bascom, da kann ich dir kein Beispiel liefern, nur in C könnte ich was schreiben.

    MfG Peter(TOO)
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

  5. #5
    Erfahrener Benutzer Begeisterter Techniker Avatar von Andre_S
    Registriert seit
    26.06.2005
    Beiträge
    360
    Hallo!

    Auch von mir noch ein etwas anderer Ansatz bei variabler Telegrammübertragung ebenfalls mit Start/Endbyte, bei welchem die Eindeutigkeit dieser gesichert ist. Allerdings müssen dazu mindestens die Nutzdaten und wenn benötigt (Sicherheitsstufe) die Prüfsumme codiert werden. Die Prüfsumme würde ich prinzipiell über alles, ausgenommen Start/Endbyte, nehmen.

    Aufbau:

    • 1. Byte Startbyte (0xAA)
    • 2. Byte Sender (0xFF)
    • 3. Byte Empfänger (0xF1)
    • 4...18 Nutzdaten (H/L codiert)
      • 0xA3 (wird zu 0x0A und 0x03)
      • 0x3C (wird zu 0x03 und 0x0C)
      • usw...

    • 19/20. Prüfsumme XOR (0xA4 -> H/L codiert)
      • 0x0A
      • 0x04

    • 21. Endbyte (0xBB)

    Start/Endbyte sind natürlich so zu wählen, dass keine Dopplung mit den Master/Slave Adressen auftreten kann. Ist dies nicht zu realisieren, müssen diese ebenfalls codiert werden.
    Das ganze kann man ebenfalls im eigenen Tread/IRQ autark laufen lassen, allerdings kann man grundsätzlich beim Empfang des Startbytes zurücksetzen und bis zum Erreichen des Endbyte einlesen, da diese eindeutig sind und nicht in den anderen Daten vorkommen können.
    Nachteil ist, dass sich das Volumen der Nutzdaten/Prüfsumme erhöht und deshalb bei Volumentarifen ungünstig ist.

    Somit passiert folgendes beim Empfang des obigen Beispiels:

    • Startbyte 0xAA empfangen -> Reset Counter
    • Bytes lessen -> Bufferspeicher (counter++)
    • Byte ist Endbyte 0xBB
      • Bufferspeicher auswerten
        • Adressen 0xFF/0xF1 -> OK
        • decodieren
        • XOR über alle Byte (außer Start/Endbyte) –> vergleich mit Prüfsumme -> OK Telegramm empfangen!



    Um nicht unnötig lesen zu müssen können auch unterschiedliche Start/Endbyte je Richtung festgelegt werden. Also Slave -> Master z.B. 0xAA/0xCC und Master -> Slave 0xBB/0xDD.

    Für ein besseres Fehler/Wiederholungsandling kann man auch noch die Information „Anzahl der Telegramme“ und „Nummer des aktuellen Telegramms“ einbinden.

    • 4. Byte Anzahl Telegramme (0x04)
    • 5. byte Aktuelles Telegramm (0x02)


    Könnte die Anzahl der zusammengehörigen Telegramme die Werte des Start/Endbytes erreichen müssten diese ebenfalls innerhalb der Codierung mitgeführt werden.

    Und je nach Sicherheitsstufe ist es natürlich auch noch möglich die Information „Anzahl der Bytes“ innerhalb des Telegramms codiert zu hinterlegen.


    Gruß André

  6. #6
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    53
    Beiträge
    765
    Ich nutze immer folgendes Schema:

    Code:
    Do
       If Ischarwaiting() = 1 Then
          Gosub Empfangen
       End If
    loop
    end
    Empfangen:
        B = Inkey()
        If B = 13  Then                      'CR
            Gosub Auswerten
        Else
            Bb = Len(seingang) 'Noch Platz im Eingangspuffer?
            If Bb < 26 Then
                Seingang = Seingang + Chr(b)
            Else
                Seingang = ""
            end if
        End If
    Return
    
    Auswerten:
       If Len(seingang) >= 1 Then                               'Überhaupt was Verwertbares?
       ...
       ...
       ...
       end if
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

  7. #7
    Erfahrener Benutzer Begeisterter Techniker Avatar von Andre_S
    Registriert seit
    26.06.2005
    Beiträge
    360
    Zitat Zitat von peterfido Beitrag anzeigen
    Ich nutze immer folgendes Schema:

    Code:
    Do
       If Ischarwaiting() = 1 Then
          Gosub Empfangen
       End If
    loop
    end
    Empfangen:
        B = Inkey()
        If B = 13  Then                      'CR
            Gosub Auswerten
        Else
            Bb = Len(seingang) 'Noch Platz im Eingangspuffer?
            If Bb < 26 Then
                Seingang = Seingang + Chr(b)
            Else
                Seingang = ""
            end if
        End If
    Return
    
    Auswerten:
       If Len(seingang) >= 1 Then                               'Überhaupt was Verwertbares?
       ...
       ...
       ...
       end if
    Hallo Peter!

    Das geht doch aber nur, wenn Du sicherstellen kannst, dass der Datenstrom keine binären Daten enthält.


    Gruß André

  8. #8
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    53
    Beiträge
    765
    Jo, stimmt. Binäre Daten in dem Sinne nutze ich so nicht. Da hängt das Protokoll dann vom anderen Baustein ab. Rein nach RS... werden Werte allerdings in Textform übertragen. Da braucht dann eine 200 halt 3 Bytes. Binäre Daten in dem Sinne sind dann was für 1 Wire, TWI und so. Bei komplett eigenen Projekten, wo ich beide Kommunikationspartner programmiere, wird alles so gemacht, wie ich es gepostet habe. "Binäre" Daten werden dann mit gesetztem 7.Bit übermittelt. So erkenne ich immer noch sicher den CHR(13) als Telegrammende. Bisher nur in meinem T300x Projekt (T-Hack) so gemacht.
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

  9. #9
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.08.2008
    Ort
    DE
    Beiträge
    523
    http://de.wikipedia.org/wiki/Type-Length-Value
    Am Schluss noch eine Checksum anfügen und schon hast du ein zu 99% sicheres und einfaches Protokoll.

    mfg

  10. #10
    Erfahrener Benutzer Begeisterter Techniker Avatar von Andre_S
    Registriert seit
    26.06.2005
    Beiträge
    360
    Zitat Zitat von peterfido Beitrag anzeigen
    Jo, stimmt. Binäre Daten in dem Sinne nutze ich so nicht. Da hängt das Protokoll dann vom anderen Baustein ab. Rein nach RS... werden Werte allerdings in Textform übertragen. Da braucht dann eine 200 halt 3 Bytes. Binäre Daten in dem Sinne sind dann was für 1 Wire, TWI und so. Bei komplett eigenen Projekten, wo ich beide Kommunikationspartner programmiere, wird alles so gemacht, wie ich es gepostet habe. "Binäre" Daten werden dann mit gesetztem 7.Bit übermittelt. So erkenne ich immer noch sicher den CHR(13) als Telegrammende. Bisher nur in meinem T300x Projekt (T-Hack) so gemacht.
    Hallo,

    ja,… das funktioniert in der Form dann auch!
    Es gibt halt immer mehrere Wege zum Ziel…

    Allerdings möchte ich gern noch ergänzen:
    „Rein nach RS... werden Werte allerdings in Textform übertragen“…
    Das würde ich nach meinen Erfahrungen nicht verallgemeinern. Ich habe mit verschiedenen Geräten zu tun, welche auf dieser Basis binär Daten übertragen und erwarten, da oft nur die elektrischen Schnittstellen aber nicht das Protokoll definiert wurde. Ein einfaches Beispiel wäre das M-Bus Protokoll, welches durch Pegelwandler auch auf RS4../RS2.. umgesetzt wird.
    Bei allen wo ich wiederum Einfluss habe, nehme ich aus Gründen der Störsicherheit das komplette „Gedeck“ mit allen Sicherungen wie oben teilweise angedeutet.


    Gruß André

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Länge eines Distanzbolzen
    Von Lunatix im Forum Mechanik
    Antworten: 2
    Letzter Beitrag: 18.08.2009, 14:27
  2. Länge eines Pulses messen
    Von waxology im Forum C - Programmierung (GCC u.a.)
    Antworten: 10
    Letzter Beitrag: 22.08.2007, 07:58
  3. Antworten: 1
    Letzter Beitrag: 03.06.2007, 10:15
  4. Einlesen eines Tasters...
    Von Spritey im Forum PIC Controller
    Antworten: 4
    Letzter Beitrag: 28.01.2005, 12:25
  5. [ERLEDIGT] Werte eines Biosensors in HW einlesen
    Von Takeo im Forum Sensoren / Sensorik
    Antworten: 2
    Letzter Beitrag: 22.11.2004, 16:46

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests