assassin Geschrieben February 16, 2016 at 13:52 Share Geschrieben February 16, 2016 at 13:52 Hallo, ich versuche mit Python über das RS232 Bricklet einen MFC der Firma Bronkhorst anzusprechen. Nach längerem probieren, lesen und basteln habe ich das Kabel korrekt belegt und die ersten Tests gemacht. Wenn ich im BrickViewer den Sollwert als ASCII String anfrage (':06030401210120\r\n') erhalte ich im BrickViewer die korrekte Antwort (':06030201210000\r\n'). Wenn ich das Loopback Beispiel aus der Dokumentation des Bricklets anpasse, wird der String korrekt geschrieben und ich sehe im BrickViewer die korrekte Antwort. Wenn ich die Antwort über Python lesen möchte, erhalte ich ich allerdings immer zwei Antworten: (':', '0', '6', '0', '3', '0', '2', '0', '1', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00') ('2', '1', '0', '0', '0', '0', '\r', '\n', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00') Im BrickViewer kommt wiederum die korrekte Antwort als ganzes an. Der BrickViewer selbst ist auch in Python geschrieben, allerdings passt die Lese-Funktion dort nicht zu meinem Problem, da hier ein Schneiden bei '\r\n' in der Mitte abgefangen wird. Ich vermute so etwas wie ein Timing Problem, wäre aber für Anregungen sehr dankbar. Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
Doncarlos Geschrieben February 16, 2016 at 14:14 Share Geschrieben February 16, 2016 at 14:14 Hi, Wenn ich es richtig verstanden habe, dann kommt ja grundsätzlich die richtige Antwort an, nur die "'\x00'" stören dich ? Beachte bitte den Längen Parameter der zum Char Array mitgeliefert wird. Nur bis dahin ist das Array sinnvoll gefüllt. '\x00' bedeutet einfach nur null, nichts... ignorieren. hth Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
assassin Geschrieben February 16, 2016 at 14:17 Autor Share Geschrieben February 16, 2016 at 14:17 Hallo, ich habe den Post oben nochmal geändert. Die Korrekte Meldung wird in zwei Strings geschnitten. Die Länge des "gesuchten" Strings ist 17 und mal wird in 9 und 8 und mal in 10 uns 7 geschnitten. Ich erhalte immer zwei Antworten aus dem Callback obwohl es nur eine sein dürfte. Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
photron Geschrieben February 16, 2016 at 15:09 Share Geschrieben February 16, 2016 at 15:09 Auch im Brick Viewer wird die Antwort in zwei Teile ankommen. Die beiden Teile werden aber so schnell hintereinander ankommen, dass es so aussieht als würden sie in einem Stück ankommen. RS232 ist streamorientiert, nicht paketorientiert. Es wäre auch okay, wenn die Daten Byteweise geliefert würden. Du musst einfach genauso wie Brick Viewer alle eingehenden Daten aneinanderhängen, um den Datenstrom zu rekonstruieren. Dann kannst du wie Brick Viewer den Datenstrom anhand der \r\n in die einzelnen Nachrichten zerlegen. class Reader(object): def __init__(self): self.data = '' def cb_read(self, message, length) self.data += ''.join(message[:length]) def get_next_message(self): i = self.data.find('\r\n') if i < 0: return None else: message = self.data[:i] self.data = self.data[i + 2:] return message Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
assassin Geschrieben February 17, 2016 at 13:49 Autor Share Geschrieben February 17, 2016 at 13:49 Hallo, vom Prinzip her verstehe ich was du meinst. Da ich aber noch nicht mit Klassen gearbeitet habe, weiss ich nicht wie ich es umsetzen soll. Ich habe den Beispiel-Code von der TF-Seite nur minimal geändert. Ohne deinen Tipp bekomme ich immer noch reproduzierbar zwei getrennte Antworten. Wie kann ich deinen Vorschlag integrieren? Schöne Grüße und ich bin dankbar für jede Anregung... #!/usr/bin/env python # -*- coding: utf-8 -*- HOST = "localhost" PORT = 4223 UID = "uVr" # Change to your UID from tinkerforge.ip_connection import IPConnection from tinkerforge.bricklet_rs232 import BrickletRS232 # For this example connect the RX1 and TX pin to receive the send message # Convert string to char array with length 60, as needed by write def string_to_char_list(message): chars = list(message) chars.extend(['\0']*(60 - len(message))) return chars, len(message) # Assume that the message consists of ASCII characters and # convert it from an array of chars to a string def char_list_to_string(message, length): return ''.join(message[:length]) # Callback function for read callback def cb_read(message, length): s = char_list_to_string(message, length) print('Message (length: ' + str(length) + '): "' + s + '"') if __name__ == "__main__": ipcon = IPConnection() # Create IP connection rs232 = BrickletRS232(UID, ipcon) # Create device object ipcon.connect(HOST, PORT) # Connect to brickd # Don't use device before ipcon is connected rs232.set_configuration(9, 0, 1, 8, 0, 0) # Register read callback to function cb_read rs232.register_callback(rs232.CALLBACK_READ_CALLBACK, cb_read) # Enable read callback rs232.enable_read_callback() # Write "test" string rs232.write(*string_to_char_list(':06030401210120\r\n')) raw_input("Press key to exit\n") # Use input() in Python 3 ipcon.disconnect() Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
photron Geschrieben February 17, 2016 at 14:05 Share Geschrieben February 17, 2016 at 14:05 Hier die Funktion der Read Klasse ohne Klasse. Dazu ersetzt du in deinem Beispiel die cb_read Funktion durch diese Version: buffer = '' # Global buffer to collect all incoming data # Callback function for read callback def cb_read(message, length): s = char_list_to_string(message, length) # Append new data to global buffer global buffer buffer += s # Check if global buffer contains a complete response i = buffer.find('\r\n') if i >= 0: # Get response (without \r\n) from buffer response = buffer[:i] # Remove response (with \r\n) from buffer buffer = buffer[i + 2:] # Print response print('Response: ' + response) Im Read Callback kommen die Daten immer noch stückweise an, daran ändert sich nichts. Der Code nutzt jetzt aber einen globalen Buffer in dem alle eingehenden Stück gesammelt werden. Dann wird in den Buffer geschaut, ob eine komplette Antwort (endet mit \r\n) im Buffer zusammen gesammelt wurde. Wenn ja wird sie aus dem Buffer entfernt und ausgegeben. Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
assassin Geschrieben February 17, 2016 at 14:13 Autor Share Geschrieben February 17, 2016 at 14:13 Hallo, klappt prima. Muss jetzt den Code noch verstehen, habe es zunächst ohne zu denken getestet. Danke! Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
Nic Geschrieben February 18, 2016 at 08:46 Share Geschrieben February 18, 2016 at 08:46 Wenn jetzt alles prima läuft, kannst du uns etwas über das MFC sagen, ich vermute es ist diesmal nicht die Microsoft Foundation Classes Ich bekomme immer allergische Reaktionen in meinen Gehirnzellen wenn da mit Fachausdrücken hantiert wird, wo man sich erstmal nix vorstellen kann. Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
assassin Geschrieben February 18, 2016 at 09:10 Autor Share Geschrieben February 18, 2016 at 09:10 Hallo, das mit den allergischen Reaktionen verstehe ich, ich kann da gerne aufklären. Es handelt sich um einen Mass Flow Controller (MFC), im Prinzip ein elektrisches Stellventil für Gasflüsse. Die Steuerung über RS232 ist meiner Meinung nach die preiswerteste (nicht die einfachste) Methode, da man so nur die Spannungsversorgung des Geräts plus die RS232 benötigt. Die Alternative wäre den analogen Ein- bzw. Ausgang des Gerätes plus die Spannungsversorgung zu nutzen. Das ist im Prinzip einfacher, benötigt aber eine Schnittstelle pro Regelgerät mehr. Daher versuche ich mein Glück über die serielle Schnittstelle. Schöne Grüße... Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
Nic Geschrieben February 18, 2016 at 11:37 Share Geschrieben February 18, 2016 at 11:37 Besten Dank. Immer wieder erstaunlich wie lange sich die RS232 schon hält. Ist das Projekt im industriellen Bereich oder mehr privater Natur ? Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
assassin Geschrieben February 18, 2016 at 11:38 Autor Share Geschrieben February 18, 2016 at 11:38 Universität, Labor... Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
buntstifte Geschrieben October 11, 2017 at 12:09 Share Geschrieben October 11, 2017 at 12:09 Hallo assassin, ich habe ein Projekt, wobei der MFC IQFlow der Bronkhorst über RS232 von einem Programm gesteuert, geregelt werden soll. Das Programm habe ich nicht mit Python sondern C#/WPF unter Windows 10 selbst geschrieben. Nachrichten-Senden & Empfängen habe ich mit Putty getestet. Das läuft sehr gut. Zum Test der Kommunikation mit dem MFC habe ich versucht, erstmal eine Anfrage an ihn zuzusenden, also dataWrite(":06030401210120\r\n"), dann Codebefehle als Beispiele aus 919027-Benutzer-Handbuch RS232 Schnittstellen. Leider antwortet er immer noch nicht. Ich kriege gar nichts hin. Die Kabeln, die ich verwende, habe alle von Bronkhorst gekauft und mit Bronkhorst-Programmen wie FlowDDE, FlowView getestet. Es funktionieren einwandfrei. Ich habe versucht die Hilfe/Infos über RS232-Kommunikation mit Bronkhorst MFC von einem selbstgeschrieben Programm im Net zu recherchieren und nur hier gefunden. Meine Frage ist, was oder wie man wieder testen/machen sollte? Ich vermute man muss erst davor irgendwas machen, bevor man z.B. eine Anfrage zum Soll-Wert zuschickt. Es wäre für Anregungen sehr dankbar. Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
photron Geschrieben October 11, 2017 at 16:07 Share Geschrieben October 11, 2017 at 16:07 buntstifte, es funktioniert also mit Putty aber nicht mit deinem eigenen Programm? Dann muss es ja an deinem eigenen Programm liegen. Öffnest du in deinem Programm die richtige serielle Schnittstelle, stellst du die Baudrate, Parität und Stopbits richtig ein? Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
buntstifte Geschrieben October 12, 2017 at 09:27 Share Geschrieben October 12, 2017 at 09:27 Hallo photron, vielen Dank für deinen Tipp. Die Einstellung/Einrichtung der RS232-Kommunikation mit dem MFC hatte ich genau wie Bronkhorst beschrieben programmiert: "Die Kommunikationseinstellungen sind: 38400,n,8,1" Mein eigenes Programm kann gut mit Putty und einer Serial-COM UWP-App bei dieser Einstellung kommunizieren, also Nachrichten erfolgreich gesendet und empfängt. Gestern habe ich eine sehr alte Dokumentation der Bronkhorst '2007-09-12-Hyperterminal-RS232-Example' gefunden und gelesen. Es wird gesagt "At power up of the MFC the MFC sends an identification string to the RS232 port". Ich kriege das nicht hin. Ich habe dann versucht per Hyperterminal und Putty eine Anfrage an seine Capacity ":060304014D014D\r\n" an ihn zuzuschicken. Die Antwort war ":0104". Per mein Programm kam aber gar nichts zurück, also kein ":0104". Eine Suche was ":0104" bedeutet hatte kein Erfolg. Es wäre für Anregungen sehr dankbar. Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
FlyingDoc Geschrieben October 12, 2017 at 11:44 Share Geschrieben October 12, 2017 at 11:44 Hast du die Firmware des Master und des RS232 Bricklet auf dem.aktuellem Stand. Das gab es mal Probleme, die inzwischen gelöst sind. Dabei wurden die Schnittstellenparameter nicht übernommen. Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
buntstifte Geschrieben October 16, 2017 at 07:18 Share Geschrieben October 16, 2017 at 07:18 Hallo FlyingDoc, vielen Dank. Sorry habe ich noch nie gesagt, dass ich kein RS232 Bricklet sondern einen anderen USB-Serial-Adapter verwendet. Alles (MFC, Bronkhorst-Kabel und der Adapter) funktioniert doch gut im Test mit den Programmen von Bronkhorst wie FlowDDE, FlowView. Aber mit meinem eigenen C#-Programm geht es leider noch immer nicht. Wie gesagt, ich habe das Thema 'direkt Kommunikation/Steuerung eines Bronkhorst-MFC über RS232' nur da im 4rum gefunden. Daher hätte ich gern die Hilfe von assassin, weil er schon mal mit diesem MFC gearbeitet hat, also mit dem MFC über RS232 direkt kommuniziert. Wie er schrittweise für den/die Direkt-Kommunikationsaufbau und -steuerung über RS232 gemacht hat, würde ich sehr gern wissen. Schöne Grüße Zitieren Link zu diesem Kommentar Share on other sites More sharing options...
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.