Ich habe ein Messgerät, dass allerlei hübsche Dinge messen kann, beispielsweise Stromstärke oder Spannung. Das Gerät kann über die serielle Schnittstelle an einen Computer angeschlossen werden.
Ziel der ganzen Aktion ist es, mit dem Gerät Messreihen aufzunehmen und sie auf dem Computer (zur weiteren Verarbeitung) zu speichern.
Das Problem ist nun, dass ich keine Ahnung habe, was das Gerät an die Schnittstelle sendet und in welcher Form. Wahrscheinlich sendet es permanent irgendetwas, man muss also wohl keine Anfragen schicken. Nun würde ich ganz gerne herausfinden, wie ich an meine schönen Messwerte komme.
Weiß irgendjemand, wie ich einfach alles, was der Computer über die serielle Schnittstelle empfängt, erstmal irgendwie aufzeichnen kann, um es auszuwerten? Ich hoffe, dass das irgendwelche Schlüsse darüber zulässt, was ich machen muss, um aus dem ganzen empfangenen Kram meine Messwerte herauszufiltern.
Ideal wäre ein Ansatz in PHP, aber eine C- oder Delphi-Lösung würde mir auch schon weiterhelfen. Betriebssystem ist Windows XP.
Wir hatten irgendwann mal nen Thread über selbstgebaute Roboter. Schau mal, ob da was brauchbares dabei war. Ansonsten könnt ich dir raussuchen, wie das in QBasic gehen würde, aber in C oder Delphi? Nicht mein Gebiet, tut mir leid. Und dass PHP sowas hat, bezweifel ich mal, aber vielleicht hast du ja Glück. Allerdings könnte ich mir vorstellen, dass die Schnittstelle unter Linux wie eine Datei angesprochen werden kann.
Wenn du mit PHP arbeiten willst, musst du dir wohl dein eigenes Modul fuer den Interpreter in c schreiben, um darauf zugreifen zu wollen.
Ich selber wuerde wohl als Schnittstelle etwas in Art von Plan 9 bauen; also mit Filediscreptoren arbeiten und mir einfach ein kleines C-Programm basteln, das eben den Windowshandler verwaltet. Alternativ kann man ueber PHP sicher auch noch Sockets auslesen.
Mit PHP wirst du aber generell nicht viel auswerten koennen, es sei denn du rufst das Script immer per Messinformation neu auf. Dafuer ist das ganze wirklich nicht geeignet. C/Cpp waere wohl optimal dafuer.
Wie du die RS232 ansprichst findest du eigentlich schnell unter google; aber da ich nicht genau weiss was du machen willst kann ich auch keine Sprache empfehlen. Fuer optische Auswertung waere z.B. Python sehr nett. HIer hilft die USPP weiter.
Mit PHP wirst du aber generell nicht viel auswerten koennen, es sei denn du rufst das Script immer per Messinformation neu auf. Dafuer ist das ganze wirklich nicht geeignet. C/Cpp waere wohl optimal dafuer.
...
Naja, wenn er 'ne permanente While-Schleife hat, die die Daten ausliest, dann geht da schon
was. Ich halte PHP hier allerdings für extrem unangebracht und würde eher auf Python, Perl
oder C zurückgreifen.
Mit wconsd (Directlink zum Download) kannst du die serielle Schnittstelle (unter Windows)
an einen Netzwerksocket binden, vllt. hilft dir das in irgendeiner Weise.
Ich weis nicht ob du unter Linux mit PHP das serielle Interface direkt auslesen kannst,
aber wie bereits gesagt, schätz ich mal, dass du ein eigenes Modul für PHP schreiben müsstest.
Naja, wenn er 'ne permanente While-Schleife hat, die die Daten ausliest, dann geht da schon
was. Ich halte PHP hier allerdings für extrem unangebracht und würde eher auf Python, Perl
oder C zurückgreifen.
Mit wconsd (Directlink zum Download) kannst du die serielle Schnittstelle (unter Windows)
an einen Netzwerksocket binden, vllt. hilft dir das in irgendeiner Weise.
Ich weis nicht ob du unter Linux mit PHP das serielle Interface direkt auslesen kannst,
aber wie bereits gesagt, schätz ich mal, dass du ein eigenes Modul für PHP schreiben müsstest.
...
Insofern PHP ihrem Einsatzort gerecht werden mag, waere ein Script immer von einer angemessenen Timeout-Zeit beschraenkt.
Danke, die Vorschläge klingen ganz brauchbar (wenn auch nach viel Arbeit ;_;).
Ich habe gestern entdeckt, dass es bei Assembler mit dem Interrupt 14h möglich ist, direkt auf die serielle Schnittstelle zuzugreifen. Ich habe, um das erstmal auszuprobieren, folgendes Programm geschrieben:
Das Programm soll ein Zeichen (8 Bit) aus der seriellen Schnittstelle (in diesem Fall COM1) auslesen (landet in AL), das Zeichen unter der Variablen "signal" speichern und diese dann ausgeben.
Weil ich an diesem Computer keine seriellen Schnittstellen habe, habe ich es am Computer meiner Eltern probelaufen lassen. Allerdings wurde nicht wie erwartet ein Zeichen ausgegeben (schließlich habe ich "signal" ja nur den 8 Bit großen Inhalt von AL übergeben), sondern mehrere Zeilen wilder ASCII-Zeichen.
Als ich das Programm mit DEBUG Schritt für Schritt ausgeführt habe, habe ich allerdings andere Zeichen ausgegeben bekommen, darunter sogar ein wenig Klartext, der mir verriet, dass der COM-Port bereit ist.
Kennt sich vielleicht jemand etwas besser mit Assembler aus und kann mir sagen, wo diese ganzen ASCII-Zeichen herkommen? (Eigentlich wollte ich ja zunächst nur ein einzelnes Zeichen empfangen.)
Hm, TASM. Also INT 21h mit AH=9 gibt eine $-terminierte Zeichenkette aus (also werden solange Zeichen ausgegeben, bis im Speicher ein $ steht). Zum Ausgeben eines einzelnen Zeichens sollte AH auf 2 gesetzt werden und das Zeichen muss sich in DL befinden. Also etwa so:
Ob du das Gerät richtig ansprichst, kann ich dir aufgrund mangelnder Produktinformationen aber nicht sagen. Eventuell solltest du aber überprüfen, ob die Schnittstelle erfolgreich initialisiert wurde.
Ganz generell wuerde ich dir empfehlen mit NASM zu assemblieren und den weltweiten Pseudostandart zu verwenden.
Sonst ist es btw doch etwas uebertrieben fuer soetwas ASM zu benuetzen. Such dir lieber einen C-Codefetzen der ueber die API den Port anspricht. So wird es auch fuer dich verstaendlicher, denke ich. Mit Hochsprachen scheinst du ja besser vertraut zu sein.
So, da es eine Gruppenarbeit ist und sich jeder um einen anderen Ansatz zum Auslesen der seriellen Schnittstelle kümmert (damit wir am Ende ein möglichst breites Spektrum an Möglichkeiten zumindest untersucht haben), arbeite ich trotz der gut gemeinten Ratschläge, das Problem mit einer höheren Sprache zu lösen, vorerst weiter mit Assembler (Aber zumindest den vorgeschlagenen Netwide Assembler).
Ich habe dieses Programm geschrieben:Es überprüft, ob an der seriellen Schnittstelle Daten vorhanden sind und gibt sie aus. Wenn keine Daten vorhanden sind, wird der "D"-Befehl an das Gerät geschickt, der nach dem >> Informationsblatt des Gerätes (PDF, ~600 kB), (siehe Seite 3) die Datenübertragung aktivieren soll.
Allerdings werden neben dem Status der seriellen Schnittstelle keine Daten ausgegeben, sondern nur "D"s, bzw, wie ich inzwischen herausgefunden habe, das, was gerade im AL-Register (und damit wegen einer Zuweisung in der Variable "zeichen") steht, in ASCII. Dabei sollte die Funktion "zeichen_empfangen" eigentlich das an der Schnittstelle vorhandene Zeichen in AL speichern (siehe >> Interrupt 14).
Ist das Gerät kaputt (die Anzeige am Gerät selber funktioniert noch problemlos und richtig, es ist eben nur ein bischen älter) oder habe ich irgendetwas falsch gemacht?
Nun habe ich mich 10 Minuten lang darüber geärgert, dass das Programm nicht funktioniert, bis mir einfiel, dass ich an diesem Computer gar keinen COM-Port habe. -_-
Naja, das Messgerät ist leider Eigentum der Schule, wo es aus diesem Grund auch momentan steht, aber ich werde das Programm Montag in einer Freistunde mal ausprobieren, um zu sehen, ob das Gerät überhaupt funktioniert. Danke für den Link.
Um mich etwas genauer mit der Funktionsweise der seriellen Schnittstelle zu beschäftigen und mir nicht bloß von Microsoft und ihrem Interrupt 14h den Arsch hinterhertragen zu lassen habe ich versucht, die serielle Schnittstelle mit einer Anleitung aus dem Internet selber zu initialisieren. Allerdings habe ich Probleme mit einem Assembler-Befehl. Es geht um out.
Die allgemeine Syntax lautet:Kann mir jemand Folgendes erklären:Sowohl AL als auch AH sind doch 8-Bit-Register, warum verhalten sie sich dann an dieser Stelle unterschiedlich?
Damit kann ich allerdings noch leben. Was mir merkwürdig vorkommt ist allerdings, dass folgende Syntax des out-Befehls einen Fehler verursacht:
Out akzeptiert als zweiten Operanden prinzipiell nur al. Das hat vermutlich intern einige Vorteile und man muss sich einfach daran halten. Die Adresse darf, soweit ich weiß, bis 255 als Direktwert angegeben werden. Danach sollte man dafür das dx Register nutzen und und keine Variable.
Danke, das erwähnen viele Quellen, die ich im Internet gefunden habe, gar nicht.
[FONT="Courier New"]out [com1], whatever[/FONT] wäre so schön anschaulich gewesen. Dadurch, dass ich nun vorher den zu versendenden Wert an AL und die Port-Adresse an DX senden muss, verdreifacht sich die Schreibarbeit und der Quelltext wird recht unübersichtlich, aber dagegen lässt sich wohl nicht viel machen.
Gibt es eigentlich irgendeine Möglichkeit, einen Timer unter Assembler einzusetzen? Ich würde die Schleife, die auf Daten von dem Gerät wartet, ganz gerne unterbrechen, wenn nach beispielsweise 2 Sekunden noch keine Daten gesendet worden sind.
Gibt es eigentlich irgendeine Möglichkeit, einen Timer unter Assembler einzusetzen? Ich würde die Schleife, die auf Daten von dem Gerät wartet, ganz gerne unterbrechen, wenn nach beispielsweise 2 Sekunden noch keine Daten gesendet worden sind.
...
Du könntest dir ja selbst einen kleinen Timer schreiben. Wie man die Uhrzeit ausliest etc. dürfte man mit Google schnell finden. Oder du nutzt einen fertigen, wie zum Beispiel den Timer der WinAPI. Am einfachsten wäre es aber, eine Schleife zu schreiben, die immer überprüft, ob ein neues Zeichen da ist, und nur dann vom Port liest, wenn ein neue Wert vorhanden ist.
Am einfachsten wäre es aber, eine Schleife zu schreiben, die immer überprüft, ob ein neues Zeichen da ist, und nur dann vom Port liest, wenn ein neue Wert vorhanden ist.
...
Das habe ich ja getan. Die Schleife bricht im Moment nur dann ab, wenn 14 Bytes von dem Gerät empfangen wurden (14 hängt mit dem Datenformat des Multimeters zusammen). Aber es kann ja auch vorkommen, dass das Gerät aus irgendeinem Grund nichts sendet, dann muss die Schleife nach einer gewissen Zeit auch abgebrochen und eine Fehlermeldung ausgegeben werden. Dafür brauche ich den Timer.
Naja, ich werde einfach mal suchen, dafür gibt es sicher fertige DOS-Interrupts, die man aufrufen kann. Aber nicht mehr heute. ^^
Ich habe das von Crash-Override gepostete Programm mal ausprobiert und festgestellt, dass das Gerät funktioniert. Man sendet ein großes "D" und das Gerät gibt die derzeitige Messwertanzeige zurück.
Mein Programm funktioniert allerdings nicht, es gibt nichts aus und wird einfach kurz nach dem Start beendet (nichteinmal eine halbe Sekunde). Ich habe keine Ahnung, wo der Fehler liegt.
Die Empfangsschleife wird mehrfach durchlaufen, dass habe ich schon überprüft. Genaueres kann ich nicht sagen, da das Gerät in der Schule steht und ich es hier (zuhause) nicht testen kann.
Nachtrag:
Ok, ich habe bei der Initialisierung vergessen, die Interrupts richtig einzustellen, das habe ich jetzt geändert (allerdings nicht im obigen Quelltext). Ich werde es morgen erstmal ausprobieren.
Nachtrag #2:
Es hat zwar noch nicht funktioniert, aber ich bin auf dem richtigen Weg. ^^
Ich habe jetzt verschiedene Fehler beseitigt, aber das Programm läuft immernoch nicht. Irgendwas stimmt noch nicht. Ich überprüfe im Programm den Status der seriellen Schnittstelle und bekomme einen Apostroph raus (ASCII-Codierung des Statusbytes). Allerdings gibt es im ASCII-Zeichensatz 4 oder 5 verschiedene Apostrophen, die in meinen Augen alle relativ gleich aussehen, aber eben durch unterschiedliche Bitkombinationen codiert werden. Weiß zufällig jemand, wie ich die einzelnen Bits eines Bytes direkt ausgeben kann?
Ja, ich bin tatsächlich skrupellos genug für einen tripple post.
Nachtrag:
Oh, vergesst es, ist nicht so wichtig. 3 der 5 möglichen Zeichen fallen raus, weil das höchste Bit, das eigentlich immer 0 ist, dann 1 sein müsste. Es gibt also noch zwei mögliche Statusmöglichkeiten:
00100111 >> Daten vorhanden, Überlauf, Paritätsfehler, Senderegister enthält noch Daten
01100000 >> Senderegister enthält noch Daten / sendet gerade Daten