|
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
sowerum
Anmeldungsdatum: 05.05.2015 Beiträge: 7
|
Verfasst am: 05.05.2015, 16:25 Titel: serielle Schnittstelle lesen |
|
|
Hallo liebe FreeBasic-Kenner,
nach einem frustrierenden Versuch mit Visual Basic versuche ich jetzt meine selbstgebaute Wetterstation mit FreeBasic auszulesen.
Die Werte der Sensoren werden von einem Atmega8 auf eine serielle Schnittstelle gesendet. Das funktioniert auch. ein Terminalprogramm empfängt diese Zeichenfolge: A0012163521872171770
Ich krieg es einfach nicht hin, die Schnittstelle mit freeBasic zu lesen. Die beiden folgenden Alternativen funktionieren nicht.
DIM dat as string
OPEN COM "COM1:4800,N,8,1" for input aS #2
dat = ""
do
dat = input(20,#2)
print dat
loop
alternativ:
DIM dat as string
OPEN COM "COM1:4800,N,8,1" for input aS #2
dat = ""
do
input #2, dat
print dat
loop
Die Befehlsreferenzliste, diese Forum und Google konnten mir nicht weiterhelfen. Eigentlich ist das doch eine Standardaufgabe.
Hat jemand für mich den entscheidenden Tip? |
|
Nach oben |
|
|
Sebastian Administrator
Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
Verfasst am: 05.05.2015, 20:48 Titel: OPEN COM in FreeBASIC |
|
|
Hallo und willkommen im Forum!
Die Kombination aus ATMega, MAX232, COM-Port und FreeBASIC habe ich selber schon benutzt. Das geht.
Schau dir vielleicht mal diesen Thread hier an:
http://forum.qbasic.at/viewtopic.php?t=7405
... und im Speziellen das Posting hier, wo im Dauerbetrieb Daten eingelesen werden:
http://forum.qbasic.at/viewtopic.php?p=95177#95177
Da der Code damals für eine spezielle Frage gemacht war, kann man nur ein immer gleiches Byte an den Mikrocontroller senden: Wenn man die 1 auf der Tastatur drückt, wird eine "1" an den COM-Port bzw. Mikrocontroller geschickt. Den Teil könnte man natürlich beliebig ausbauen und auch andere Kommandos schicken.
Durch Tastendruck auf ESC wird die Schleife beendet.
Der Beispielcode aus dem Posting müsste da eingesetzt werden, wo hier die "..." sind:
http://forum.qbasic.at/viewtopic.php?p=95170#95170
Das CLOSE muss am Ende natürlich nur 1x gemacht werden.
Das hier
Code: | Const COMPort = "COM1:9600,N,8,1,ME,CS0,DS0,RS" |
könnte in deinem Fall vielleicht so aussehen:
Code: | Const COMPort = "COM1:4800,N,8,1,ME,CS0,DS0,RS" |
Viele Grüße!
Sebastian _________________
Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen! |
|
Nach oben |
|
|
sowerum
Anmeldungsdatum: 05.05.2015 Beiträge: 7
|
Verfasst am: 05.05.2015, 21:12 Titel: |
|
|
Danke, Sebastian, für deine Antwort.
Morgen werde ich mal testen, ob der Comport überhaupt geöffnet wird, mit:
If (Open Com ( COMPort For Binary As #1 ) <> 0 ) Then
Print "Fehler: Der Port konnte nicht geoeffnet werden!"
wie in einem deiner Hinweise steht.
Die Zeile:
If Loc(1) > 0 Then ....; bei mir "Loc(2)"
hatte ich schon mal eingebaut, Loc(2) ergab immer "0".
Sind die Parameter "ME,CS0,DS0,RS" eigentlich wichtig? In der Befehlsreferenz bei "open com..." sind sie zwar aufgeführt, aber im Beispielcode nicht verwendet.
Ist mein Lesebefehl "input #2, dat" resp. "dat = input(20,#2)" so eigentlich richtig angewendet. In einem thread, auf den du verweist, wird mit "Get #1.." gelesen. Wird mit "Get.." nicht ein einzelnes Byte gelesen? Ich möchte einen String lesen mit 20 Zeichen. |
|
Nach oben |
|
|
Sebastian Administrator
Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
Verfasst am: 05.05.2015, 23:17 Titel: |
|
|
sowerum hat Folgendes geschrieben: | Sind die Parameter "ME,CS0,DS0,RS" eigentlich wichtig? In der Befehlsreferenz bei "open com..." sind sie zwar aufgeführt, aber im Beispielcode nicht verwendet. |
Das kommt natürlich immer darauf an, was für ein Gerät man am COM-Port anschließt und was für ein "Protokoll" davon benutzt wird. Im Endeffekt muss man das im technischen Handbuch des Geräts (Modem, Barcodescanner, Messgerät, ...) nachschauen, welche Schnittstellenkonfiguration erwartet wird. Wenn man die angeschlossene Schaltung selber gebaut hat, kann man es selber gestalten und auch kompliziert machen.
Ich vermute mal, du hast einfach nur TX, RX und GND beschaltet und benutzt keine hardware-basierte "Flow Control"? In dem Fall sollen beide Seiten einfach senden, egal, ob die Gegenstelle Bereitschaft signalisiert bzw. das überhaupt kann. Dann kann man die ganze "Koordinationsthematik" mit "CS0,DS0,CD0" abschalten. Und ME weist FreeBASIC an, über Fehlerzustände möglichst hinwegzugehen und die Schnittstelle trotzdem zum Senden zu benutzen.
sowerum hat Folgendes geschrieben: | Ist mein Lesebefehl "input #2, dat" resp. "dat = input(20,#2)" so eigentlich richtig angewendet. In einem thread, auf den du verweist, wird mit "Get #1.." gelesen. Wird mit "Get.." nicht ein einzelnes Byte gelesen? Ich möchte einen String lesen mit 20 Zeichen. |
Wenn du den COM-Port unter dem Filehandle #1 geöffnet hast (mit OPEN COM), kannst du mit LOC(1) feststellen, wie viele Bytes im Empfangspuffer vorliegen.
Code: | If Loc(1) > 0 Then
Puffer = Space(Loc(1)) 'Puffergroesse entsprechend festlegen
Get #1, , Puffer
Print "--> " & Puffer
End If |
Mit der Zeile
Code: | Puffer = Space(Loc(1)) |
wird ein String erzeugt, der genau so lang ist wie die Daten, die unter dem Filehandle #1 abholbereit sind. Anschließend werden die Bytes mit
eingelesen. Dabei werden bis zu so viele Bytes gelesen, wie der String Puffer lang ist.
Achtung: Wenn du das Filehandle mit OPEN COM unter einer anderen Nummer als 1 geöffnet hast (z. B. 2), dann liefert LOC(1) natürlich keine Werte.
Wenn dein Mikrocontroller laufend sendet, wirst du wahrscheinlich keine Datenpakete von immer exakt 20 Zeichen hereinbekommen, die genau da anfangen und aufhören, wo es fachlich sinnvoll wäre. Sondern manchmal werden vermutlich unvollständige Pakete eingehen und der Rest des Pakets steckt dann in der nächsten Fuhre an Zeichen.
Bsp: Dein Controller sendet die Folge:
Code: | A023834093B023477292C834834920D982338340E093458953 |
Dann bekommst du vermutlich nicht 5x einen Puffer mit jeweils 10 Zeichen herein, also so:
Code: | A023834093
B023477292
C834834920
D982338340
E093458953 |
sondern vielleicht alles in einem Stück oder in solchen Portionen hier:
Code: | A023834093B0234772
92
C83483492
0D982338340E09
3458953 |
Von daher ist es vermutlich nicht sinnvoll, immer eine feste Pufferlänge zu erwarten.
Eine einfache Möglichkeit, damit umzugehen, könnte sein, mit jeder Nachricht einen kleinen Header mit Startzeichen zu schicken. Das Startzeichen darf dann nicht in den eigentlichen Daten ("Payload") vorkommen. Wenn deine Daten alphanumerisch sind, könntest du z. B. eine Raute nehmen oder sowas. Nach dem Startzeichen sendest du, wenn die Nachrichten unterschiedlich lang sein können, ein Byte, das die Länge des Payloads angibt (z. B. falls bei Regen mehr Daten gesendet werden müssen, als wenn die Sonne scheint). Dann könnte man ungefähr so vorgehen:
Man fängt mit einem leeren Stringpuffer ("") an. In einer Endlosschleife wartet man darauf, dass LOC(1) größer 0 wird. Sobald das passiert, liest man ein einzelnes Byte ein. Ist dieses Byte gleich dem Startzeichen (z. B. "#"), wird der Puffer geleert und man setzt sich ein Flag, dass jetzt als nächstes ein UByte (vorzeichenloser 8-Bit-Wert, also 0 bis 255) erwartet wird, was die Länge des Temperaturdatensatzes angibt ("Warte auf Längenangabe"). Das nächste ankommende Byte wird also als Soll-Länge benutzt, nennen wir sie S. Man setzt das Flag vom Status "Warte auf Längenangabe" auf "Warte auf Übermittlung der Nachricht". In dem Moment weiß man, dass man jetzt den Empfang von S Bytes (ggf. in mehreren "Fuhren") abwarten muss. Immer, wenn ein Byte eingeht, wird es dem Puffer hinten angehängt (Puffer = Puffer + CHR(EinzelnesByte)). (Man kann z. B. auch einen Timeout einbauen: Wenn die S Bytes (z. B. 20 oder 100 Bytes) nicht innerhalb von 30 Sekunden vollständig eingegangen sind, wird die halb-empfangene Nachricht verworfen (Timeout).) Sobald man die Soll-Datenlänge von S Bytes empfangen und in den Stringpuffer eingefügt hat, wird der Puffer als fertiges Datenpaket an eine SUB o. ä. übergeben, die die Nachricht verarbeitet, und das Prozedere geht für die nächste Nachricht von vorne los. _________________
Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen! |
|
Nach oben |
|
|
sowerum
Anmeldungsdatum: 05.05.2015 Beiträge: 7
|
Verfasst am: 06.05.2015, 11:16 Titel: |
|
|
So, ich hab jetzt mal mit:
OPEN COM "COM1:4800,N,8,1" for input aS #1
If (Open Com ( "COM1:4800,N,8,1" For Binary As #1 ) <> 0 ) Then
Print "Fehler: Der Port konnte nicht geoeffnet werden!"
End If
das Öffnen der Schnittstelle überprüft. Die Schnittstelle kann nicht geöffnet werden!
Um auszuschließen, dass sie schon aus irgendeinem Grund vorher geöffnet war, hab ich auch mal "close #" davorgesetzt. - kein Erfolg. Wie schon oben geschrieben: ein fremdes Terminalprogramm liest einwandfrei. Die Schnittstelle ist keine umgesetzte USB-Schnittstelle.
Die Zusatzparameter ",ME,CS0,DS0,RS" bewirken übrigens, dass die Schnittstelle viel schneller angesprochen wird, auf das korrekte Öffnen haben sie keinen Einfluss.
An das Problem, dass der empfangene String an der richtigen Stelle beginnt und endet habe ich schon gedacht. Der Messwertgeber sendet nur Ziffern. Der Buchstabe "A" in meinem Beispiel wird vom Sender künstlich erzeugt, um den Beginn der echten Daten zu markieren und muss nachher ausgefiltert werden.
Aber erstmal muss die Schnittstelle überhaupt mal funktionieren. |
|
Nach oben |
|
|
RockTheSchock
Anmeldungsdatum: 04.04.2007 Beiträge: 138
|
Verfasst am: 06.05.2015, 11:27 Titel: |
|
|
Ich glaube damit der Freebasic Treiber für die Serielle / Parallele Schnittstelle Funktioniert muss einmalig das Programm mit Administratorrechten gestartet werden. |
|
Nach oben |
|
|
sowerum
Anmeldungsdatum: 05.05.2015 Beiträge: 7
|
Verfasst am: 06.05.2015, 11:34 Titel: |
|
|
Hallo RockTheSchock,
wie soll ich das verstehen?
Ich hab mal das Programm kompiliert und dann mit rechtsklick "als Administrator ausführen" ausgewählt. Das hatte keinen erfolg.
Ach ja - ich benutze Windows 7 professional. |
|
Nach oben |
|
|
Sebastian Administrator
Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
Verfasst am: 06.05.2015, 12:21 Titel: |
|
|
Wenn du das genau so innerhalb 1 Programms hattest,
Zitat: | Code: | OPEN COM "COM1:4800,N,8,1" for input aS #1
If (Open Com ( "COM1:4800,N,8,1" For Binary As #1 ) <> 0 ) Then
Print "Fehler: Der Port konnte nicht geoeffnet werden!"
End If |
|
kann es nicht funktionieren. Du öffnest da den Port zuerst im falschen Modus und versuchst dann direkt in der nächsten Zeile, ihn im "Raw"-Binärmodus noch mal zu öffnen. Das schlägt einerseits fehl, weil das Dateihandle #1 schon vergeben war (an die INPUT-Öffnung) und weil der COM-Port, falls er ihn aufgemacht hat, dann ja auch schon geöffnet war.
Hast du es denn schon mal mit einem Code versucht, der möglichst nahe an den geposteten Beispielcodes ist?
sowerum hat Folgendes geschrieben: | Ich hab mal das Programm kompiliert und dann mit rechtsklick "als Administrator ausführen" ausgewählt. |
Ja, das meinte er.
Versuch vielleicht mal die Zeile hier mit dem Beispiel-Grundgerüst:
Code: | Const COMPort = "COM1:4800,N,8,1,ME,CS0,DS0,CD0,RS" |
Bei dem FreeBASIC-OPEN-COM-String muss man im Vergleich zu Terminalprogrammen ein bisschen umdenken. Bei denen kann man viele Dinge über Auswahlfelder konfigurieren. Bei FreeBASIC muss jedes Konfigurationsdetail über diesen String geliefert werden.
Schau mal z. B. hier bei HyperTerminal:
Die Auswahl am Ende bei "Protokoll". Da geht es um die Flusssteuerung. Wenn du bei deiner Schaltung nur 3 Leitungen der Schnittstelle verbunden hast (TX, RX und GND), hast du keine hardwarebasierte Flusssteuerung, für die es ja die Ein-/Ausgänge zusätzlich zu den Datenleitungen braucht. Wird sie trotzdem verwendet, funktioniert es nicht. Xon/Xoff verwendest du softwareseitig wahrscheinlich auch nicht, würde ich vermuten? Um FreeBASIC klar zu machen, dass du die Einstellung "Kein" (vgl. 2. Screenshot) willst, brauchst du die zusätzlichen Angaben.
Ganz wichtig ist natürlich auch, dass die Port-Nummer stimmt. Gerade irgendwelche USB->RS232-Konverter erzeugen in der Regel nicht einfach COM1 sondern COM9 oder sowas. Ich habe allerdings auch schon mitbekommen, dass es mit solchen USB-Konvertern öfters mal Schwierigkeiten gibt. Da ist es dann besser, ggf. ein paar COM-Ports per PCI-Express-Steckkarte nachzurüsten. _________________
Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen! |
|
Nach oben |
|
|
sowerum
Anmeldungsdatum: 05.05.2015 Beiträge: 7
|
Verfasst am: 06.05.2015, 12:58 Titel: |
|
|
Dieser Code bringt keine Fehlermeldung:
Const COMPort = "COM1:4800,N,8,1,ME,CS0,DS0,CD0,RS"
If (Open Com ( "COM1:4800,N,8,1,ME,CS0,DS0,RS" For Binary As #1 ) <> 0 ) Then
Print "Fehler: Der Port konnte nicht geoeffnet werden!"
end if
also müsste sich die schnittstelle damit öffnen lassen.
Was bedeutet "Const COMPort = "COM1:4800,N,8,1,ME,CS0,DS0,CD0,RS""
In der befehlsreferenz ist CONST erläutert, aber ich verstehs nicht.
Ist die Schnittstelle mit dem obigen Code zum lesen geöffnet? |
|
Nach oben |
|
|
Sebastian Administrator
Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
Verfasst am: 06.05.2015, 13:12 Titel: |
|
|
Wie wär's hiermit?
Code: | ' KONFIGURATION ZU BEGINN:
' COM-Port-Parameter:
Const COMPortKonfig = "COM1:4800,N,8,1,ME,CS0,DS0,CD0,RS"
' Ein Beispiel-Kommando, das gesendet werden soll, wenn der User die Taste [1] drueckt:
Const Kommando = "Hallo"
Print "Versuche, COM-Port mit folgenden Einstellungen zu oeffnen:"
Color 14
Print COMPortKonfig
Color 7
Print
If (Open Com ( COMPortKonfig For Binary As #1 ) <> 0 ) Then
Color 12
Print "Fehler: Der Port konnte nicht geoeffnet werden!"
Color 7
Sleep: End 1
End If
Color 10
Print "COM-Port geoeffnet! Warte auf eingehende Daten..."
Color 7
Print
Print "Bedienung:"
Print "- Druecken Sie die 1 auf der Tastatur, um die Zeichenfolge '"; Kommando; "' an das "
Print " Geraet zu senden."
Print "- Druecken Sie ESC, um die Verbindung zu schliessen."
Print
Dim As String Puffer, Taste
Do
' Taste gedrueckt?
Taste = Inkey
If Taste = "1" Then
Put #1, , Kommando
Print "<-- "; Kommando; " an die Wetterstation gesendet."
ElseIf Taste = Chr(27) Then 'ESC
Exit Do
End If
' Irgendwelche Daten bereit zum Einlesen?
If Loc(1) > 0 Then
Puffer = Space(Loc(1)) 'Puffergroesse entsprechend festlegen
Get #1, , Puffer
Print "--> Daten empfangen: " & chr(34) & Puffer & chr(34)
End If
Sleep 1
Loop
Close #1
Print
Print "Verbindung geschlossen. Beliebige Taste zum Beenden druecken."
GetKey
End |
Mit CONST legst du eine Konstante an, auf die du später im Programm an beliebig vielen Stellen zugreifen kannst. So musst du eine feste, bestimmte Information (z. B. die Schnittstellenparameter oder die Konstante Pi) nur 1x am Anfang des Programms hinterlegen. Ändert sich der Wert einmal, musst du ihn nicht x-mal irgendwo im Quelltext anpassen, sondern nur 1x ganz zu Beginn. Im Beispielcode oben habe ich das mal dadurch versucht anzudeuten, dass die Konfiguration zuerst einmal ausgegeben wird (auf dem Bildschirm) und dann fürs Öffnen der Schnittstelle benutzt wird. _________________
Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen! |
|
Nach oben |
|
|
sowerum
Anmeldungsdatum: 05.05.2015 Beiträge: 7
|
Verfasst am: 06.05.2015, 14:24 Titel: Danke an Sebastian und RockTheSchock |
|
|
vielen Dank euch beiden für die Mühe, die ihr euch gemacht habt.
Was du geschickt hast, Sebastian, hab ich mal komplett in ein leeres Blatt kopiert und es läuft!
Noch nicht so ganz, statt eines Strings von 20 Zeichen erhalte ich zwei mal acht und einmal vier Zeichen. Aber das liegt ja an der Anpassung an meinen Sendestring und das krieg ich sicher hin.
Wenn ich noch Fragen hab melde ich mich einfach nochmal
Gruß - Uli |
|
Nach oben |
|
|
Sebastian Administrator
Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
Verfasst am: 06.05.2015, 15:11 Titel: Re: Danke an Sebastian und RockTheSchock |
|
|
sowerum hat Folgendes geschrieben: | hab ich mal komplett in ein leeres Blatt kopiert und es läuft! |
Super!
sowerum hat Folgendes geschrieben: | Noch nicht so ganz, statt eines Strings von 20 Zeichen erhalte ich zwei mal acht und einmal vier Zeichen. |
Hm, ja, das ist das kleine Problem, was ich hier schon mal versucht habe anzudeuten:
http://forum.qbasic.at/viewtopic.php?p=106889#106889
Der Empfangspuffer kann nicht "wissen", wie deine Nachrichten inhaltlich aufgebaut sind, z. B. ob immer 5 Bytes hintereinander eine abgeschlossene Nachricht sind oder 20 oder ob das je nach Typ der Nachricht unterschiedlich sein kann. Es wird immer so viel abgerufen, wie gerade im Augenblick im Puffer bereitliegt. Das sind nicht zwangsläufig vollständige Nachrichten. Dadurch kann der Anfang einer Nachricht in der ersten "Fuhre" Daten sein und der Rest in einer zweiten.
Von daher würde ich das Datenformat, das die Schaltung sendet, ein bisschen erweitern. Statt nur reine Messwerte zu senden, würde ich noch 2 Bytes am Anfang der Nachricht hinzufügen: Eine Startmarkierung und ein Zeichen, das die Länge der Nachrichtendaten angibt - sozusagen ein kleiner Datagramm-Header für ein eigenes Übertragungsprotokoll.
Hier ein allgemeines Beispiel, wie man Nachrichten aus Header und Payload zusammensetzen könnte:
Wenn du in den empfangenen Daten die Startmarkierung siehst, nimmst du die darauffolgende Längenangabe und sammelst alle Bytes, die ab dann reinkommen, in einem "Sammelbehälter", bis die geforderte Längenangabe erreicht ist. Sobald das geschieht, geht die gesammelte Nachricht irgendwo hin in deinem Programm zur Weiterverarbeitung. Bei dem Ansatz macht es überhaupt nichts, wenn die Daten "kleckerweise" in unterschiedlich großen Stücken eingehen. Und du hättest die Möglichkeit, vom Controller aus auch mal unterschiedlich lange Nachrichten zu schicken, z. B. abhängig von Kommandos, die der PC sendet. Den kleinen Header, bestehend aus Startzeichen und Längenangabe, könnte man natürlich auch noch erweitern um ein weiteres Byte, das den Nachrichtentyp (z. B. "T" = Temperaturwert, "W" = Wasserstand, "I" = Modellbezeichnung der Wetterstation, ...) klassifiziert. _________________
Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen! |
|
Nach oben |
|
|
sowerum
Anmeldungsdatum: 05.05.2015 Beiträge: 7
|
Verfasst am: 06.05.2015, 16:17 Titel: |
|
|
Da ich ja das sendende Gerät selbst gebaut und programmiert habe, weiß ich ja wie der Sendstring aussieht. Deshalb glaube ich, den Header ganz einfach halten zu können. Eigentlich nur ein Zeichen: "A"
Wie oben schon mal geschrieben, ist das Startzeichen ein "A".
Dann folgen je drei Ziffern für Helligkeit, Radioaktivität, Luftdruck, Temperatur, Feuchtigkeit, Windrichtung und zwei Zeichen (im Moment nur eines) für Windgeschwindigkeit. Die Länge des Sendestrings ist also immer 20 Zeichen. Ich hab also mal die Variable "puffer" mit "space(20)" dimensioniert.
Damit erhalte ich den richtigen String, wie er gesendet wird. z.B.:
A0092133691842221980". Direkt danach kommt allerdings noch ein String mit unbekannter Zeichenzahl und nicht darstellbaren Zeichen - könnten auch Leerzeichen sein.
An Anfangder Zeile Print "--> Daten empfangen: " & chr(34) & Puffer & chr(34) habe ich noch "LOC(1)" ausgeben gelassen. In der Zeile mit den richtigen Werten ist LOC(1)=8, in der Zeile mit den Leerzeichen ist LOC(1)=2 ???? |
|
Nach oben |
|
|
Sebastian Administrator
Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
Verfasst am: 06.05.2015, 16:46 Titel: Vollständige Nachrichten empfangen |
|
|
Könnte das evtl. schon funktionieren? (Ungetestet!)
Code: | Declare Sub VerarbeiteDatensatz(Daten As String) ' Deklaration fuer Unterprogramm, s.u.
' KONFIGURATION
' COM-Port-Parameter:
Const COMPortKonfig = "COM1:4800,N,8,1,ME,CS0,DS0,CD0,RS"
Const Startmarkierung As UByte = 65 '= ASCII-Code von "A"
Const DatenlaengeOhneStartmarkierung = 19
' Status-Flags
Const WARTE_AUF_START = 0
Const EMPFANGE_NACHRICHT = 1
Print "Versuche, COM-Port mit folgenden Einstellungen zu oeffnen:"
Color 14
Print COMPortKonfig
Color 7
Print
If (Open Com ( COMPortKonfig For Binary As #1 ) <> 0 ) Then
Color 12
Print "Fehler: Der Port konnte nicht geoeffnet werden!"
Color 7
Sleep: End 1
End If
Color 10
Print "COM-Port geoeffnet! Warte auf eingehende Daten..."
Color 7
Print
Print "Bedienung:"
Print "Druecken Sie eine beliebige Taste, um die Verbindung zu beenden."
Print
Dim As String Puffer = "" ' Standardmaessig leer.
Dim As String Taste
Dim As Integer Status = WARTE_AUF_START ' Vorbelegen mit diesem Wert
Dim As UByte EinzelnesByte
Dim AS UInteger BytesEmpfangenTotal = 0, BytesVerworfen = 0, AnzahlNachrichten = 0
Do
' Taste gedrueckt?
Taste = Inkey
' Irgendwelche Daten bereit zum Einlesen?
If Loc(1) > 0 Then
Get #1, , EinzelnesByte
' Fuer die Statistik: Zaehler um 1 erhoehen:
BytesEmpfangenTotal += 1
' Empfangenes Byte auswerten:
If (EinzelnesByte = Startmarkierung) Then
' Startmarkierung erhalten! Puffer bereitmachen und Status auf
' "EMPFANGE_NACHRICHT" setzen:
Puffer = ""
Status = EMPFANGE_NACHRICHT
Print "--> Eingehende Nachricht..."
Else
' Es wurde ein Zeichen empfangen, aber es war keine Startmarkierung.
' Dieses Zeichen koennen wir nur gebrauchen, wenn wir gerade dabei
' sind, eine Nachricht zu empfangen.
If (Status = EMPFANGE_NACHRICHT) Then
' Empfangenes Byte hinten an den Puffer anhaengen:
Puffer = Puffer + Chr(EinzelnesByte)
' Pruefen, ob die Nachricht vollstaendig ist:
If (Len(Puffer) >= DatenlaengeOhneStartmarkierung) Then
' Soll-Laenge erreicht. Nachricht bereit zur Weiterverarbeitung.
Print " Nachricht vollstaendig empfangen!"
VerarbeiteDatensatz(Puffer)
' Fuer die Statistik:
AnzahlNachrichten += 1
' Puffer leeren und in den Ausgangszustand zurueckkehren:
Puffer = ""
Status = WARTE_AUF_START
End If
Else
' Wir haben ein Zeichen erhalten, obwohl noch keine Startmarkierung
' gesehen wurde. Damit koennen wir nichts anfangen, weil anscheinend
' der Anfang der Nachricht verlorengegangen ist.
BytesVerworfen += 1
End If
End If
End If
Sleep 1
Loop Until Len(Taste) > 0 'Abbruch durch irgendeinen Tastendruck.
Close #1
Print
Print "Verbindung geschlossen. Kleine Statistik:"
Print " - " & BytesEmpfangenTotal & " Bytes empfangen."
Print " - " & AnzahlNachrichten & " Nachrichten empfangen."
Print " - " & BytesVerworfen & " empfangene Bytes verworfen."
Print
Print "Beliebige Taste zum Beenden druecken."
GetKey
End
' Unterprogramm:
Sub VerarbeiteDatensatz(Daten As String)
' Hier koennte man die Nachricht z. B. in eine Datei oder Datenbanktabelle schreiben.
' Im Beispiel einfach auf dem Bildschirm ausgeben:
Print " Inhalt: "; Daten
End Sub |
_________________
Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen! |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|