HEX Länge ermitteln

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
kiaralle
User
Beiträge: 154
Registriert: Donnerstag 19. August 2021, 19:11

Hi,
hätte mal wieder eine Frage.
Folgenden Hex hätte ich im Angebot

b'@B\x00\x01,\xc8\xe7'

Ich weiß, das sich das Ding aus 4 Segmente (Hex-Werte) zusammen setzt.
Nun erhalte ich wenn etwas nicht funktioniet statt diesem langen HEX nur einen kurzen.

b'@B\x0c

0c is der Fehlercode, mit dem ich was anfangen kann.

Wie kann ich die Länge des Hex ermitteln.


Code: Alles auswählen

sick_string = "FF 42"


def status(sick_string):    
    
    data = bytearray.fromhex(sick_string)
    data.append(ChecksumXor8.calc(data))
  
        
    ser.reset_input_buffer() 
    ser.reset_output_buffer()
    time.sleep(0.01)  #give the serial port sometime to receive the data

    ser.write(data)
    time.sleep(0.01)
    response = ser.read(7)
    print(response)
    

    if  .....wenn der Hex zu kurz kommt ....:
        fehlermeldung=''.join(format(byte, '02x') for byte in response[2:3])
        fehlerspeicher = sick_error.srm_errors(fehlermeldung)        
        data = 0
    else:
        fehlerspeicher = ""
        data = int.from_bytes(response[2:6],'big',signed=False)
    
    return data, fehlerspeicher
 
test = status(sick_string)
print(test[0])
print(test[1])

Gruß Ralf
Benutzeravatar
sparrow
User
Beiträge: 4615
Registriert: Freitag 17. April 2009, 10:28

XY-Problem.

Prüfe nicht auf die Länge. Prüfe auf den Inhalt.
Wenn du weißt, dass b'@B\x0c' einen Fehler bedeutet, dann prüfe exakt darauf, nicht auf die Länge.
Vielleicht kommt es zu dem Umstand, dass b'@Baa' zurück kommt. und dann möchtest du das wissen und nicht so tun, als wäre das der Fehlercode.
kiaralle
User
Beiträge: 154
Registriert: Donnerstag 19. August 2021, 19:11

b'@B\x0c' kann aber auch teil der Daten = Positionszahl sein.

b'@B\x0c\x01,\xc8\xe7' ... Zahl
b'@B\x0c ... Error
kiaralle
User
Beiträge: 154
Registriert: Donnerstag 19. August 2021, 19:11

ich zerlege

int.from_bytes(response[2:6],'big',signed=False)

und prüfe vorab ob
int.from_bytes(response[3:4],'big',signed=False)
etwas enthält.
wenn nicht, ist der Datensatz kürzer.
Sirius3
User
Beiträge: 18342
Registriert: Sonntag 21. Oktober 2012, 17:20

Wie ist denn die Spezifikation des Protokolls? Das muß ja irgendwo genau erklärt sein, was welches Byte bedeutet. Es muß ja irgendwie klar sein, was ein gültiger Datensatz ist und was ein Fehler. Anscheinend fängt ja beides mit `40 42` an, was etwas ungewöhnlich wäre, wenn danach nur noch Nutzdaten kommen.
Zusätzlich solltest Du auch die Prüfsumme prüfen, dafür ist sie ja da.
Ohne Dokumentation kann man also hier nur raten, was Du eigentlich brauchst.

Zur Funktion an sich: alles was eine Funktion braucht, muß sie über ihre Argumente bekommen. `ser` kommt aber aus dem Nichts. Eine Funktion sollte einen eindeutigen Rückgabewert haben und bei Fehler eine Exception werfen.

Code: Alles auswählen

SICK_STRING = b"\xFF\x42"

def query_status(serial_interface, sick_string):    
    data = bytearray.fromhex(sick_string)
    data.append(ChecksumXor8.calc(data))
    serial_interface.reset_input_buffer() 
    serial_interface.reset_output_buffer()
    time.sleep(0.01)
    serial_interface.write(data)

    # give the serial port sometime to receive the data
    time.sleep(0.01)
    response = serial_interface.read(7)
    print(response)
    if response[:2] == b"\x40\x42" or ChecksumXor8.calc(response) != 0:
        raise ValueError("Wrong data received")
    if  is_error(response):
        error_code = f"{response[2]:02x}"
        raise ValueError(sick_error.srm_errors(error_code))        
    result = int.from_bytes(response[2:6], "big", signed=False)
    return result
 
print(query_status(serial_interface, SICK_STRING))
kiaralle
User
Beiträge: 154
Registriert: Donnerstag 19. August 2021, 19:11

Ich werde falsch verstanden. Ist aber nicht so schlimm.


Ich sende den sick_string an das Gerät.

sick_string = "Rs485-Adresse + Befehl "

Erhalten werde ich wenn alles iO. ist

response = "Rs485-Adresse + Befehl + 4Bit Position+ Checksum "

Erhalten werde ich wenn nicht alles iO. ist

response = "Rs485-Adresse + Befehl + 1Bit Fehlermeldung + Checksum "

Wobei das 7. Bit das Errorbit sein soll. Ich jedoch noch nie festgestellt habe, das dies gesetzt ist.
Ich erhalte immer b' '.
Wahrscheinlich muss ich mich darauf konzentrieren. Denn wenn das gesetzt wäre, hätte ich ja meine Fehlererkennung.

Dokumentation: https://www.audin.fr/pdf/documentation ... ERFACE.pdf
Benutzeravatar
__blackjack__
User
Beiträge: 14259
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@kiaralle: Wenn das Fehlerbit nicht gesetzt ist, vermute ich dass gar kein Fehler vorliegt, sondern Du ein Timeout beim `Serial`-Objekt gesetzt hast, das zu klein ist, und Du einfach nicht die komplette Nachricht empfängst.
“Programming is partially an artform and, like artists, programmers will do it even if they don't get money.” — Linus Torvalds
Antworten