Schritt 1: Erstellen des ActiveX Steuerelementes Öffnet die VB IDE und erstellt ein neues ActiveX Steuerelement
Fügt dem Projekt die Komponente Microsoft Comm Control 6.0 hinzu.
Ändert den Projektnamen (oMas345) und den Usercontrolnamen (usrMas345), fügt dann noch ein Modul zu dem Projekt hinzu (modMas345). Nun sollte euer Projektbrowser in der IDE so aussehen.
Nachdem wir unsere Arbeitsumgebung vorbereitet haben füllen wir jetzt die einzelnen Projektteile. 1. Modul modMas345 Private Declare Sub Sleep Lib "kernel32" ( _ ByVal lngMilliseconds As Long) Der Vollständigkeit halber habe ich noch die Main Funktion definiert, benutze sie aber nicht. Public Sub Main() ' End Sub Und die Prozedur die zur API gehört. Public Sub SleepLong(ByVal lngSeconds As Long, _ Optional ByVal blnBeAwake As Boolean = True) Dim t As Single Dim b As Boolean t = Timer Do Sleep 1 If blnBeAwake Then DoEvents End If b = Timer - t > lngSeconds Loop Until b End Sub Da das Multimeter auf jede Anfrage 1 Sekunde wartet bevor es die Displaydaten sendet benötigen wir diese Prozedur. Daraus ergibt sich auch der kleinste Abfrageinterval von 1 Sekunde. Die Prozedur hält die Anwendung solange an wie im Parameter lngSeconds übergeben worden ist. Damit ist das Modul erst mal fertig gestellt. 2. UserControl usrMas345
auf die Form. Ein Besonderheit: das 3. Lable ist Visible false auf der Form und wird erst zur Laufzeit sichtbar geschaltet um Fehlermeldungen anzuzeigen. Die Verteilung der Steuerelemente soll jedem selbst überlassen sein; in Abb5. sieht man die von mir gewählte Anordnung.
Beginnen wir jetzt mit der Deklaration der Klassenvariablen: Public Event ReceiveData(Data As String) Private lInterval As Long Private bKommunikation As Boolean Das Event ReceiveData wird immer dann ausgelöst, wenn über das Comm Objekt Daten empfangen werden. A.) Button_Click Set Private Sub Command1_Click() ' Com Schnittstelle initialisieren With MSComm1 If IsNumeric(Text1(0).Text) Then .CommPort = Text1(0).Text Command2.Enabled = True Else ' Fehler anzeigen wenn die Comport Zuweisung keine Zahl ist Lbl_Error.Caption = "Bitte erneut Comport eingeben !!" Lbl_Error.Visible = True End If End With ' Interval der Messungen einstellen (Default alle 3 Sekunden) If IsNumeric(Text1(1).Text) Then lInterval = Text1(1).Text Else lInterval = 30 End If End Sub Hier wird das Comm Objekt initialisiert auf das System. Um falsche Eingaben in der Textbox1(0) zu unterbinden wird auf isNumeric abgefragt, so dass alle nicht numerischen Eingaben eine Fehlermeldung in dem Lbl_Error anzeigen. Erst wenn eine numerische Eingabe erfolgt, wird der ComPort zugewiesen und der Start Button freigeschaltet. In der Textbox(1) kann der User seine Intervallzeiten vorgeben. (10 = 1 Sekunde), default auf 3 Sekunden eingestellt. B.) Button_Click Start/Stop Private Sub Command2_Click() If Tmr_Fetch_Data.Enabled Then MSComm1.PortOpen = False Tmr_Fetch_Data.Enabled = False Else Tmr_Fetch_Data.Enabled = True End If End Sub Mit dem Click Ereignis des 2. Buttons wird der Timer zum Daten holen gestartet bzw. gestoppt. Wenn das Daten holen gestoppt wird, setzt das Ereignis auch den ComPort zurück. C.) TextBox_Click Private Sub Text1_Click(index As Integer) ' Fehleranzeige zurücksetzen If index = 0 Then Lbl_Error.Caption = "" Lbl_Error.Visible = False End If End Sub Auf das Click_Ereignis der ComPort Textbox werden eventuelle Fehlermeldungen wieder gelöscht. D.) Konstruktor UserControl_Initialize Private Sub UserControl_Initialize() ' Com Schnittstelle auf das Multimeter einstellen With MSComm1 .Settings = "600,N,7,1" .RThreshold = 14 .DTREnable = True .Handshaking = comNone End With End Sub Dies ist jetzt wichtig für die Kommunikation zum DMM. Ohne diese SETTINGS kann keine Kommunikation aufgebaut werden. E.) ON COMM Ereignis Private Sub MSComm1_OnComm() Dim str As String ' Ereignise des MsComm Steuerelement auswerten Select Case MSComm1.CommEvent Case comOverrun Case comRxOver Case comEvReceive str = MSComm1.Input SleepLong (1) RaiseEvent ReceiveData(str) bKommunikation = True Case comEvEOF Case comEventBreak End Select End Sub Im ON_COMM_Ereignis des Comm Objektes bekommen wir die angekommen Daten vom DMM gemeldet bzw. dessen Error Ereignisse, die aber nicht weiter ausprogrammiert sind. Im Case comEvReceive benötigen wir dann die Sleep Funktion aus modMas345, denn das Multimeter benötigt 1 Sekunde zum Übertragen der Daten. Ohne das Sleep würde die str Variable immer leer sein, da die Wertezuweisung in einem Bruchteil einer Sekunde passiert. F.) Timer Private Sub Tmr_Fetch_Data_Timer() ' Timer für den Messinterval Static Delay As Integer Static bk As Boolean Delay = Delay + 1 ' 36000 ^ 1 Std If ((Delay Mod lInterval) = 0) Then Delay = 0 If bk Then If Not bkommunkation Then Lbl_Error.Caption = "Falscher Comm Port Bitte neu Konfigurieren" Lbl_Error.Visible = True End If End If If Not MSComm1.PortOpen Then MSComm1.PortOpen = True MSComm1.Output = vbNewLine bk = True If Shape1(0).Visible Then Shape1(0).Visible = False Shape1(1).Visible = True Else Shape1(0).Visible = True Shape1(1).Visible = False End If End If End Sub In dem Timer wird das Polling an das DMM angestoßen. Der Timer ist ein 100 ms Timer, daher auch 10 = 1 Sekunde. Hier kommt dann auch die Klassenvariable lInterval zum Tragen, denn nur wenn Delay Modulus lInterval keinen Rest ergibt wird das Polling ausgeführt. Mit den Shapes wird die Kommunikation auf dem Control visualisiert. Auch wird hier das Kommunikations-Flagg abgefragt. Damit ist das OCX fertig. Jetzt noch kompilieren und das OCX kann in anderen Anwendungen Verwendung finden. Schritt 2: Erstellen der Anwendung Öffnet die VB IDE und erstellt eine neue Standard EXE
Dann konfiguriert die Komponenten des Projekts und aktiviert das OCX welches ihr vorher erstellt habt.
Damit diese Anwendung funktioniert muss in den Verweisen noch die Microsoft ActiveX Data Objects 2.8 Library aktiviert werden.
Damit mit ADO auf eine MYSQL Datenbank zugegriffen werden kann, müssen dann noch die ODBC Treiber für MYSQL installiert sein. Ich gebe die Treiber mal mit in das Zip File. Jetzt wird die Anwendung vorbereitet: Nennt das Formular um in frmMain. Fügt ein neues Modul hinzu und nennt es modStr. In diesem Modul werden einige nützliche Stringfunktionen definiert. Eine neue Klasse brauchen wir auch noch, nennt die Klasse clsDBCon. In der Klasse wird der Datenbankzugriff programmiert. Damit steht das Grundgerüst. Füllen wir jetzt das Modul A.) modStr - Funktion Replace ' replaces string in string Public Function Replace(ByVal s As String, _ sSearch As String, sReplace As String) As String Dim p As Integer Dim q As Integer q = 1 Do p = InStr(q, s, sSearch) If (p > 0) Then s = Left$(s, p - 1) & sReplace & _ Right$(s, Len(s) - p - Len(sSearch) + 1) q = p + Len(sReplace) End If Loop Until (p = 0) Replace = s End Function Diese Funktion sucht im übergebenen String s nach einem Zeichen sSearch und ersetzt es durch das in der Parameterliste übergebende Zeichen sReplace. Diese Funktion brauchen wir, um das Datumsformat an das der Datenbank anzupassen. B.) modStr - DateFunc Public Function DateFunc(sDate As String) As String Dim YY As String Dim MM As String Dim DD As String Dim sTime As String YY = Mid(Extract(3, sDate, "-"), 1, 4) MM = Extract(2, sDate, "-") DD = Extract(1, sDate, "-") sTime = Extract(2, sDate, " ") DateFunc = YY & "-" & MM & "-" & DD & " " & sTime End Function Diese Funktion dreht die Datumsnotation von Europäisch in Englisch. C.) modStr - Extract ' Extract Strings in Strings Public Function Extract(nNo As Variant, sSource As String, sDel As String) As String Dim q As Long Dim p As Long Dim s As String Dim nCount As Long On Error Resume Next ' xxx q = 1 nCount = 0 s = "" Do p = InStr(q, sSource, sDel) If (p = 0) And (q <= Len(sSource)) Then p = Len(sSource) + 1 If (p > 0) Then nCount = nCount + 1 If (nCount >= nNo) Then If (nNo > 1) Then q = q + Len(sDel) - 1 s = Mid$(sSource, q, p - q) Exit Do End If q = p + 1 End If Loop Until (p = 0) Or p >= Len(sSource) Extract = s End Function Dies ist die letzte Funktion. Sie filtert den String zwischen zwei Trennzeichen heraus; mit nNo gibt man an ab welchen Zeichen die Extraktion beginnen soll. Schritt 3: Weiterverarbeitung der Daten Nun wird die Klasse clsDBCon ausprogrammiert A.) clsDBCon SaveDataInDB Public Sub SaveDataInDB(RawData As String) Const sConStr = "Provider=MSDASQL;Driver={MySQL ODBC 3.51 Driver};" & _ "Server=Server-2003;UID=...;PWD=...;database=mas345;" Dim adocn As ADODB.Connection Dim adors As ADODB.Recordset Dim sInsert As String Dim sSelect As String Dim iPrimKeyNr As Long Dim sData As String Dim sEinheit As String Dim sType As String Dim sDate As String On Error GoTo handler ' Erstellen und Konfigurieren der DB Connection Set adocn = New ADODB.Connection With adocn .ConnectionString = sConStr .CommandTimeout = 50 .ConnectionTimeout = 20 .CursorLocation = adUseServer .Open End With ' Inkrementieren des Primärkeys Set adors = New ADODB.Recordset sSelect = "SELECT max(id)as MaxNr from Tbl_MessDaten" adors.Open sSelect, adocn, adOpenDynamic, adLockOptimistic If IsNull(adors!MaxNr) Then ' Initialisierung bei ersten Eintrag in Tabelle iPrimKeyNr = 1 Else iPrimKeyNr = adors!MaxNr + 1 End If adors.Close ' Analysieren der Rohdaten sData = Trim(Mid(RawData, 4, 6)) sType = Trim(Mid(RawData, 1, 3)) sEinheit = Trim$(Mid(RawData, Len(RawData) - 3, Len(RawData))) sDate = DateFunc(Replace(Now, ".", "-")) ' Einfügen der Daten in Tabelle sInsert = "INSERT INTO Tbl_Messdaten " & _ "Value ('" & _ iPrimKeyNr & "','" & sData & "','" & sDate & "','" & sType & "','" & _ sEinheit & "')" adocn.BeginTrans adocn.Execute sInsert adocn.CommitTrans adocn.Close Exit Sub handler: Resume Next End Sub Diese Klasse enthält nur eine Funktion die dafür sorgt, dass die empfangenen Daten vom DMM in die Datenbank transferiert werden. Dazu erstellen wir eine Datenbankverbindung adocn, der Connectionstring sConStr enthält den ODBC Treiber, den wir verwenden. Mit der ersten Abfrage ermitteln wir den höchsten Wert aus der Spalte ID, die als Primärschlüssel konfiguriert ist. Der Wert wird um 1 inkrementiert, um den nächsten Primärschlüsselwert zu bekommen. Nun zerlegen wir den Rohdatenstring in die Informationen Daten, Type, Einheit und Datum und schicken sie über die Datenbankverbindung via Execute in die Tabelle. Anmerkungen: An letzter Stelle nun noch die Form frmMain
Auf die Form ziehen wir nun unser OCX und sehen die Steuerelemente des Controls. A.) Deklaration der Klassenvariablen Private cDB As clsDBCon Private WithEvents usrMas345 As usrMas345 cDB - instanzieren der Datenbankklasse B.) Form Load Ereignis Private Sub Form_Load() Set cDB = New clsDBCon End Sub Im Load Ereignis wird die Datenbankklasse erzeugt. C.) Event usrMas3451_ReceiveData Private Sub usrMas3451_ReceiveData(Data As String) ' Speichern der eingelesenen Daten in MYSQL Datenbank cDB.SaveDataInDB (Data) End Sub In dem Eventhandling werden die Rohdaten an die Datenbankklasse übergeben. Projekt kompilieren - FERTIG Nachdem der Datensammler nun arbeitet habe ich mir eine Auswertung als Diagramm in einem PHP-Script geschrieben. Einfacher PHP Scriptcode zum Erstellen eines Linien-Diagramms <?php include ("C:/Inetpub/wwwroot/jpgraph/jpgraph.php"); include ("C:/Inetpub/wwwroot/jpgraph/jpgraph_line.php"); //Konfiguration Datenbank $DatabaseHost = "Server-2003"; $DatabaseUser = "..."; $DatabasePassword = "..."; $Database = "mas345"; $Table = "Tbl_Messdaten"; //Abfragezeitraum aus einem gesonderten Formular übermittelt $sStartdate=$_POST['start']; $sStopdate=$_POST['stop']; //Daten aus der MySQL-Tabelle auslesen $DatabasePointer = @mysql_connect($DatabaseHost, $DatabaseUser, $DatabasePassword); @mysql_select_db($Database, $DatabasePointer); $sSql = "SELECT logData,Einheit,logdate from Tbl_Messdaten where logdate >= '$sStartdate' and logdate <= '$sStopdate'" ; $ResultPointer = @mysql_query("$sSql", $DatabasePointer); for($i=0, $XWerte=""; $i<mysql_num_rows($ResultPointer); $i++) { $MessDaten = mysql_fetch_object($ResultPointer); $XWerte[] = $MessDaten->logData; } //Graphen erstellen //http://www.binnendijk.net/jpgraph/index.php?page=line_1 für nähere Informationen $graph = new Graph(1200,600,"auto"); $graph->SetScale("textlin"); $lineplot=new LinePlot($XWerte); $graph->Add($lineplot); $graph->title->Set("Temperaturkurve von: $sStartdate bis: $sStopdate "); $graph->img->SetMargin(60,20,20,40); $lineplot->SetColor("red"); $graph->yaxis->SetColor("blue"); $graph->Stroke(); ?>
Fazit: Download Dieser Workshop wurde bereits 22.140 mal aufgerufen.
Anzeige
![]() ![]() ![]() (einschl. Beispielprojekt!) Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv! - nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten - Symbol-Galerie mit mehr als 3.200 Icons im modernen Look Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m. |
sevISDN 1.0 ![]() Überwachung aller eingehender Anrufe! Die DLL erkennt alle über die CAPI-Schnittstelle eingehenden Anrufe und teilt Ihnen sogar mit, aus welchem Ortsbereich der Anruf stammt. Weitere Highlights: Online-Rufident, Erkennung der Anrufbehandlung u.v.m. Tipp des Monats ![]() Manfred Bohn IndexOf für mehrdimensionale Arrays Die generische Funktion "IndexOf" ermittelt das erste Auftreten eines bestimmten Wertes in einem n-dimensionalen Array sevAniGif (VB/VBA) ![]() Anzeigen von animierten GIF-Dateien Ab sofort lassen sich auch unter VB6 und VBA (Access ab Version 2000) animierte GIF-Grafiken anzeigen und abspielen, die entweder lokal auf dem System oder auf einem Webserver gespeichert sind. |
||||||||||||||
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein. |