spezifisches Protokoll mit pyserial verarbeiten

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
spacemishka
User
Beiträge: 8
Registriert: Montag 7. Dezember 2015, 20:42

Hallo zusammen,

ich möchte mir gern ein Tool bauen, mit dem ich Daten aus meiner Nikon F100 auslesen kann. Leider komme ich mit der Doku nicht so gut zurecht.
Grundsätzlich bin ich ich der Meinung die Kamera korrekt anzusprechen. Zumindest was das WAKEUP und die Initalabfrage angeht.

Leider scheint das Lesen des Feedback nicht zu funktionieren.

Hier ist mein anfänglicher Code:

Code: Alles auswählen

import serial
import time
import binascii


com = serial.Serial(port='COM15', baudrate=1200, bytesize=serial.EIGHTBITS, stopbits=1)
print(com.is_open)
print(com.name)

com.write(binascii.hexlify(b'00'))
time.sleep(0.2)
#com.write(serial.to_bytes([0x53, 0x31, 0x30, 0x30, 0x30 ,0x05]))
com.write(binascii.hexlify(b'533130303005'))
time.sleep(0.1)
print(com.inWaiting())
if (com.inWaiting() > 0):
    data_str = com.read( com.inWaiting() )
    print(data_str)
Als Anwort kommt immer
b'\xfc'
Das Protokoll ist in den Kameras Nikon F90, F5, F100, F6 verfügbar, auch wenn in der Beschreibung nur die F90 erwähnt wird.

Könnt ihr mir eine Denkhilfe geben?

Danke!
Peter
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du scheinst hexdarstellung mit binären Daten zu verwechseln. Das ist in jedem Fall falsch. Alles wo du hexlify benutzt ist also schon mal fragwürdig. Das serial.to_bytes sieht sinnvoller aus.

Für mehr Hilfe wäre eine Beschreibung/Verlinkung des Protokolls hilfreich.
spacemishka
User
Beiträge: 8
Registriert: Montag 7. Dezember 2015, 20:42

Hallo,

ja das habe ich in der Tat vergessen:

https://web.archive.org/web/20071203124 ... tocol.html
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Na dann werd mal das hexlify los & benutz b“\x00“ stattdessen. Und für das inquiry die to_bytes Variante.
spacemishka
User
Beiträge: 8
Registriert: Montag 7. Dezember 2015, 20:42

Hallo,

danke für deine Antwort. Leider bekomme ich mit den Anpassungen die gleiche Meldung.
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Bitte zeigen was du versuchst. Wie sonst soll man das denn beurteilen?
spacemishka
User
Beiträge: 8
Registriert: Montag 7. Dezember 2015, 20:42

Mein Code lautet aktuell wie folgt:

Code: Alles auswählen

import serial
import time


com = serial.Serial( port='COM17', baudrate=1200, bytesize=8, stopbits=1, parity=serial.PARITY_NONE )
print( com.is_open )
print( com.name )

com.write( b'\x00\r\n')
#com.write(serial.to_bytes([0x00]))
time.sleep( 0.2 )
# print('1' , com.read())
com.write( serial.to_bytes( [0x53, 0x31, 0x30, 0x30, 0x30, 0x05] ) )
time.sleep( 0.1 )
print(com.read())
com.write( serial.to_bytes( [0x31, 0x30, 0x32, 0x30, 0x46, 0x39, 0x30, 0x58] ) )

time.sleep( 0.1 )
print(com.read())
com.write( serial.to_bytes( [0x2F, 0x4E, 0x39, 0x30, 0x53, 0x00, 0x03, 0x06] ) )  # 2F 4E 39 30 53 00 03 06
time.sleep(0.1)
print(com.read())
# com.close()
while com.inWaiting():
    r = com.read()
    print( '1', r )

zurückkommt :

Code: Alles auswählen

True
COM17
b'\xf8'
b'\xf8'
b'\xf8
mmhh kann doch nicht so schwer sein.
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wieso benutzt du denn mal bytestrings und mal to_bytes? Und warum fügst du an das 0-Byte CR & newline an? Stand doch so nicht im Beispiel deiner Webseite.
spacemishka
User
Beiträge: 8
Registriert: Montag 7. Dezember 2015, 20:42

benutz b“\x00“ stattdessen. Und für das inquiry die to_bytes Variante.
deswegen. :)

Es geht aber auch nicht wenn ich nur mit to_bytes arbeite.
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Na vor allem musst du die newline und CR Zeichen loswerden.
spacemishka
User
Beiträge: 8
Registriert: Montag 7. Dezember 2015, 20:42

Ich komm langsam vorwärts:

Code: Alles auswählen

import serial
import time
import codecs

com = serial.Serial( port='COM15', baudrate=1200)
print( com.is_open )
print( com.name )

#com.write(serial.to_bytes( [0x00]) )
#com.write(bytes.fromhex('00'))
com.write(codecs.decode('00', 'hex_codec'))
time.sleep( 0.2 )
com.flush()
com.write(codecs.decode('533130303005', 'hex_codec'))

#com.write( serial.to_bytes( [0x53, 0x31, 0x30, 0x30, 0x30, 0x05] ) )
time.sleep( 0.1 )
print(1,com.read(com.in_waiting))
com.flush()
#com.write( serial.to_bytes( [0x31, 0x30, 0x32, 0x30, 0x46, 0x39, 0x30, 0x58] ) )
com.write(codecs.decode('3130323046393058', 'hex_codec'))
time.sleep( 0.1 )
print(2,com.read(com.in_waiting))
com.flush()
#com.write( serial.to_bytes( [0x2F, 0x4E, 0x39, 0x30, 0x53, 0x00, 0x03, 0x06] ) )  # 2F 4E 39 30 53 00 03 06
com.write(codecs.decode('2F4E393053000306', 'hex_codec'))
time.sleep(0.1)
print(3,com.read(com.in_waiting))
com.flush()
# com.close()
erzeugt analog der Beschreibung:

Code: Alles auswählen

True
COM15
1 b'\x00S1000\x05'
2 b'1020F90X'
3 b'/N90S\x00\x03\x06'
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mit Verlaub - aber du musst mal aufhören zu Cargo culten und dich mit der Verarbeitung von bytes Strings in python beschäftigen.

Diese von-hinten-durch-die-Brust-ins-Auge dekodiere von hex werte liefert EXAKT was da vorher stand:

Code: Alles auswählen

>>> codecs.decode('00', 'hex_codec')
b'\x00'
Das Problem waren also die eingestreuten anderen Zeichen, die du danach eingefügt hast.

In Python kannst du problemlos b'\xAB' schreiben um den Wert 171 als genau ein Byte zu erhalten. Und mehrere Hexwerte als '\x12\x34' etc.
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Die anderen Hex-Werte sind zum Großteil schön lesbare Buchstaben:

Code: Alles auswählen

b'S1000\x05'
b'1020F90X'
b'/N90S\x00\x03\x06'
Antworten