MMS Geschrieben October 28, 2014 at 23:29 Geschrieben October 28, 2014 at 23:29 Hallo, ich habe ein Problem damit die UIDs von Base58 in Int umzurechnen. In der Doku steht:"UID "b1Q" (Base58) or 33688 (integer)" ich komme aber auf 582*34+23 = 114399. Wie wird richtig gerechnet? Grüße Zitieren
borg Geschrieben October 29, 2014 at 08:58 Geschrieben October 29, 2014 at 08:58 Ich komme auf 33688 . olaf@pc:~$ python Python 2.7.6 (default, Mar 22 2014, 22:59:38) [GCC 4.8.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> BASE58 = '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ' >>> def base58decode(encoded): ... value = 0 ... column_multiplier = 1 ... for c in encoded[::-1]: ... column = BASE58.index(c) ... value += column * column_multiplier ... column_multiplier *= 58 ... return value ... >>> base58decode("b1Q") 33688 Händisch: >>> BASE58 = '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ' >>> BASE58.index('b') 10 >>> BASE58.index('1') 0 >>> BASE58.index('Q') 48 >>> 10*58**2 + 0*58**1 + 48*58**0 33688 Zitieren
MMS Geschrieben October 29, 2014 at 11:14 Autor Geschrieben October 29, 2014 at 11:14 Ok. Danke, habe eine falsche Zeichntabelle verwendet. Ich versuche direkt über die RS485 Extension (Slave, Adresse: 1) mit einem Ambient Light Bricklet (UID: b1Q) zu kommunizieren. Wenn ich folgendes sende müsste ich doch die Helligkeit als Antwort erhalten: Modbus Adress: 0x01 Func. Code: 0x64 Seq. Num: 0x01 UID: 0x98 0x83 0x00 0x00 Packet Length: 0x08 Func ID: 0x01 Seq. Num.: 0x18 Flags: 0x00 CRC16: 0xAE 0x41 Ich bekomme aber nur 0x00 zurück. Habe ich irgendwo einen Fehler übersehen? Zitieren
borg Geschrieben October 30, 2014 at 09:21 Geschrieben October 30, 2014 at 09:21 Das sieht soweit ganz gut aus. Passt die Baudrate? Womit sprichst du RS485 (was nutzt du als RS485 Master)? Zitieren
MMS Geschrieben October 30, 2014 at 12:19 Autor Geschrieben October 30, 2014 at 12:19 Baudrate überall 250000, Parität und Stopbits passen auch. Als Master verwende ich einen Raspberry mit einem RS485 zu UART Wandler. Die gesendeten Daten passen und wurden mit einem Terminalprogramm überprüft. Sie kommen auch am Stack an, habs mit nem Oszi gemessen. Zitieren
photron Geschrieben October 30, 2014 at 12:43 Geschrieben October 30, 2014 at 12:43 Sprichts du denn das Protokoll auch so wie hier beschrieben: http://www.tinkerforge.com/de/doc/Low_Level_Protocols/Modbus.html#requests-and-responses Sprich pollst du den Slave für Responses nachdem du ihm den Request gesendet hast? Slaves dürfen von sich aus keinen Response senden, sondern nur als Antwort auf einen Request. Edit: Hätte mal richtig lesen sollen. Wie handhabt dein RS485 Wandler den Transmitter und Receiver Enable? Steuerst du das von Hand, oder passiert das automatisch? Wenn der Transmitter auf der Master-Seite aktiviert ist wenn der Slave antwortet dann kann die Antwort verfälscht ankommen. Zitieren
MMS Geschrieben October 30, 2014 at 15:18 Autor Geschrieben October 30, 2014 at 15:18 Habe meinen Fehler gefunden. Lag am Receiver Enable. Ich habe am RS485 Wandler zu früh auf Empfangen umgeschaltet, so wurden die letzten bits nicht gesendet. Jetzt bekomme ich eine Antwort. Danke für die Hilfe!!! Zitieren
Loetkolben Geschrieben November 5, 2014 at 11:47 Geschrieben November 5, 2014 at 11:47 Hallo MMS, kannst du kurz mal die Hardware beschreiben und die Software posten wie man so eine Abfrage macht? Danke. Der Loetkolben Zitieren
MMS Geschrieben November 14, 2014 at 21:15 Autor Geschrieben November 14, 2014 at 21:15 Hallo, zur Hardware: -Rasperry Pi mit aktuellem Raspian und Python 3 -Raspicomm Erweiterung für RS485 (andere RS485 Boards bei denen man den RTC Pin für die Datenrichtung manuell setzen muss gehen auch, machen das programmieren aber sehr aufwändig) -ein Stück dreiadriges Kabel -Masterbrick mit RS485 Extension Hier der Python Code. Er funktioniert ist aber ein erster Entwurf und noch nicht optimiert. @borg: passt denn die Bestätigung nach erfolgreicher Abfrage: 0x01, 0x64, modbus_sequence, crc16 import serial import time import crc16 def get_value(port, mod_adr, mod_seq, tcp_seq, func_id): #Abfrage des Bricks flag = True #Flag True bis Abfrage erfolgreich req = bytearray([0x01, 0x64, mod_seq, mod_adr[0], mod_adr[1], mod_adr[2], mod_adr[3], 0x08, func_id, tcp_seq, 0x00]) #bytearray für modbus/tcp Abfrage crc_req = 0xFFFF for x in range (0, 11): #Prüfsumme berechnen crc_req = crc16.calcByte( int.from_bytes(req[x:x+1], byteorder='big'), crc_req) req[11:13] = crc_req.to_bytes(2, byteorder='little') #Prüfsumme anhängen ack = bytearray([0x01, 0x64, mod_seq]) #bytearray für modbus Bestätigung crc_ack = 0xFFFF for x in range (0, 3): #Prüfsumme berechnen crc_ack = crc16.calcByte( int.from_bytes(ack[x:x+1], byteorder='big'), crc_ack) ack[3:5] = crc_ack.to_bytes(2, byteorder='little') #Prüfsumme anhängen while flag: #solange Abfrage nicht erfolgreich port.write(req) #Abfrage schicken ans = b'\x00' ans = port.read(20) #Antwort empfangen leng = int.from_bytes(ans[7:8], byteorder='big') #Länge des TCP Packets bestimmen crc_ans = 0xFFFF for x in range (0, leng+3): #Prüfsumme der Antwort berechnen crc_ans = crc16.calcByte( int.from_bytes(ans[x:x+1], byteorder='big'), crc_ans) if bytearray([0x01, 0x64, mod_seq, mod_adr[0], mod_adr[1], mod_adr[2], mod_adr[3]]) in ans[0:7]: #Antwort mit Abfrage vergleichen (Adresse) if (int.from_bytes(ans[leng+3:leng+5], byteorder='little')) == crc_ans: #Prüfsumme kontrollieren port.write(ack) #Bestätigung senden if leng > 8: #wenn Daten vorhanden val = int.from_bytes(ans[11:11+leng-8], byteorder='little') #Daten ausgeben return val else: return 0 flag = False else: flag = True #fehlerhafte Antwort, erneuter Versuch if __name__ == "__main__": #Hauptprogramm port = serial.Serial(port='/dev/ttyRPC0', baudrate=115200, timeout=2) #Port öffnen, 115200 Baud, 8N1 time.sleep(.1) mod_adr = bytearray([0x98, 0x83, 0x00, 0x00]) #Adresse des Brick/Bricklet mod_seq = 0x01 #Modbus sequence number tcp_seq = 0x01 #TCP sequence number func_id = 0x01 #Funktions ID value = get_value(port, mod_adr, mod_seq, tcp_seq,func_id) #Abfrage print ("Wert: %d\n" % value) #Wert ausgeben Verbesserungsvorschläge und Fragen sind natürlich wilkommen. Zitieren
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.