Home    Impressum / Datenschutz    Shop    Download    Links     Blog  

Ansteuerung des I2C-RS232-Modems mit VB Express 2008

Komplettes Demoprogramm zum Lesen und Schreiben des PCF8574 und LM75 Temperatursensor

Mit diesem Programmbeispiel in Visual Basic 2008 Express sehen Sie wie das I2C-Modem über die serielle Schnittstelle angesprochen werden kann.

Das Programmierpaket kann auf der Microsoft Visual Studio 2008 Express Editions Seite kostenlos heruntergeladen und frei verwendet werden.

VB 2008 Express Quellcode für I2C-Modem

Imports System.IO.Ports

Public Class Form1
    Private WithEvents MODEM_COM As IO.Ports.SerialPort

    Dim Kommando(18) As Byte    'I2C-Modem Kommando
    Dim Antwort(18) As Byte     'Antwort vom I2C-Modem
    Dim LM75 As Boolean         'Temperaturwert lesen


    Private Sub Form1_Load _
    (ByVal sender As System.Object, _
     ByVal e As System.EventArgs) Handles MyBase.Load
        'Treadübergreifende Zugriffe erzeigen keinen Fehler
        CheckForIllegalCrossThreadCalls = False

        'Combo-Box löschen
        Combo_COM.Items.Clear()

        'vorhandene serielle Schnittstellen in Combo-Box eintragen
        For Each sp As String In My.Computer.Ports.SerialPortNames
            Combo_COM.Items.Add(sp)
        Next

        If Combo_COM.Items.Count = 0 Then
            'Meldung wenn keine Schnittstelle gefunden wurde
            MsgBox("Keine serielle Schnittstelle gefunden")
        Else
            'oder erste selektieren
            Combo_COM.SelectedIndex = 0

            'COM-Port für Modem-zugriff deklarieren
            MODEM_COM = New SerialPort
        End If

        'Combo-Boxen auf ersten Wert einstellen
        Combo_WRITE_ADR.Text = "64"
        Combo_READ_ADR.Text = "65"
        ComboBox_LM75_ADR.Text = "144"

    End Sub 

    Private Sub Button_VERBINDEN_Click _
    (ByVal sender As System.Object, _
     ByVal e As System.EventArgs) Handles Button_VERBINDEN.Click

        'I2C-Modem mit dem PC über RS232 verbinden 
        'und Schaltflächen einblenden

        If Me.MODEM_COM.IsOpen = False Then
            'COM-Port öffnen

            With MODEM_COM
                .Encoding = System.Text.Encoding.GetEncoding(28591)
                .PortName = Combo_COM.Text          'COM-Nummer 
                .BaudRate = 19200                   '19200 Baud
                .DataBits = 8                       '8 Datenbits
                .StopBits = IO.Ports.StopBits.One   '1 Stopbit
                .Parity = IO.Ports.Parity.None      'n Parity
                .WriteTimeout = 500
                .ReadTimeout = 500
                '1Byte im Eingangspuffer löst DataReceived Event aus
                .ReceivedBytesThreshold = 1
            End With

            MODEM_COM.Open()
            Label_COM_Status.Text = "verbunden"
            Label_COM_Status.BackColor = Color.LightGreen
            Button_VERBINDEN.Text = "trennen"
            Button_IDENT.Enabled = True
            Button_VERSION.Enabled = True
            Button_STATUS.Enabled = True
            Button_READ.Enabled = True
            Button_WRITE.Enabled = True
            Button_LM75.Enabled = True
            Call Check_CTS(MODEM_COM)   'CTS prüfen

        Else
            'COM-Port schließen
            MODEM_COM.Close()
            Label_COM_Status.Text = "getrennt"
            Label_COM_Status.BackColor = Color.LightCoral
            Button_VERBINDEN.Text = "verbinden"
            Button_IDENT.Enabled = False
            Button_VERSION.Enabled = False
            Button_STATUS.Enabled = False
            Button_READ.Enabled = False
            Button_WRITE.Enabled = False
            Button_LM75.Enabled = False
            Label_IDENT.Text = "??"
            Label_IDENT.BackColor = Label_VERSION.BackColor
            Label_VERSION.Text = "??"
            Label_Status_SDA.BackColor = Color.White
            Label_Status_SCL.BackColor = Color.White
            Label_Status_INT.BackColor = Color.White
            Label_STATUS_MODEM.BackColor = Label_VERSION.BackColor
            Label_STATUS_MODEM.Text = "0"
            Label_BYTES.Text = "0 Bytes empfangen"
        End If

    End Sub 

    Private Sub MODEM_COM_PinChanged(ByVal sender As Object, _
      ByVal e As System.IO.Ports.SerialPinChangedEventArgs) _
      Handles MODEM_COM.PinChanged

        Select Case e.EventType
            Case IO.Ports.SerialPinChange.Break

            Case IO.Ports.SerialPinChange.CDChanged

            Case IO.Ports.SerialPinChange.CtsChanged
                ' Der Zustand des CTS-Signals (Clear to Send) 
                ' hat sich geändert. Beim I2C-Modem ist
                ' dies der INT einer angeschlossenen Eingabekarte
                Call Check_CTS(sender)

            Case IO.Ports.SerialPinChange.DsrChanged

            Case IO.Ports.SerialPinChange.Ring

        End Select
    End Sub 

    Private Sub Check_CTS(ByVal sender)
        'CTS-Signal überprüfen
        If (DirectCast(sender, SerialPort).CtsHolding) Then
            Label_Status_INT_AUTO.BackColor = Color.Red
        Else
            Label_Status_INT_AUTO.BackColor = Color.White
        End If
    End Sub 

    Private Sub Button_IDENT_Click_1 _
    (ByVal sender As System.Object, _
     ByVal e As System.EventArgs) Handles Button_IDENT.Click
        'Befehl 16: IDENT
        'Modem sendet I2C-OK. Dieser Befehl kann dazu verwendet 
        'werden, das I2C-Modem an der 'RS232 zu erkennen. 
        'Empfängt das I2C-Modem 'diesen Befehl, 
        'wird ein Datenbyte generiert,
        'in dem die Bits 6 und 7 gesetzt sind. (192 dez)

        Kommando(0) = 16
        MODEM_COM.BaseStream.Write(Kommando, 0, 1)
        Timer1.Start()  'Timer zur Überwachung starten

    End Sub 

    Private Sub Button_STATUS_Click_1 _
    (ByVal sender As System.Object, _
     ByVal e As System.EventArgs) Handles Button_STATUS.Click
        'Befehl 48: STATUS
        'liest er die Zustände der Leitungen SDA, SCL und INT aus.
        'Diese werden zusammen mit einem OK in einem 
        'Byte an den PC zurückgesendet.

        Kommando(0) = 48
        MODEM_COM.BaseStream.Write(Kommando, 0, 1)
        Timer1.Start()  'Timer zur Überwachung starten

    End Sub 

    Private Sub StatusBits(ByVal ST As Byte)
        ' Auswerten des Status-Bytes

        If (ST And 1) > 0 Then
            Label_Status_SDA.BackColor = Color.Green
        Else
            Label_Status_SDA.BackColor = Color.White
        End If

        If (ST And 2) > 0 Then
            Label_Status_SCL.BackColor = Color.Yellow
        Else
            Label_Status_SCL.BackColor = Color.White
        End If

        If (ST And 4) > 0 Then
            Label_Status_INT.BackColor = Color.White
        Else
            Label_Status_INT.BackColor = Color.Red
        End If

    End Sub 

    Private Sub Button_VERSION_Click_1 _
    (ByVal sender As System.Object, _
     ByVal e As System.EventArgs) Handles Button_VERSION.Click
        'Befehl 80: VERSION
        'Das I2C-Modem antwortet mit zwei Byte.
        'Werden die Bytes in der Reihenfolge zusammengesetzt 
        'so ergibt sich die Versionsnummer der geladenen Firmware

        Kommando(0) = 80
        MODEM_COM.BaseStream.Write(Kommando, 0, 1)
        Timer1.Start()  'Timer zur Überwachung starten

    End Sub 

    Private Sub Button_READ_Click_1 _
    (ByVal sender As System.Object, _
     ByVal e As System.EventArgs) Handles Button_READ.Click
        'Befehl 128: READ
        'Mit dem Befehl werden 1-16 Bytes vom I2C-Bus ausgelesen

        Kommando(0) = 128                   'Kommando 128 = Lese 1 Byte
        Kommando(1) = Combo_READ_ADR.Text   'Slave Adresse

        '2Bytes zum Modem senden
        MODEM_COM.BaseStream.Write(Kommando, 0, 2)
        Timer1.Start()  'Timer zur Überwachung starten

    End Sub 

    Private Sub Button_WRITE_Click_1 _
    (ByVal sender As System.Object, _
     ByVal e As System.EventArgs) Handles Button_WRITE.Click
        'Befehl 64: WRITE
        'Mit dem Befehl werden 1-16 Bytes zum I2C-Bus geschrieben

        Kommando(0) = 64                    'Kommando 64 = Schreibe 1 Byte
        Kommando(1) = Combo_WRITE_ADR.Text  'Slave Adresse

        If CheckBox_WRITE_INVERS.Checked = False Then
            Kommando(2) = TextBox_WRITE.Text  'Wert der übertragen wird
        Else
            Kommando(2) = 255 - TextBox_WRITE.Text  'Wert invertieren
        End If

        '3Bytes zum Modem senden
        MODEM_COM.BaseStream.Write(Kommando, 0, 3)
        Timer1.Start()  'Timer zur Überwachung starten

    End Sub 

    Private Sub Button_LM75_Click_1 _
    (ByVal sender As System.Object, _
     ByVal e As System.EventArgs) Handles Button_LM75.Click
        'Befehl 128+1: READ 2 Bytes
        'Mit dem Befehl werden 1-16 Bytes vom I2C-Bus ausgelesen

        Kommando(0) = 129                    'Kommando 129 = Lese 2 Byte
        Kommando(1) = ComboBox_LM75_ADR.Text 'Slave Adresse LM75

        '2Bytes zum Modem senden
        MODEM_COM.BaseStream.Write(Kommando, 0, 2)
        Timer1.Start()  'Timer zur Überwachung starten

        LM75 = True ' Temperatur wurde ausgelesen 
    End Sub 

    Private Sub LM75_TEMPERATUR(ByVal BY1 As Byte, ByVal BY2 As Byte)
        Dim Wert

        If (BY1 And 128) = False Then
            Wert = BY1        'Temperatur Vorkomma >= 0°C
        Else
            Wert = BY1 - 255  'Temperatur Vorkomma < 0°C
        End If

        If BY2 And 128 Then
            Wert = Wert + 0.5
        End If

        TextBox_LM75.Text = Format(Wert, "##,##0.00 °C")

    End Sub 

    Private Sub MODEM_COM_DataReceived(ByVal sender As Object, _
        ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) _
        Handles MODEM_COM.DataReceived
        Dim I As Integer
        Dim Wert As Byte

        Timer1.Stop()
        'Thread 50 ms anhalten bis alle Daten eingelaufen sind
        System.Threading.Thread.Sleep(50)

        If MODEM_COM.BytesToRead > 0 Then
            If MODEM_COM.BytesToRead = 1 Then
                Label_BYTES.Text = MODEM_COM.BytesToRead & " Byte emfpangen"
            Else
                Label_BYTES.Text = MODEM_COM.BytesToRead & " Bytes emfpangen"
            End If

            For I = 0 To MODEM_COM.BytesToRead - 1
                Wert = MODEM_COM.BaseStream.ReadByte
                Antwort(I) = Str$(Wert)
            Next

            Select Case Kommando(0)
                Case 16 'Befehl 16: IDENT
                    Call STATUS() 'Status übernehmen

                    If Antwort(0) = 192 Then
                        Label_IDENT.Text = "ok"
                        Label_IDENT.BackColor = Color.LightGreen
                    Else
                        Label_IDENT.Text = "FEHLER"
                        Label_IDENT.BackColor = Color.LightCoral
                    End If

                Case 48 'Befehl 48: STATUS
                    Call StatusBits(Antwort(0)) 'Statusbits auswerten

                Case 80 'Befehl 80: VERSION
                    Label_VERSION.Text = Antwort(0) & "." & Antwort(1)

                Case 64 To 79 'Befehl 64..79: WRITE bis zu 16 Bytes
                    Call STATUS() 'Status übernehmen

                Case 128 To 143 'Befehl 128..143: READ bis zu 16 Bytes
                    Call STATUS() 'Status übernehmen
                    If LM75 = False Then
                        'gelesener Wert eintragen
                        TextBox_READ.Text = Antwort(1)
                    Else
                        LM75 = False
                        'Temperatur eintragen
                        Call LM75_TEMPERATUR(Antwort(1), Antwort(2))
                    End If
            End Select
        End If
    End Sub 

    Private Sub STATUS()
        Dim Fehler As Boolean

        'Farbumschlag für Fehlernummer
        Fehler = Not Antwort(0) And 128
        If Fehler Then
            Label_STATUS_MODEM.BackColor = Color.LightCoral
        Else
            Label_STATUS_MODEM.BackColor = Color.LightGreen
        End If

        'Statusbyte in Feld kopieren
        Label_STATUS_MODEM.Text = Antwort(0)

        'Statusbits rangieren
        CheckBox_STATUS_0.Checked = Antwort(0) And 1
        CheckBox_STATUS_1.Checked = Antwort(0) And 2
        CheckBox_STATUS_2.Checked = Antwort(0) And 4
        CheckBox_STATUS_3.Checked = Antwort(0) And 8
        CheckBox_STATUS_4.Checked = Antwort(0) And 16
        CheckBox_STATUS_5.Checked = Antwort(0) And 32
        CheckBox_STATUS_6.Checked = Antwort(0) And 64 And Fehler

    End Sub 

    Private Sub LinkLabel1_LinkClicked _
    (ByVal sender As System.Object, _
     ByVal e As System.Windows.Forms.LinkLabelLinkClickedEventArgs) _
     Handles LinkLabel1.LinkClicked
        'Aufruf der Internetseite "www.horter.de" über den Standard-Browser

        System.Diagnostics.Process.Start("http://horter.de")
    End Sub 

    Private Sub Timer1_Tick(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles Timer1.Tick
        'Wenn nicht innerhalb 500ms eine Antwort vom Modem kommt
        ' wird ein Fehler ausgegeben

        Timer1.Stop()
        MsgBox("Keine Antwort vom I2C-Modem")

    End Sub 

End Class
 
EXE-Programm und VB 2008 Express Beispielprojekt
I2C-Modem_VB2008-Express.zip (28 kB)
Komplettes Visual Basic 2008 Express Projekt
I2C-Modem Test_VB2008.zip (17 kB)
Testprogramm "I2C-Modem Test.exe" kompiliert.
Benötigt jedoch NET Framework 3.5 auf dem Rechner