Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

serielle Schnittstelle lesen

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
sowerum



Anmeldungsdatum: 05.05.2015
Beiträge: 7

BeitragVerfasst am: 05.05.2015, 16:25    Titel: serielle Schnittstelle lesen Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Sebastian
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 5969
Wohnort: Deutschland

BeitragVerfasst am: 05.05.2015, 20:48    Titel: OPEN COM in FreeBASIC Antworten mit Zitat

Hallo und willkommen im Forum! lächeln

Die Kombination aus ATMega, MAX232, COM-Port und FreeBASIC habe ich selber schon benutzt. lächeln 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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
sowerum



Anmeldungsdatum: 05.05.2015
Beiträge: 7

BeitragVerfasst am: 05.05.2015, 21:12    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Sebastian
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 5969
Wohnort: Deutschland

BeitragVerfasst am: 05.05.2015, 23:17    Titel: Antworten mit Zitat

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. lächeln
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
Code:
Get #1, , Puffer

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
sowerum



Anmeldungsdatum: 05.05.2015
Beiträge: 7

BeitragVerfasst am: 06.05.2015, 11:16    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
RockTheSchock



Anmeldungsdatum: 04.04.2007
Beiträge: 138

BeitragVerfasst am: 06.05.2015, 11:27    Titel: Antworten mit Zitat

Ich glaube damit der Freebasic Treiber für die Serielle / Parallele Schnittstelle Funktioniert muss einmalig das Programm mit Administratorrechten gestartet werden.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
sowerum



Anmeldungsdatum: 05.05.2015
Beiträge: 7

BeitragVerfasst am: 06.05.2015, 11:34    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Sebastian
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 5969
Wohnort: Deutschland

BeitragVerfasst am: 06.05.2015, 12:21    Titel: Antworten mit Zitat

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. lächeln

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
sowerum



Anmeldungsdatum: 05.05.2015
Beiträge: 7

BeitragVerfasst am: 06.05.2015, 12:58    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Sebastian
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 5969
Wohnort: Deutschland

BeitragVerfasst am: 06.05.2015, 13:12    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
sowerum



Anmeldungsdatum: 05.05.2015
Beiträge: 7

BeitragVerfasst am: 06.05.2015, 14:24    Titel: Danke an Sebastian und RockTheSchock Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Sebastian
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 5969
Wohnort: Deutschland

BeitragVerfasst am: 06.05.2015, 15:11    Titel: Re: Danke an Sebastian und RockTheSchock Antworten mit Zitat

sowerum hat Folgendes geschrieben:
hab ich mal komplett in ein leeres Blatt kopiert und es läuft!

Super! lächeln

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. lächeln

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
sowerum



Anmeldungsdatum: 05.05.2015
Beiträge: 7

BeitragVerfasst am: 06.05.2015, 16:17    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Sebastian
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 5969
Wohnort: Deutschland

BeitragVerfasst am: 06.05.2015, 16:46    Titel: Vollständige Nachrichten empfangen Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
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.

 Impressum :: Datenschutz