Kommunikation RS232 mit Visua lBasic 2010

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Kommunikation RS232 mit Visua lBasic 2010

      Hallo,
      habe mal eine kleine Frage zur Komm. über die RS232. Möchte mit Visual Basic 2010 ein Word (als Zahl!) über die COM1 an einen ATMega48 senden.
      Hier mein kleiner Code:

      Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
      SerialPort1.Write("1" & vbCr)
      Wert = 124
      SerialPort1.Write(Wert)
      End Sub

      Es kommt im Prozessor richtiger Weise eine 48 ("1"), eine 13 ("vbCr") an und danach eine 52!
      Das heißt, Visual Basic hat eine Charakter "4" übertragen. Ist mein Format der Variablen falsch?

      Über Hterm habe ich diese Probleme nicht. Und welches Progamm nehmt ihr zum steuern diverser MC's?

      Danke und noch einen schönen Abend
      Jürgen

      a_56_df238249
    • Du musst dir darüber im klaren sein, dass man keine Zahlen als Word übertragen kann auf einem Protokoll, welches Bytes überträgt.

      Es werden einzelne Bytes über die Serielle übertragen!

      Einen Zahlenwert von 0 bis 255 kann man also in einem Übertragungsbyte transportieren. Hier gilt allerdings zu beachten:
      Arbeitet man mit CharMatch in Bascom, kann auch dieses Steuerzeichen innerhalb der Nutzdaten sein.
      Erwartet Bascom also z.B. ein #13 als Zeilenende und man sendet als Nutzdaten ein #13, dann hat man ein Problem.

      Besser wäre, sich ein eigenes Protokoll auszudenken.

      Man kann z.B. eine "1=" gefolgt vom Zahlenwert als String senden: "1=123" + #13
      In Bascom empfängt man mit CharMatch 13

      In der Empfangsroutine kann man dann das Empfangene folgend auswerten :
      ( das ist kein fertiges Programm, sondern ein Schema, wie es laufen könnte!)

      BASCOM Source Code

      1. Config Serialin = Buffered , Size = 20 , Bytematch = 13
      2. ......
      3. Dim Outword As Word
      4. Dim Data_in As String * 20
      5. Dim Valstr As String * 10
      6. Dim Rx_str As Byte
      7. ......
      8. Declare Sub Rx_data()
      9. do
      10. If Rx_str > 0 Then
      11. Rx_str = 0
      12. Call Rx_data
      13. Data_in = ""
      14. End If
      15. ...
      16. loop
      17. end.
      18. Serial0charmatch:
      19. Input Data_in Noecho
      20. Rx_str = 1
      21. Return
      22. Sub Rx_data()
      23. Local Pos As Byte
      24. if Mid(data_in , 1 , 2) = "=1" Then
      25. Pos = Len(data_in) - 2
      26. Valstr = Mid(data_in , 3 , Pos)
      27. Outword = Val(valstr)
      28. Elseif Mid(data_in , 1 , 2) = "=2" Then
      29. ......
      30. end if
      31. Data_in = ""
      32. end sub
      Display All
      Code first, think later - Natural programmer :D
    • Aus VB bin ich jetzt schon länger weg.
      Aber wenn SerialPort1.Write einen String erwartet und du da eine numerische Variable übergeben möchtest, muss zuerst der Inhalt der numerischen Variable in einen String umgewandelt werden.
      In vielen Basic-Dialekten geht das dann mit String=STR(Numerische Variable).
      Als kompletter Befehl, angelehnt an dein Beispiel, also dann SerialPort1.Write(Str(Wert) & vbCr)
      Ob der Befehl in VB jetzt exakt STR heißt, musst du kontrollieren.
    • Kein Problem! Schnell die Variable als Byte def. und Werte nicht über 255 eingegeben.
      Leider mit dem gleichen Ergebnis. der Wert "123" wird als String interpretiert. Ich brauche ihn nicht einmal aufwendig zu wandeln.
    • HJH-MD wrote:

      Es kommt im Prozessor richtiger Weise eine 48 ("1"), eine 13 ("vbCr") an und danach eine 52!
      Das heißt, Visual Basic hat eine Charakter "4" übertragen. Ist mein Format der Variablen falsch?
      Sieht für mich aus, als ob das Empfangsprogramm was verschluckt.
      Das könntest du mal anhängen.

      Möglicherweise sendet dein VB 1,CR,2,CR,4,CR und deine Empfangsroutine springt nach dem erstem Zeichen in den Interrupt und braucht zu lange, dass nur noch Bruchstücke der Nachfolgedaten ankommen.
    • Ja, Michael!
      Auf der Empfangsseite habe ich eine Pause von 1s noch drin. Das ist aber nicht mein Problem. Sende ich nur die 123 ohne die erste Wrire-Anweisung
      empfange ich "49, 50 und 51 auf meinen AVR. Über Hterm (mit Labtop gekoppelt) emfpange ich auch nur ascii-code. Es geht mir um die Senderseite.
      Übrigens hatte ich mal 2 AVRs über den UART gekoppelt und konnte einfach ein word übertragen. Hatte mir dazu vor längerer Zeit mal ein Board mit
      LCD und Tastatur gebaut. Bei Interesse kann ich ja mal die Eagle-Datei dafür einstellen. Bild ist schon mal dabei.
      Jürgen
      Files
      • DSCN6998.JPG

        (407.61 kB, downloaded 14 times, last: )
    • Dieses Problem hatte ich auch schon.

      SerialPort.Write() erwartet ein String, ein Byte-Buffer oder ein Char-Buffer.
      Es handelt sich bei der Methode um eine sogenannte überladene Methode.
      (Unterschiedliche Parameter bei gleichem Namen für die Methode)

      Wird nur ein Parameter angegeben, wandelt VB den übergebenen Parameter in ein Sting (Unicode) um.
      Bei 2 Parameter, muss der 1. ein Byte- oder ein Char-Array sein.

      Bascom kennt Unicode nicht, sondern nur Ascii.
      Will man also einen String von VB nach Bascom übertragen, muss man den vor dem Senden von Unicode in Ascii umwandeln.
      Rückwärts ist es umgekehrt.

      Unicode verwendet pro Zeichen 2 Byte, Ascii nur 1 Zeichen. Daher vermutlich die Verwirrung.

      Ich müsste jetzt in den alten Routinen graben, wie ich das damals gelöst habe.
      Aber String direkt senden geht nicht.
    • Ich muss etwas korrigieren.

      Das mit dem Umwandeln von Unicode in ASCII kann die Klasse SerialPort.
      Man muss das Objekt allerdings richtig konfigurieren.

      Etwas so:

      BASCOM Source Code

      1. Public Sub New()
      2. With SerialPort1 ' Default-Einstellungen
      3. .BaudRate = 4800 ' Baud
      4. .DataBits = 8 ' 8 Datenbits
      5. .StopBits = 1 ' 1 Stoppbit
      6. .Parity = Parity.None ' keine Parität
      7. .DtrEnable = False ' DTR aus
      8. .RtsEnable = False ' RTS aus
      9. .DiscardNull = False ' Null-Werte zulassen (Binär-Mode)
      10. .ReadTimeout = 3000 ' Timeout=3 Sekunden
      11. .WriteTimeout = 3000 ' Timeout=3 Sekunden
      12. .Encoding = System.Text.Encoding.Default
      13. End With
      14. End Sub
      Display All


      In Zeile 12 ist die Codierung angegeben, damit die Umwandlung zum AVR automatisch funktioniert.

      In dem Fall kann man einfach einen String senden etwa so:

      BASCOM Source Code

      1. Sub WriteString(ByVal Message As String)
      2. Dim localString As String = Message + vbCr ' automatisch ein CR anhängen oder
      3. 'Dim localString As String = Message + vbLf ' automatisch ein LF anhängen oder
      4. 'Dim localString As String = Message + vbCrLf ' automatisch ein CRLF anhängen oder
      5. 'Dim localString As String = Message + vbNullChar ' automatisch ein Null anhängen
      6. SerialPort1.Write(localString)
      7. End Sub
      Die Routine zeigt, wie man verschiedene Endungen an den String anhängen kann.
      Den String in der Routine manipulieren kann man sich auch schenken, wenn man einen String immer mit einer bestimmten Endung senden will.

      Dann muss man das einstellen, etwa so:

      BASCOM Source Code

      1. Public Sub New()
      2. With SerialPort1 ' Default-Einstellungen
      3. .BaudRate = 4800 ' Baud
      4. .DataBits = 8 ' 8 Datenbits
      5. .StopBits = 1 ' 1 Stoppbit
      6. .Parity = Parity.None ' keine Parität
      7. .DtrEnable = False ' DTR aus
      8. .RtsEnable = False ' RTS aus
      9. .DiscardNull = False ' Null-Werte zulassen (Binär-Mode)
      10. .ReadTimeout = 3000 ' Timeout=3 Sekunden
      11. .WriteTimeout = 3000 ' Timeout=3 Sekunden
      12. .Encoding = System.Text.Encoding.Default
      13. .NewLine = vbCrLf ' String-Abschluss
      14. End With
      15. End Sub
      Display All
      Die Endung wird angegeben wie in Zeile 13 gezeigt für CRLF Es können auch andere Endungen eingegeben werden.

      Bei meinen damaligen Versuchen hatte ich herausgefunden, dass die Textkodierung "Default" die einzige war, die richtig gut mit AVR geklappt hat.
      Die Einstellung "ASCII" hatte da nicht so gut geklappt. Aber was das war weiß ich jetzt auch nicht mehr.

      Übrigens Sub New()
      End Sub

      ist der Konstruktor der Klasse. Ich hatte meine Routinen in eine Klasse gepackt (Wiederverwendung).
      Der Konstruktor wird aufgerufen, wenn die Klasse instanziert wird, man also ein Objekt daraus macht.

      Man braucht dann eigentlich nur noch den Port öffnen und Schreiben/Lesen.

      Hoffe dir hilft das weite.
    • Danke Mitch, werde mich mal schlau machen über Unicode.

      Habe mal einen Speicheroszi bemüht und sende nur ein Zeichen. Und ich sehe auch nur ein Byte.
      Hterm sendet bis 255 auch nur ein Byte. Ich möchte aber kein String übertragen sondern eine Zahl
      von 0 bis 16383. Auch wenn diese mit 2 Bytes ankommt wäre es kein Problem. Setze sie dann im
      AVR zusammen wie bei Hterm z. B.: 4387 = 017 + 035 >> 17*256 + 35*1
    • Ok! Habe mir Dein Programm angesehen und werde es mal umsetzen. Will es aber jetzt vielleicht
      mit Excel oder Python versuchen. Übrigens hat SciLab wohl das gleiche Problem.
      Wie schön war doch TPascal und Delphi.
      Danke
    • Binärdaten als String senden geht nicht, da in Binärdaten auch eine 0 vorkommen kann, die auch String-Terminator ist.
      In VB.net gibts aber zb. die BitConverter-Klasse um Variablen in Byte Arrays und umgekehrt zu wandeln. Die SerialPort.Write() Funktion kann dieses Byte Array direkt senden.
      Für Uint16, Short, Word oder sonstige Bezeichnungen:

      Source Code

      1. Dim Source As Short = 11111
      2. Dim MyArray() As Byte = BitConverter.GetBytes(Source)
      3. SerialPort1.Write(MyArray, 0, 2)



      In Bascom:

      Source Code

      1. Dim Myvariable As Word
      2. Inputbin Myvariable

      Bzw. umgekehrt gehts auch mit Printbin und

      Source Code

      1. Dim MyArray() As Byte
      2. SerialPort1.Read(MyArray, 0, 2)
      3. BitConverter.ToUInt16(MyArray, 0)
    • zaubara wrote:

      Binärdaten als String senden geht nicht, da in Binärdaten auch eine 0 vorkommen kann, die auch String-Terminator ist.
      Korrekt ist, dass in Binärdaten auch ne 0 vorkommen kann.
      Aber in VB werden Strings nicht Null-Terminiert im Speicher abgelegt.
      Ein String ist auch nichts anderes als eine Array mit Bytes.

      Es ist die Frage, wie die Daten in Bascom gelesen werden.

      Ich selbst habe schon Strings in Frames versendet mit anderen Binären Daten im Frame versendet.
      Das geht!

      Solange man in Bascom binär einliest, ist der Rest reine Interpretationssache.
    • HJH-MD wrote:

      Auf der Empfangsseite habe ich eine Pause von 1s noch drin.
      Das ist nicht gut.

      HJH-MD wrote:

      Das ist aber nicht mein Problem.
      Das sehe ich anders.

      HJH-MD wrote:

      Sende ich nur die 123 ohne die erste Wrire-Anweisung
      empfange ich "49, 50 und 51 auf meinen AVR.
      Das stützt meine Vermutung, dass dein AVR nach dem ersten CR ein Problem hat.

      Ich würde dir gerne helfen, aber ohne Programm tue ich mich schwer.
    • Hallo, ihr habt mir doch schon geholfen. Ein CR sende ich gar nicht mehr. Alles bis auf die 3stellige Zahl rausgenommen.
      Ich bekomme auch ein korrektes "Hallo" über die Leitung. Ja, das Programm. Ist noch im Entstehen. Ich teste mit einem
      Minimalcode erst mal die Kommunikation. Auf der Bascom-Seite habe ich keine Probleme. Das VB-Programm ist eigentlich
      wie oben.
      Ich versuche es morgen mal mit den guten Hinweisen von zaubara. Bis denne und einen schönen Abend noch
      Jürgen
    • Dann wäre es zum testen einfacher zwei com ports am PC zu verbinden (ohne AVR) Einen mit Hterm den anderen mit dem VB Programm. Hier akzeptiert und sendet es alles von 30-255. Darunter verweiget die Textbox die Annahme. Per Chr gehen dann auch die ersten 30. Sicher ist es möglich ein Integer in ein-zwei Bytes zu übertragen. Mir ist Klartext lieber, das kann jedes beliebige Terminalprogramm.
    • ...am einfachsten wäre, das Prinzip zu verstehen und nicht irgendwelche Werte durch überladene Funktionen oder Casts versuchen zu wandeln.
      Warum es in Pascal oder Delphi besser wäre verstehe ich auch nicht.
      Wenn du wirklich in Pascal programmiert hast, müsstest du wissen, dass gerade Pascal eine einwandfreie Deklaration verlangt.

      Ich habe dir oben in einem beispielhaften Code gezeigt, wie du jede beliebige Zahl senden und empfangen kannst; auch Steuerzeichen wie chr(13).
      Code first, think later - Natural programmer :D
    • Mal auch für mein Anfängerverständnis: wieso kann er nicht byte für byte einlesen und in nen String schreiben? unabhängig in welcher Form es nun "abgeschickt" hat, kann er es ja auf bascom Seite, seine (z.B.) Dezimal wieder in Char umwandeln? Seine 124 wäre ja 49 50 52? Richtig? Wenn noch irgendwas dran häng muss es ja immer, bei jedem Senden dran hängen. Könnte man also einfach weglassen. quasi nur das erste, zweite und dritte byte nehmen. Ich bin zu wenig vom Fach um es so zu erklären wie ich es meine. Ich meinte einfach alles (bytematch all) empfangen und nach einander in nen String. Danach kann er aussortieren. Da sollte doch auf jeden Fall mal nix verloren gehen oder?

      The post was edited 4 times, last by darasol ().

    • darasol wrote:

      Wenn noch irgendwas dran häng muss es ja immer, bei jedem Senden dran hängen. Könnte man also einfach weglassen.
      Ja, Hängt nun aber nur am Letzten was dran (z.B. {13}{10} )Weiß der Avr das die Sequenz fertig ist. Hängt nirgendwo was oder immer das selbe wäre Anfang und Ende nicht erkennbar.
      PS Er wollte ja keinen String sondern ein Byte 123 (&H7B)