Home    Impressum / Datenschutz    Shop    Download    Links     Blog  

I2C-USB-Modem Programmierbeispiele

Beispielprojekt mit Visual Basic Express 2010

Imports System.IO.Ports

Public Class Form1
    Private WithEvents MODEM_COM As IO.Ports.SerialPort
 
    Dim Kommando(128) As Byte   'I2C-Modem Kommando
    Dim Antwort(128) As Byte    'Antwort vom I2C-Modem
    Dim Kennung                 'Kennung Befehl 

    'Deklarationen der FTDI-Bibliothek
    Declare Function FT_CreateDeviceInfoList Lib "ftd2xx.dll" _
    (ByRef lpdwNumDevs As Long) As Long
 
    Declare Function FT_ListDevices Lib "ftd2xx.dll" _
    (ByVal arg1 As Long, ByVal arg2 As String, _ 
     ByVal dwFlags As Long) As Long
 
    Public Const FT_OPEN_BY_SERIAL_NUMBER = 1
    Public Const FT_OPEN_BY_DESCRIPTION = 2
 
    ' Flags for FT_ListDevices
    Const FT_LIST_BY_NUMBER_ONLY = &H80000000
    Const FT_LIST_BY_INDEX = &H40000000
    Const FT_LIST_ALL = &H20000000
 
    ' Return codes
    Const FT_OK = 0
    Const FT_INVALID_HANDLE = 1
    Const FT_DEVICE_NOT_FOUND = 2
    Const FT_DEVICE_NOT_OPENED = 3
    Const FT_IO_ERROR = 4
    Const FT_INSUFFICIENT_RESOURCES = 5
    Const FT_INVALID_PARAMETER = 6
    Const FT_INVALID_BAUD_RATE = 7
 
    Declare Function FT_OpenEx Lib "FTD2XX.DLL" _
    (ByVal arg1 As String, ByVal arg2 As Long, _ 
    ByRef lngHandle As Long) As Long
 
    Declare Function FT_GetComPortNumber Lib "FTD2XX.DLL" _
    (ByVal lngHandle As Long, ByRef portnumber As Long) As Long
 
    Declare Function FT_Close Lib "FTD2XX.DLL" _
    (ByVal lngHandle As Long) As Long 

    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 = "145"
 
    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 = 115200                  '115200 Baud
                .DataBits = 8                       '8 Datenbits
                .StopBits = IO.Ports.StopBits.One   '1 Stopbit
                .Parity = IO.Ports.Parity.None      'n Parity
                .WriteTimeout = 500
                .ReadTimeout = 500
                '4 Byte im Eingangspuffer löst DataReceived Event aus
                .ReceivedBytesThreshold = 4
            End With
 
            MODEM_COM.Open()
            Label_COM_Status.Text = "verbunden"
            Label_COM_Status.BackColor = Color.LightGreen
            Button_VERBINDEN.Text = "trennen"
            Button_CALL.Enabled = True
            Button_VERSION.Enabled = True
            Button_I2CGET.Enabled = True
            Button_SPEED.Enabled = True
            Button_SPEED_SET.Enabled = True
            Button_READ.Enabled = True
            Button_WRITE.Enabled = True
            Button_LM75.Enabled = True
 
        Else
            'COM-Port schließen
            MODEM_COM.Close()
            Label_COM_Status.Text = "getrennt"
            Label_COM_Status.BackColor = Color.LightCoral
            Button_VERBINDEN.Text = "verbinden"
            Button_CALL.Enabled = False
            Button_VERSION.Enabled = False
            Button_I2CGET.Enabled = False
            Button_SPEED.Enabled = False
            Button_SPEED_SET.Enabled = False
            Button_READ.Enabled = False
            Button_WRITE.Enabled = False
            Button_LM75.Enabled = False
            Label_CALL.Text = "??"
            Label_CALL.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.BackColor = Label_VERSION.BackColor
            Label_STATUS.Text = "0"
            Label_BYTES.Text = "0 Bytes empfangen"
        End If
 
    End Sub

    Private Sub Button_CALL_Click_1(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles Button_CALL.Click
        'Befehl CALL 12 hex = 18 dez.
        '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 = "#")

        Kennung = 1         'Taste CALL wurde gedrückt

        Kommando(0) = 18    'Befehl 18 = Call
        Kommando(1) = 0     'Frame Anzahl = 0
        Kommando(2) = 4     'Endekennung

        'Befehl mit 3 Byte absetzen
        MODEM_COM.BaseStream.Write(Kommando, 0, 3)
        Timer1.Start()  'Timer zur Überwachung starten

    End Sub

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

        Kennung = 2         'Taste VERSION wurde gedrückt

        Kommando(0) = 17    'Befehl 17 = Versionsabfrage
        Kommando(1) = 0     'Frame Anzahl = 0
        Kommando(2) = 4     'Endekennung

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

    End Sub

    Private Sub Button_I2CGET_Click(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles Button_I2CGET.Click
        'Befehl I2C-GET 32 hex = 50 dez.
        'Mit diesem Befehl kann der aktuellen Zustand der
        'I2C-Bussignale SDA SCL und INT abgefragt werden.

        Kennung = 3         'Taste I2C-GET wurde gedrückt

        Kommando(0) = 50    'Befehl 50 = I2C-GET
        Kommando(1) = 0     'Frame Anzahl = 0
        Kommando(2) = 4     'Endekennung

        MODEM_COM.BaseStream.Write(Kommando, 0, 3)
        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_SPEED_Click(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles Button_SPEED.Click
        'Befehl 32: I2C-Speed 22 hex = 34 dez.
        'Die Geschwindigkeit am I2C-Buss wird auf den gewünschten 
        'Wert eingestellt. Der Defaultwert ist Null und 
        'stellt die maximale Busgeschwindigkeit ein.

        Kennung = 4         'Taste SPEED wurde gedrückt

        Kommando(0) = 34      'Befehl 18 = I2C-SPEED
        Kommando(1) = 0       'Frame Anzahl = 0
        Kommando(2) = 4       'Endekennung

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

    End Sub

    Private Sub Button_SPEED_SET_Click(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles Button_SPEED_SET.Click
        'Befehl SPEED 22 hex = 34 dez.
        'Mit diesem Befehl kann die Taktgeschwindigkeit des I2C-Bus 
        'zwischen 350 kHz und 40 Hz eingestellt werden.
        'Dabei handelt es sich um einen zwei Byte großen Wert,
        'der mit dem LSB voran im Datenblock abzulegen ist.

        Kennung = 5         'Taste SPEED wurde gedrückt

        Dim Takt, Wert As Integer
        Dim HBy, LBy As Byte
 
        Takt = Val(ComboBox_SPEED_SET.Text) * 1000
 
        Wert = 1 / (Takt * 0.0000004)
 
        HBy = Fix(Wert / 256)   'high-Byte berechnen
        LBy = Wert - HBy * 256  'low-Byte berechnen

        Kommando(0) = 34      'Befehl 34
        Kommando(1) = 2       'Frame Anzahl = 2
        Kommando(2) = LBy     'low-Byte senden
        Kommando(3) = HBy     'high-Byte senden
        Kommando(4) = 4       'Endekennung

        MODEM_COM.BaseStream.Write(Kommando, 0, 5)
        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
        'Der Befehl I2C-Data 33 hex = 51 dez.
        'liest oder schreibt bis zu 128 Bytes vom I2C-Slave

        Kennung = 10         'Taste PCF-READ wurde gedrückt

        Dim Adr
        Adr = Combo_READ_ADR.Text  'Slave Adresse

        Kommando(0) = 51      'Befehl 51 = I2C-DATA
        Kommando(1) = 3       'Frame Anzahl = 3
        Kommando(2) = Adr     'Bus-Adresse des PCF 8574
        Kommando(3) = 0       'Adresse MSB
        Kommando(4) = 1       '1 Byte lesen
        Kommando(5) = 4       'Endekennung

        'Kommando zum Modem senden
        MODEM_COM.BaseStream.Write(Kommando, 0, 6)
        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
        'Der Befehl I2C-Data 33 hex = 51 dez.
        'liest oder schreibt bis zu 128 Bytes vom I2C-Slave

        Kennung = 11         'Taste PCF-WRITE wurde gedrückt

        Dim W, Adr
        Adr = Combo_WRITE_ADR.Text  'Slave Adresse

        On Error GoTo ErrorHandler  'Für falsche Eingaben im Feld

        If TextBox_WRITE.Text > 255 Then
            MsgBox("Im Feld WERT nur Zahlen <= 255 erlaubt")
            TextBox_WRITE.Text = 255
        Else
            If CheckBox_WRITE_INVERS.Checked = False Then
                W = TextBox_WRITE.Text         'Ausgabewert direkt 
            Else
                W = 255 - TextBox_WRITE.Text   'Ausgabewert invertieren 
            End If
 
            Kommando(0) = 51  'Befehl 51 = Daten senden
            Kommando(1) = 3   'Frame Anzahl = 3
            Kommando(2) = Adr 'Bus-Adresse des PCF 8574
            Kommando(3) = 0   'Adresse MSB
            Kommando(4) = W   'Wert ausgeben
            Kommando(5) = 4   'Endekennung
        End If
 
        'Kommando zum Modem senden
        MODEM_COM.BaseStream.Write(Kommando, 0, 6)
        Timer1.Start()  'Timer zur Überwachung starten
        Exit Sub
 
ErrorHandler:
        Select Case Err.Number              'Fehlernummer auswerten.
            Case 0 'ok
            Case 13
                MsgBox("Im Feld WERT nur Zahlen erlaubt")
                TextBox_WRITE.Text = ""
            Case Else
                MsgBox("Fehler " & Err.Number)
        End Select
 
    End Sub
 
    Private Sub Button_LM75_Click_1(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles Button_LM75.Click
        'Der Befehl I2C-Data 33 hex = 51 dez.
        'liest oder schreibt bis zu 128 Bytes vom I2C-Slave

        Kennung = 20         'Taste LM75-READ wurde gedrückt

        Dim Adr
        Adr = ComboBox_LM75_ADR.Text       'Adresse aus Cobo-Box

        Kommando(0) = 51      'Befehl 51 = Data
        Kommando(1) = 3       'Frame Anzahl = 3
        Kommando(2) = Adr     'Adresse LSB lesen
        Kommando(3) = 0       'Adresse HSB
        Kommando(4) = 2       '2 Bytes lesen
        Kommando(5) = 4       'Endekennung

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

    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, W 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
 
            'Antwort-Frame löschen und aus Puffer lesen
            Label_Antwort.Text = ""
            For I = 0 To MODEM_COM.BytesToRead - 1
                Wert = MODEM_COM.BaseStream.ReadByte
                Antwort(I) = Str$(Wert)
                Label_Antwort.Text = Label_Antwort.Text & Antwort(I) & _
		","
            Next
 
            'Erstes Byte in Statusfeld eintragen und Farbumschlag 
            Label_STATUS.Text = Hex(Antwort(0)) & " = "
            If (Antwort(0) And 1) > 0 Then
                Label_STATUS.BackColor = Color.LightCoral
                Label_STATUS.Text = Label_STATUS.Text & "Fehler " & _ 
		Antwort(2)
            Else
                Label_STATUS.BackColor = Color.LightGreen
                Label_STATUS.Text = Label_STATUS.Text & "ok"
            End If
 
 
            Select Case Kennung
                Case 1 'Taste CALL wurde gedrückt
                    If Antwort(2) = 35 Then
                        Label_CALL.Text = "ok"
                        Label_CALL.BackColor = Color.LightGreen
                    Else
                        Label_CALL.Text = "FEHLER"
                        Label_CALL.BackColor = Color.LightCoral
                    End If
 
                Case 2 'Taste VERSION wurde gedrückt
                    Label_VERSION.Text = Antwort(2) & "." & _ 
			Antwort(3) & Antwort(4)
 
                Case 3 'Taste I2C-GET wurde gedrückt
                    Call StatusBits(Antwort(2)) 'Statusbits auswerten

                Case 4 'Taste SPEED wurde gedrückt
                    If Antwort(1) = 2 Then
                        'Speed wurde abgefragt
                        W = Antwort(3) * 256 + Antwort(2)    
			'High-Byte * 256 + Low Byte
                        Label_SPEED.Text = Fix(1 / (W * 0.0000004)) & " Hz"
                    End If
 
                Case 10 'Taste PCF-READ
                    If CheckBox_READ_INVERS.Checked = False Then
                        TextBox_READ.Text = Antwort(2)
                    Else
                        TextBox_READ.Text = 255 - Antwort(2)
                    End If
 
                Case 20 'Taste LM75-READ
                    'Temperatur eintragen
                    Call LM75_TEMPERATUR(Antwort(2), Antwort(3))
            End Select
 
            Kennung = 0
        End If
    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

   Private Sub Button_suchen_Click_(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles Button_suchen.Click
 
        Dim A, I As Integer
        Dim Handle, cP As Long
        Dim strDescription As String = Space(64)
 
        'Prüfen ob FTDI-Chip am USB-Bus vorhanden ist
        Call FT_CreateDeviceInfoList(A)
 
        If A = 0 Then
            Label_STATUS.Text = "Kein FTDI-Chip am USB gefunden"
        Else
            'prüfen ob ein USB-Modem angeschlossen ist

            For I = 0 To A - 1
                If FT_ListDevices(I, strDescription, FT_LIST_BY_INDEX _
                    Or FT_OPEN_BY_DESCRIPTION) <> FT_OK Then
                    Label_STATUS.Text = "kein FTDI-Chip am USB gefunden"
                    Exit Sub
                End If
 
                If InStr(1, strDescription, "USB Modem") Then
                    Call FT_OpenEx(strDescription, _
                    FT_OPEN_BY_DESCRIPTION, Handle)
 
                    'COM-Nummer herausfinden
                    Call FT_GetComPortNumber(Handle, cP)
                    Call FT_Close(Handle)
 
                    Exit For
                End If
            Next I
 
            If cP = 0 Then
                Label_STATUS.Text = "Kein I2C-USB-Modem angeschlossen"
                Exit Sub
            Else
                Label_STATUS.Text = "I2C-USB-Modem an COM" & cP & _
		" gefunden"
                Combo_COM.Text = "COM" & cP
            End If
        End If
    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 Browser

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

 
Programmbeispiele zum I2C-USB-Modem
I2C-USB-Modem-Test.xls und port.dll (118 kB)
Excel-Makro mit den Grundfunktionen des Modems und je einem Beispiel zur Ansteuerung der I2C-Ausgabekarte, I2C-Eingabekarte, und einem Eprom.
I2C-USB-Modem Test_VB-Express 2010.zip (118 kB)
Visual Basic Express Version 2010 Projekt mit den Grundfunktionen des I2C-USB-Modem und je einem Beispiel zur Ansteuerung der I2C-Ausgabekarte, I2C-Eingabekarte und LM75 Temperatur lesen.
Hier ein Link zur Beschreibung der "FTD2XX.DLL" direkt auf der Homepage von FTDI
D2XX Programmer's Guide (ca. 750 kb)
 
Bausätze können Sie günstig in unserem Onlineshop in der Rubrik
"I2C-Komponenten" bestellen.